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")