Kane
Kane

Reputation: 308

Converting RGB PDFs to CMYK PDFs via GhostScript CLI / Python (quality problem)

I am trying to achieve the following using a python script:

  1. Read in an SVG design file (with images)
  2. Manipulate the SVG file
  3. Convert this to a web-ready PDF and a print-ready PDF

My problem is with the conversion of the RGB PDF to the CMYK PDF. An SVG with a 15MB photo in it will export as a 15MB RGB PDF, but then convert (using GhostScript) to a 3MB CMYK PDF. When trying ImageMagic, the resolution of the output PDF is determined by the density and I can't find how to keep the PDF's canvas size while setting the density.

So far, I have a script which reads in the SVG files and does some manipulation (add a logo using svgutils, change some text by scanning through the SVG text file). It then uses Inkscape to export the web-ready PDF (using "--export-area-page" and converting the text to paths) and a temporary PDF (using "--export-margin=X" where X is the bleed size, also converting text to paths). The temporary PDF is what I need, except it is RGB rather than CMYK. So, I then want to convert this file (Inkscape does not work with CMYK).

This is the function I am using to convert the file (it is setup with GhostScript and also I was trialling ImageMagick):

converter_program = "GHOSTSCRIPT"
def convertPDFtoPrintReadyPDF(pdf_in, new_filename=None, output_location=None):
    global converter_program
    if (new_filename == None):
        new_filename = os.path.basename(pdf_in).replace(".svg", ".pdf")
    if (output_location == None):
        output_location = os.path.dirname(pdf_in)
    output_file = output_location + "\\" + new_filename

    argument_list = []
    
    if (converter_program == "GHOSTSCRIPT"):
        pdf_tool_loc = r'"C:\Program Files\gs\gs9.55.0\bin\gswin64c.exe"' # Added "c" at end for non-window version (command line)
        
        argument_list.append('-o "' + output_file + '"')
        argument_list.append(r"-sDEVICE=pdfwrite")
        argument_list.append(r"-dUseBleedBox")
        argument_list.append(r"-dQUIET")
        argument_list.append(r"-dPDFSETTINGS=/printer")
        argument_list.append(r"-dCompressPages=false")
        argument_list.append(r"-dMaxInlineImageSize=200000")
        argument_list.append(r"-dDetectDuplicateImages")
        #argument_list.append(r"-dJPEGQ=100")
        argument_list.append(r"-dAutoFilterColorImages=false")
        argument_list.append(r"-dAutoFilterGrayImages=false")
        #argument_list.append(r"-sCompression=Flate")
        #breaks the code: argument_list.append(r"-sColorImageFilter=/Flate")
        #argument_list.append(r"-r600")
        argument_list.append(r"-dColorImageResolution=600")
        argument_list.append(r"-dGrayImageResolution=300")
        argument_list.append(r"-dMonoImageResolution=1200")
        argument_list.append(r"-dDownsampleColorImages=false")
        argument_list.append(r"-sProcessColorModel=DeviceCMYK")
        argument_list.append(r"-sColorConversionStrategy=CMYK")
        argument_list.append(r"-sColorConversionStrategyForImages=CMYK")
        argument_list.append('"' + pdf_in + '"')
        
    elif (converter_program == "IMAGEMAGICK"):
        pdf_tool_loc = 'magick'
        
        argument_list.append(r'convert "' + pdf_in + '"')
        argument_list.append(r"-density 300")
        argument_list.append(r"-resize 100%")
        argument_list.append(r"-colorspace CMYK")
        argument_list.append('"' + output_file + '"')
        #convert tp_rgb.pdf -verbose -density 300 -colorspace CMYK  tp_cmyk.pdf
    
    argument_string = " ".join(argument_list)
    subprocess.run(pdf_tool_loc + " " + argument_string, shell=True, check=True)
    
    return output_file

Versions:

Python 3.8.10

GhostScript 9.55.0

ImageMagick 7.1.0-16

Upvotes: 1

Views: 1005

Answers (1)

Kane
Kane

Reputation: 308

I found some GhostScript parameters to add to the conversion process:

argument_list.append(r"-dAutoFilterColorImages=false")
argument_list.append(r"-dAutoFilterGrayImages=false")
argument_list.append(r"-dColorImageFilter=/FlateEncode")
argument_list.append(r"-dGrayImageFilter=/FlateEncode")
argument_list.append(r"-dDownsampleMonoImages=false")
argument_list.append(r"-dDownsampleGrayImages=false")

So, the full argument list looks like this:

argument_list.append('-o "' + output_file + '"')
argument_list.append(r"-sDEVICE=pdfwrite")
argument_list.append(r"-dUseBleedBox")
argument_list.append(r"-dQUIET")
argument_list.append(r"-dDetectDuplicateImages")
argument_list.append(r"-dAutoFilterColorImages=false")
argument_list.append(r"-dAutoFilterGrayImages=false")
argument_list.append(r"-dColorImageFilter=/FlateEncode")
argument_list.append(r"-dGrayImageFilter=/FlateEncode")
argument_list.append(r"-dDownsampleMonoImages=false")
argument_list.append(r"-dDownsampleGrayImages=false")
argument_list.append(r"-dColorImageResolution=300")
argument_list.append(r"-dGrayImageResolution=300")
argument_list.append(r"-sProcessColorModel=DeviceCMYK")
argument_list.append(r"-sColorConversionStrategy=CMYK")
argument_list.append(r"-sColorConversionStrategyForImages=CMYK")
argument_list.append('"' + pdf_in + '"')

This turned the 15MB->3MB conversion into a 15MB->53MB. It still needs some tweaking, but is now on the right track (I will update this answer if I get the process better).

I found the information thanks to this post: http://zeroset.mnim.org/2014/07/14/save-a-pdf-to-cmyk-with-inkscape/

Documentation is here (don't forget to delete the leading letter to search ("dColorImageFilter" to "ColorImageFilter"): https://www.ghostscript.com/doc/current/VectorDevices.htm

Upvotes: 2

Related Questions