While reading in an EPS file, I get the error “OSError: Unable to locate Ghostscript on paths” Here’s my code that generates the error:
def _readImage(self, image):
actual_file = image
# Try each, and open the one that actually exists:
if exists(CFG.image_source + image.replace(".gif", ".eps")):
actual_file = image.replace(".gif", ".eps")
elif exists(CFG.image_source + image.replace(".gif", ".png")):
actual_file = image.replace(".gif", ".png")
elif exists(CFG.image_source + image.replace(".gif", ".jpg")):
actual_file = image.replace(".gif", ".jpg")
elif exists(CFG.image_source + image.replace(".gif", ".jpeg")):
actual_file = image.replace(".gif", ".jpeg")
return Image.open(CFG.image_source + actual_file)
I’m trying to parse the output of a program called AdMax from Software Consulting Systems. The output file lists images with the “.gif” extension regardless of the actual extension that the image uses, so each image call has to use os.path.exists() to determine what the actual file name is.
I do believe there is a way to edit the export, but doing so might break the current export system that I’m trying to seamlessly replace, so modifications are out of the question.
Possible Fix:
1.) Download and Install GhostScript from: https://ghostscript.com/releases/gsdnld.html
2.) Import EpsImagePlugin from PIL:
from PIL import EpsImagePlugin
3.) Configure your path to Ghostscript. I found mine in “C:\Program Files\gs\gs9.56.1\bin\gswin64c.exe”
EpsImagePlugin.gs_windows_binary = r'C:\Program Files\gs\gs9.56.1\bin\gswin64c.exe'
That worked like a charm for me. Here’s the rest of the code in case I missed something above.
Note, I’ve stopped working on this midstream, so the tail end portions of this are nowhere near complete, and some of this code has not been tested at all, not even once! Use at your own risk!
from os.path import exists
import pandas as pd
from PIL import Image
from PIL import EpsImagePlugin
import numpy as np
# Ghost script is needed on every computer that runs this script:
# Get it here: https://ghostscript.com/releases/gsdnld.html
EpsImagePlugin.gs_windows_binary = r'C:\Program Files\gs\gs9.56.1\bin\gswin64c.exe'
# source input file is I:/_classUpload/internetWImages.txt
class CFG:
image_source = "v:/new_logos_backup/"
output_location = "i:/_classupload/python/"
class OneClassAd:
def __init__ (self):
# convert class variables into instance variables:
self.ad_text = ""
self.source_images = []
self.ad_image = None
self.ad_number = None
self.class_code = None
self.combined_full_path = None
self.combined_image_filename = None
def setClassCode(self, code):
self.class_code = code
def getClassCode(self):
return self.class_code
def setAdText(self, text):
self.ad_text = text
def getAdText(self):
return self.ad_text
def addSourceImage(self, source_image):
self.source_images.append(source_image)
def getSourceImages(self):
return self.source_images
def setAdImage(self, image):
self.ad_image = image
def getAdImage(self):
return self.ad_image
def _readImage(self, image):
# So this is a bit of a mess. The exporting program can export the image in any file format that it
# can read, but it doesn't give us the proper extension, so all images are called 'image.gif' even
# if they are 'image.eps'
actual_file = image
# Try each, and open the one that actually exists:
if exists(CFG.image_source + image.replace(".gif", ".eps")):
actual_file = image.replace(".gif", ".eps")
elif exists(CFG.image_source + image.replace(".gif", ".png")):
actual_file = image.replace(".gif", ".png")
elif exists(CFG.image_source + image.replace(".gif", ".jpg")):
actual_file = image.replace(".gif", ".jpg")
elif exists(CFG.image_source + image.replace(".gif", ".jpeg")):
actual_file = image.replace(".gif", ".jpeg")
return Image.open(CFG.image_source + actual_file)
def generateSingleImageFromList(self):
if (len(self.source_images) > 0):
max_width, total_height = self.determineMaxImageWidthAndHeight()
# Create a new PIL image with the required width and height:
new_image = Image.new('RGB',(max_width, total_height), (250,250,250))
# add each image to the combined image:
# Start at y position 0, at the top
current_y_pos = 0
for image in self.source_images:
img_obj = self._readImage(image)
new_image.paste(img_obj, (0, current_y_pos))
# increase the current_y_pos:
current_y_pos += img_obj.size[1]
save_to = CFG.output_location + str(self.getAdNumber()) + ".png"
new_image.save(save_to)
return save_to
else:
return None
def determineMaxImageWidthAndHeight(self):
max_width = 0
total_height = 0
# open each image with PIL, get the images width
for image in self.source_images:
img_obj = self._readImage(image)
width, height = img_obj.size
if width > max_width:
max_width = width
total_height += height
return (max_width, total_height)
def setCombinedImageFilename(self, full_path, image_filename):
self.combined_full_path = full_path
self.combined_image_filename = image_filename
def setAdNumber(self, ad_number):
self.ad_number = ad_number
def getAdNumber(self):
return self.ad_number
def dumpAdInfo(self):
print("_________________________________________________________")
print("Ad Number: " + str(self.getAdNumber()))
print("Ad Classification: " + str(self.getClassCode()))
print("Ad Text: " + str(self.getAdText()))
print("Ad Images: " + str(self.getSourceImages()))
def readSource(sourceFile):
source_pd = pd.read_csv(sourceFile, sep='|', names = ['class_code', 'ad_text', 'images'], header=None )
for index, row in source_pd.iterrows():
this_ad = OneClassAd()
this_ad.setAdNumber(index)
this_ad.setClassCode(row['class_code'])
this_ad.setAdText(row['ad_text'])
# See if the image is a nan or not by comparing it to itself.
# only Nans (not a number) return false equality:
if (row['images'] == row['images']):
# ignore 'newadhdr.gif' images
if("newadhdr.gif" not in row['images']):
# add each image specified to the ad, multiple images are separated with ',':
for image in str(row['images']).split(','):
this_ad.addSourceImage(image.replace("'",""))
this_ad.dumpAdInfo()
this_ad.generateSingleImageFromList()
# Read in the classified import file:
readSource("I:\_classUpload\internetWImages.txt")
