16 bit TIFF file #144
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
I am trying to convert a 16bit CMYK image to PDF.
When I use
I get
Is it possible to support 16bit TIFF data with img2pdf?
Can you share your input tif image? How did you create it?
Here is a PIL issue about this: https://github.com/python-pillow/Pillow/issues/1888
Either this limitation of PIL gets fixed or we write our own parser of some image format that understands CMYK as well as 16 bit samples. Does such a format exist apart from tif?
You could also first convert your image to 8bit but that wouldn't be lossless anymore of course. :/
I'm afraid I do need 16bit as the CMYK ends up sent to a non-linear device where 8 bits isn't smooth enough.
Here is a 16bit image of colour test patches made with argyllcms.
Doesn't look like we can hold out much hope for Pillow support soon. Imagemagick has decent enough 16bit handling (though their PDF output isn't so great and only does 8bit).
Photoshop PSD can hold 16bit fine (though not really an easier to support support than TIFF).
Imagemagick can write out raw CMYK data, but with no header so not even row length is included.
Interesting though: Imagemagick also has its own MIFF format, an ASCII header followed by the raw data. That looks pretty simple to parse.
https://imagemagick.org/script/miff.php
Hrm... yeah parsing MIFF is an option but I don't really like splitting off a imagemagick process to create the MIFF. This will be very platform specific. Your problem is also that you need CMYK or otherwise you could use PNG as another format that supportrs 16bit while at the same time we do not go through PIL to include it. So 16bit PNG works well but only as RGB and not as CMYK.
What are you doing with the PDF in the end? Why the need not only for 16bit but also for CMYK? Usually I see people use 16bit if they have medical imaging data as input where the color channels map to different sensors. But then I'm puzzled that CMYK is needed. Can printers print precisely enough for 16 bit colors?
The printer does dither to 16 bits, but the individual steps would likely not be visible. If the printer's response was roughly perceptually linear then 8bit would be enough but as it is I need extra headroom so when input values are mapped into a small part of the device range they still get discrete output values and smooth gradients (the full 16 bits aren't really needed, but more than 8).
You're right that 16 bit RGB PNGs work fine. These days things mostly work well with sending RGB to print drivers and letting the device/driver do the conversion, but I'm using a non-standard ink set and doing that the response is too irregular (and non-monotonic) to be corrected by a profile. So, I'm looking at CMYK where I can control the black separation myself.
I'd be very happy with MIFF support built in rather than img2pdf trying to manage Imagemagick converting itself. I can easily put the Imagemagick conversion in my workflow, and anyone else with an unusual format supported by IM could do likewise.
A non-standard ink set... At which point should I get worried what people are doing with my software? :D
So I guess you want to convert your tiff into pdf because pdf is what you send to your printer? I'm surprised that your printer driver preserves the full 16bit cmyk but great if it does! If you have a website, blog or scientific paper describing what you do, I'd love to read it. :)
Ah you are right, if img2pdf would get MIFF reading support then this would solve your problem and could be done without using either PIL or calling imagemagick from within img2pdf. I think this can be done! Either wait until I find some freetime to implement this myself or, if you don't want to wait, feel free to send a merge request implementing MIFF input for me to review.
Thanks!
Ha ha. Nothing as exciting as you're thinking, just syringe refilling cartridges with actual ink, but not a good match to that the printers were tuned with.
There are quite a few users for adapted prosumer printers though. T-shirt printers find it's a very cost effective way to get a high quality print head, but you're always pushing against the manufacturers' view of how things should work.
If I get somehting working I'll send you a PR.
Here is a MIFF parser:
The code above works with all my MIFF test cases. Now I just need a 16 bit CMYK MIFF image. If I try to convert your
testCMYK.tif
to MIFF using convert I get:Do you have more luck or can supply me with a 16 bit CMYK MIFF file?
Something about your TIFF file seems odd. When I run
tifftopnm
fromnetpbm
I get the following message:so then I ran
tiffinfo
on your file and I got this:So is this really a CMYK TIFF or is it just a cyan, magenta, yellow TIFF?
In any case, I managed to create a 16 bit CMYK test file by converting a 16 bit RGB png to CMYK using:
That MIFF file then looks how we would like it:
And together with the following patch I get a 16 bit CMYK PDF as I put into the attachment:
https://paste.debian.net/1245266/
Curious. It is CMYK (it's 4 channel and the InkSet:1 on last line of your tiffinfo output means exactly this), but it does seem to have only cmy inks named which is perhaps capable of confusing some applications.
Certainly, my version of ImageMagick (default Ubuntu 20.04 package) has no problem with the testCMYK TIFF.
It will happily process it, including converting to MIFF. It also opens fine as a 16bit CMYK file in KDE krita (not gimp which doesn't handle cmyk).
In any case, your patch works a treat and (via converting to a MIFF) I can embed testCMYK in a pdf successfully. Fantastic - Thanks!
The new code is rather python 3.10-y in it's use of match. I had to install a newer interpretor to get it to run on Ubuntu 20.04. Something to note if you merge into the mainline.
From the patch:
Note you can quite easily create a 16bpc CMYKA MIFF file with
Remove the
-depth 16
or-colorspace cmyk
for 8bit or RGBA.thank you for your feedback!
i committed the preliminary MIFF support to main and will add more test cases later but your use-case of 16bit CMYK should be covered already so have fun! :)
As @jpnp has mentioned already, the new MIFF parser code uses
match
/case
, which is only available since Python 3.10. You'll either want to setpython_requires
to>= 3.10
insetup.py
, or switch back to classicalif
clauses.@mara0004 yeah i'm still thinking about that bit. The
match
/case
syntax is a feature i've waited for since i started using python a decade ago so i'm really eager to use it now. I'm not sure how much of a problem this is for any users.While newer Linux distributions probably come with recent enough versions of Python, I think it might cause trouble for users who are still on older distros. Installing another Python in parallel isn't always desirable, and might not be an option if img2pdf is used in a larger app or framework that depends on system packages.
I too have been looking forward to the introduction of a switch/case-like feature in Python, but am quite disappointed with the way it was implemented. As you might have noticed, non-dotted constants aren't usable with Python's match/case. The increased indentation level doesn't feel very nice, either.
Both Debian Stable, and Ubuntu 20.04 (it'll be a while before we upgrade at work) are pre 3.10 - never mind RHEL and the rest. I'd guess that unless they have a specific need for a newer version, users on those OSs are using the .debs anyway.
I think it's OK to use match (it's easy to see how much cleaner it makes the parsing code), but you'd want to flag it in the package metadata, and in the installation section of the Readme. Finding out while trying it out is more off-putting.
@mara0004 thank you for your input -- i've reverted the match/case usage for now:
af6fe27d53