2

currently i am generating a pdf using weasyprint version 52.5. The pdf generated is in RGB but i need it in CMYK for printing. Now i tried converting it using ghostscript version 9.50 which works just fine, but my generated PDF always consists of texts in rich black.

I did find a solution to convert the RGB(0,0,0) to plain black(K=100%). I tried the hack described in this issue: Converting (any) PDF to black (K)-only CMYK. But this only worked if my pdf didn't consists any transparent objects which i have, else ghostscript would render my PDF to a bitmap which i don't want.

Now instead of using the hack, the ghostscript support recommended using ICC profiles to accomplish the same result: https://bugs.ghostscript.com/show_bug.cgi?id=704872.

So i had to consult my printer to provide me with an icc profiles which i should use instead of the hack. And here is the problem, i can't get to make ghostscript use and embedd the ICC profile into the pdf. It seems ghostscript converts the pdf to cmyk but i think its using the defaul_cmyk.icc profile and not my specified icc profle.

Also i don't realy think that the ICC profile from my printer is the right one. I tried inspecting my PDF and the CMYK black generated was never plain K. The recommended profile was: PS0coated_v3.icc

Here is my ghostscript command:

gs -q -o weasyprint_rgb.pdf -sDEVICE=pdfwrite -dNOPAUSE -dBATCH -sProcessColorModel=DeviceCMYK -sColorConversionStrategy=CMYK -sColorConversionStrategyForImages=CMYK -dOverrideICC=true -dEncodeColorImages=true -sOutputICCProfile=PS0coated_v3.icc converted_cmyk.pdf

Also here is my function implemented in python(django)

def convert_pdf_to_cmyk(pdf_bytes: bytes) -> bytes:
    if pdf_bytes is not None:
        with NamedTemporaryFile(prefix="weasyprint_rgb", suffix=".pdf") as rgb_pdf_file:
            rgb_pdf_file.write(pdf_bytes)
            rgb_pdf_file.seek(0)
            # Converting pdf from RGB to CMYK
            # https://stackoverflow.com/questions/6241282/converting-pdf-to-cmyk-with-identify-recognizing-cmyk
            # HACK to convert rich black to plain CMYK black we need to convert it to ghostscript than to pdf
            # using a colour conversion script.
            # By default RGB->CMYK will create rich black instead plain K black
            # https://stackoverflow.com/questions/6248563/converting-any-pdf-to-black-k-only-cmyk/9024346#9024346).
            # with NamedTemporaryFile(prefix="ghostscript_", suffix=".ps") as ghostscript_file:
            #     command = [
            #         "gs",
            #         "-q",
            #         "-o",
            #         ghostscript_file.name,
            #         "-dNOPAUSE",
            #         "-dBATCH",
            #         "-sDEVICE=ps2write",
            #         rgb_pdf_file.name,
            #     ]
            #     subprocess.check_call(command)
            with NamedTemporaryFile(prefix="converted_cmyk", suffix=".pdf") as converted_pdf_file:
                command = [
                    "gs",
                    "-q",
                    "-o",
                    converted_pdf_file.name,
                    "-sDEVICE=pdfwrite",
                    "-dNOPAUSE",
                    "-dBATCH",
                    "-sProcessColorModel=DeviceCMYK",
                    "-sColorConversionStrategy=CMYK",
                    "-sColorConversionStrategyForImages=CMYK",
                    "-dOverrideICC=true",
                    "-dEncodeColorImages=true",
                    f"-sDefaultCMYKProfile = {os.path.join(DOCUMENT_DATA_DIR, 'PSOcoated_v3.icc')}",
                    f"-sOutputICCProfile = {os.path.join(DOCUMENT_DATA_DIR, 'PS0coated_v3.icc')}",
                    #os.path.join(DOCUMENT_DATA_DIR, "rgb_to_plain_cmyk_black.ps"),
                    rgb_pdf_file.name #ghostscript_file.name,
                ]
                subprocess.check_call(command)
                pdf_bytes = converted_pdf_file.read()
    return pdf_bytes

Would appreciate any ideas in how to solve this? :)

0andriy
  • 4,183
  • 1
  • 24
  • 37
David Marogy
  • 116
  • 7

1 Answers1

0

Use DeviceLink ICC profile generated by collink tool from argyll by binding the source RGB icc to destination CMYK icc with the -f parameter to force neutral and black to be encoded only on the K plate.

If the resulting DeviceLink ICC is named "sRGB_to_eciCMYK_v2.icc (I used sRGB as the source and FOGRA59/eciCMYK_v2 as the destination)" add lines such as

Image_RGB   sRGB_to_eciCMYK_v2.icc  0   1   0
Graphic_RGB sRGB_to_eciCMYK_v2.icc  0   1   0
Text_RGB    sRGB_to_eciCMYK_v2.icc  0   1   0

to a control.txt file

and use Ghostscript with parameters

-sDEVICE=pdfwrite \
-sColorConversionStrategy=CMYK \
-sSourceObjectICC=control.txt \

where the sSourceObjectICC is the txt file defining which ICC profile and intent should be used for the image, graphic and text RGB objects. For better images where forcing neutrals to K only is not often desired, make another ICC DeviceLink profile with collink but without the -f parameter, and have this profile instead used for the Image_RGB row in control.txt file.