Closed ferryfax closed 6 years ago
This is a bug :( sorry. Fixed with this patch:
ie. import CMYK images right at the start.
It'll be in 7.40.5, due rsn.
Hey John, I tried VipsThumbnail from 7.40.5-1 under Windows and got the same error.
Did the fix make it into that version?
You'll still get the error if the image has no ICC profile embedded in it. In that case you'll need to provide a profile for vipsthumbnail
to use to import the image.
It should now do the right thing if the image does have an embedded profile.
Hi, I'm using vips: stable 7.40.10 and I get this error. Is that normal? The image is here: https://infinitely-production.s3.amazonaws.com/uploads/assets/attachment/5187ae04f3317f2f1f00164a/Jacinto_Lirio_kwaderno.jpg
Here's the full metadata of the image
identify -verbose Jacinto_Lirio_kwaderno.jpg
Image: Jacinto_Lirio_kwaderno.jpg Format: JPEG (Joint Photographic Experts Group JFIF format) Mime type: image/jpeg Class: DirectClass Geometry: 4961x3508+0+0 Resolution: 300x300 Print size: 16.5367x11.6933 Units: PixelsPerInch Type: ColorSeparation Endianess: Undefined Colorspace: CMYK Depth: 8-bit Channel depth: cyan: 8-bit magenta: 8-bit yellow: 8-bit black: 8-bit Channel statistics: Pixels: 17403188 Cyan: min: 0 (0) max: 100 (0.392157) mean: 3.0409 (0.0119251) standard deviation: 16.4575 (0.0645393) kurtosis: 25.6952 skewness: 5.25657 Magenta: min: 0 (0) max: 135 (0.529412) mean: 4.28151 (0.0167902) standard deviation: 23.1797 (0.0909008) kurtosis: 25.6952 skewness: 5.25664 Yellow: min: 0 (0) max: 255 (1) mean: 8.29823 (0.0325421) standard deviation: 44.9226 (0.176167) kurtosis: 25.6945 skewness: 5.25658 Black: min: 0 (0) max: 49 (0.192157) mean: 1.50316 (0.00589474) standard deviation: 8.13645 (0.0319076) kurtosis: 25.6944 skewness: 5.2565 Image statistics: Overall: min: 0 (0) max: 255 (1) mean: 4.28095 (0.016788) standard deviation: 26.8905 (0.105453) kurtosis: 61.5876 skewness: 7.59952 Total ink density: 209.02% Rendering intent: Perceptual Gamma: 0.454545 Chromaticity: red primary: (0.64,0.33) green primary: (0.3,0.6) blue primary: (0.15,0.06) white point: (0.3127,0.329) Background color: cmyk(255,255,255,0) Border color: cmyk(223,223,223,0) Matte color: cmyk(189,189,189,0) Transparent color: cmyk(0,0,0,0) Interlace: None Intensity: Undefined Compose: Over Page geometry: 4961x3508+0+0 Dispose: Undefined Iterations: 0 Compression: JPEG Quality: 99 Orientation: Undefined Properties: date:create: 2014-10-04T12:55:45-04:00 date:modify: 2013-05-06T09:20:13-04:00 jpeg:colorspace: 4 jpeg:sampling-factor: 1x1,1x1,1x1,1x1 signature: e2bee6d037910f0b23db5881471ba9e735bfa6e1ac26fad8a6eda20a1b277ed2 Profiles: Profile-8bim: 28 bytes Profile-icc: 557168 bytes Artifacts: filename: Jacinto_Lirio_kwaderno.jpg verbose: true Tainted: False Filesize: 2.595MB Number pixels: 17.4M Pixels per second: 47.04MB User time: 0.370u Elapsed time: 0:01.370 Version: ImageMagick 6.8.9-7 Q16 x86_64 2014-08-31 http://www.imagemagick.org
It should work, I see this:
$ vipsthumbnail --vips-info Jacinto_Lirio_kwaderno.jpg
info: vipsthumbnail: thumbnailing Jacinto_Lirio_kwaderno.jpg
info: vipsthumbnail: selected loader is VipsForeignLoadJpegFile
info: vipsthumbnail: loading jpeg with factor 8 pre-shrink
info: vipsthumbnail: importing with embedded profile
info: vipsthumbnail: converting to processing space srgb
info: vipsthumbnail: integer shrink by 2
info: vipsthumbnail: anti-alias, sigma 1.28125
info: vipsthumbnail: residual scale by 0.412903
info: vipsthumbnail: bicubic interpolation
info: vipsthumbnail: converting to sRGB
info: vipsthumbnail: sharpening thumbnail
info: vipsthumbnail: thumbnailing Jacinto_Lirio_kwaderno.jpg as ./tn_Jacinto_Lirio_kwaderno.jpg
$ vipsthumbnail --vips-version
libvips 7.40.10-Sun Oct 5 09:29:34 BST 2014
What command did you run?
I'm using sharp https://github.com/lovell/sharp, which is using libvips
Sorry, then I don't know. Have you tried opening an issue there?
First, @jcupitt, congratulations on the fantastic library!
I am running into the vips_colourspace: no known route between 'cmyk' and 'srgb'
issue with libvips 8.3.3
on debian 8.5.
I am trying to convert a page from a PDF to JPG. The conversion works fine with the same file and same libvips
version on OS X.
The exact command:
vipsthumbnail my.pdf[page=5] -o out.jpg -s 595x842
The errors:
vipsthumbnail: unable to thumbnail my.pdf[page=5]
vips_colourspace: no known route between 'cmyk' and 'srgb'
Is it possible I am missing a library handling this conversion on the server? (I checked and I do have both liblcms2-2:amd64
as well as liblcms2-dev:amd64
installed.)
Thank you for your help.
Hi @tomasc, libvips now has two ways to import PDF files, I think your two installs are using different paths.
The old way is via libMagick. This uses (in turn) gs
to import CMYK PDFs as true CMYK images, so you'll need to get a profile from somewhere if you want to convert to sRGB for save.
The new way is via libpoppler and the pdfload
operation. This is much, much faster and more memory efficient, but it always generates an sRGB image, it cannot make CMYK.
Unless you really need exact CMYK values, I would suggest the new libpoppler route. I would check for poppler-glib
on the linux server.
hi @jcupitt thanks a lot for getting back to me so quickly. i saw your posts re poppler & pdf so i took care to install libpoppler-glib-dev
, libpoppler-glib8
etc. and indeed i have libmagic
installed as well. could it be that the libmagic
takes precedence? is there a way to enforce the use of poppler
or do i simply need to uninstall everythig related to libmagic
?
libMagick will always come last. Check the output of configure and make sure you have something like:
PDF import with poppler-glib: yes
(requires poppler-glib 0.16.0 or later)
near the end. You can verify that poppler really is being used to read your PDFs with vipsheader
. You should see:
$ vipsheader nipguide.pdf
nipguide.pdf: 595x841 uchar, 4 bands, srgb, pdfload
ie. the libpoppler pdfload
operation was used to load the image. You'll see something like:
$ vipsheader dicom_test_image.dcm
dicom_test_image.dcm: 128x128 ushort, 1 band, grey16, magickload
if it's libMagick.
@jcupitt you're right!
595x842 ushort, 4 bands, cmyk, magickload
I will try to recompile, hope that solves the issue.
Yes, you must reconfigure vips after installing libpoppler-glib-dev
.
@jcupitt thanks again for help, i compiled libpoppler from source (there is no >= 0.3 version package for debian jessie for example), recompiled vips and eveything now works perfectly.
Good to hear!
I noticed your dragonfly with vips, it looks nice. Did you consider using ruby-vips rather than a command-line interface? It should be possible to get a useful speedup by calling the library directly.
Interesting!
What the dragonfly gems do is that they chain processing of files -- they convert one tempfile into another. Intuitively I thought command line would be fastest for this (esp. knowing ruby is not particularly known for its performance). Besides wouldn't I have to reimplement all the nice work you did for vipsthumbnail? Why do you think that using the ruby-vips would be more performant?
It depends what you are doing. For thumbnailing, ruby-vips would be no faster, but if you are doing more complex processing, like watermarking or adding a drop shadow, ruby-vips will be a lot quicker.
The command-line interface runs operations one after the other, with a lengthy read phase and write phase between each one as images are written to temp files and then immediately read back in.
ruby-vips can use the libvips chaining mechanism. If you run a sequence of operations in ruby-vips, perhaps:
im = Vips::Image.new_from_file "test.tif", :access => :sequential
text = Vips::Image.text "Hello world!", :dpi => 300
text = (text * 0.3).cast(:uchar)
text = text.embed 100, 100, text.width + 200, text.height + 200
text = text.replicate 1 + im.width / text.width, 1 + im.height / text.height
text = text.crop 0, 0, im.width, im.height
im = text.ifthenelse [255, 0, 0], im, :blend => true
im.write_to_file "out.tif"
(the watermarking example), ruby-vips will not actually execute any of the operations until you reach the final .write_to_file
, it just constructs an image-processing pipeline. When you execute the final write, the whole pipeline runs at the same time, all in parallel. This gives a huge speedup on systems with many cores. Moreover, there's no load/save between operations, which gives another big speedup. And finally the images are streamed, ie. they pass through the pipeline in small 128x128 pixel chunks, so there's an enormous memory saving too.
I'll try a command-line version of that thing and time it, hang on.
Here's watermarking in sh and ruby-vips:
#!/usr/bin/ruby
require 'vips'
im = Vips::Image.new_from_file ARGV[0], :access => :sequential
text = Vips::Image.text ARGV[2], :dpi => 300
text = (text * 0.3).cast(:uchar)
text = text.embed 100, 100, text.width + 200, text.height + 200
text = text.replicate 1 + im.width / text.width, 1 + im.height / text.height
text = text.crop 0, 0, im.width, im.height
im = text.ifthenelse [255, 0, 0], im, :blend => true
im.write_to_file ARGV[1]
#!/bin/bash
infile=$1
outfile=$2
str="$3"
# make text mask
vips text t1.v "$str" --dpi 300
vips linear t1.v t2.v 0.3 0
vips cast t2.v t1.v uchar
text_width=$(vipsheader -f width t1.v)
text_height=$(vipsheader -f height t1.v)
text_width=$((text_width + 200))
text_height=$((text_height + 200))
vips embed t1.v t2.v 100 100 $text_width $text_height
im_width=$(vipsheader -f width $infile)
im_height=$(vipsheader -f height $infile)
across=$((1 + im_width / text_width))
down=$((1 + im_height / text_height))
vips replicate t2.v t1.v $across $down
vips crop t1.v text.v 0 0 $im_width $im_height
# make solid colour
vips black t1.v 1 1
vips linear t1.v t2.v 1 "255 0 0"
vips cast t2.v t1.v uchar
vips embed t1.v colour.v 0 0 $im_width $im_height --extend copy
# combine
vips ifthenelse text.v colour.v $infile $outfile --blend
With a large image on my little two-core laptop, I see:
$ time ./watermark.rb ~/pics/wtc.jpg x.tif "hello world"
real 0m2.006s
user 0m3.852s
sys 0m0.280s
$ time ./watermark.sh ~/pics/wtc.jpg x.tif "hello world"
real 0m3.867s
user 0m4.384s
sys 0m1.340s
So about a 2x speedup. It would be more on a larger machine, I expect.
Last post: of course you could keep shelling out to run vipsthumbnail
, but implement other stuff in ruby-vips, perhaps.
I see, that's very good, solid performance gain. I will def. switch over to ruby for some more complex operations. Thanks a lot for the explanation.
BTW I thought it would be very nice to have some of the image magick's geometry behaviour implemented in the vipsthumbnail
– for example ability to specify width or height only (NNx
and xNN
) and no resize when source is larger or smaller (NNxNN>
and NNxNN<
) – see http://www.imagemagick.org/script/command-line-processing.php#geometry
Would you be open for adding these? I wrote the necessary calculations here in Ruby https://github.com/tomasc/dragonfly_libvips/blob/master/lib/dragonfly_libvips/dimensions.rb and would like to help to get them included vipsthumbnail
as these seem to be frequently used when generating image thumbnails.
Sure, why not, open a new issue and tag it as an enhancement.
Great, I posted as #503 but can't seem to be able to add labels. Let me know if I can help implementing this.
Run into this problem myself for a cmyk image with no profile. Is the some way I can tell it to use a default profile or something? I mean, if I don't know in advance whether the image has a profile or not, how can I provide a default profile without overriding any existing one?
Hello @andrews05, sure, you can give a fallback profile to thumbnail
:
http://jcupitt.github.io/libvips/API/current/libvips-resample.html#vips-thumbnail
From the command-line, for example:
$ vips thumbnail cmyk.tif x.jpg 128 --import-profile generic-cmyk.icm
And it'll use the generic profile you specify if the TIFF file does not have oine embedded.
In case anyone stumbles across this old issue -- thanks to work by tomasc, since libvips 8.5 you can give geometry specifications like 128x>
or '99x99!to
vipsthumbnail`.
Thank you. Is it possible to use thumbnail without changing the colorspace? Just keep a cmyk image as cmyk, without having to specify any profiles.
[edit] To clarify, here's how things are working to the best of my understanding: If I thumbnail a cymk image with a profile, output is cmyk. If it has no profile, it complains about "no known route". If I provide a cmyk import profile, output is rgb. If I provide both an import and an export profile, output is cmyk, but this will throw errors if the input was actually rgb. My ideal world: A single set of options that can thumbnail all images, with either a) all retaining their colorspace, or b) all being converted to rgb. Sorry, I don't understand a whole lot about this stuff, all I know is imagemagick never required me to specify profiles :)
Hello again, it does the shrinking in RGB colourspace, so CMYK images are actually processed as CMYK -> RGB -> CMYK. This is because CMYK is very non-linear and simply averaging pixels gives ugly results.
You're right, to get the behaviour you want at the moment you need a separate command for CMYK images.
I'll have a think, perhaps this can be improved.
I think I found an improvement! icc_import
was not attaching the fallback profile to the output image if it used it, so thumbnail
was unable to get back to CMYK. I've added a thing to 8.6 to fix this and I now see:
john@kiwi:~/pics$ vipsthumbnail cmyk-no-profile.jpg
vipsthumbnail: unable to thumbnail cmyk-no-profile.jpg
vips_colourspace: no known route from 'cmyk' to 'srgb'
john@kiwi:~/pics$ vipsthumbnail cmyk-no-profile.jpg --iprofile ~/GIT/nip2/share/nip2/data/cmyk.icm
john@kiwi:~/pics$ vipsheader tn_cmyk-no-profile.jpg
tn_cmyk-no-profile.jpg: 128x85 uchar, 4 bands, cmyk, jpegload
So it's picking up the fallback profile to get back to CMYK again after the thumbnail operation.
This change will be in 8.6.3, due in a few days. Thanks!
Sounds great, that should be a big help.
Testfile: https://drive.google.com/file/d/1b7FzZZKJhrLnlb-5bYsUwuzRSEhKltBA/view?usp=sharing Version: vips-8.6.4-Wed Jun 13 15:24:52 UTC 2018
cli command: vips colourspace test_CMYK.jpg rgb.jpeg srgb vips_colourspace: no known route from 'cmyk' to 'srgb'
Did I do something wrong to convert to srgb or rgb?
Hello, convert CMYK jpg images to sRGB like this:
$ vips icc_transform cmyk.jpg x.jpg /usr/share/color/icc/colord/sRGB.icc
That's assuming your jpg image has an embedded CMYK profile.
libvips does not have a built-in CMYK -> $x converter, you need to use lcms via the icc_import
/ icc_export
/ icc_transform
operations.
Ok thx both cli's are working
vips icc_transform test_CMYK.jpg rgb.jpg ../icc/RGB/AppleRGB.icc
and
vips icc_import test_CMYK.jpg rgb.jpg --input-profile icc/CMYK/USWebCoatedSWOP.icc
icc_import replaces the color profile selected but also to color space RGB, i expected it would have kept the CMYK color space?
icc_import
takes the image to PCS (CIELAB by default). When you write a CIELAB image to JPG, libvips uses an internal converter to make sRGB for you. Try:
john@yingna ~/pics $ vips icc_import cmyk.jpg x.v
john@yingna ~/pics $ vipsheader -a x.v
x.v: 1419x1001 float, 3 bands, lab, jpegload
width: 1419
height: 1001
bands: 3
format: float
coding: none
interpretation: lab
xoffset: 0
yoffset: 0
xres: 11.808
yres: 11.808
filename: x.v
vips-loader: jpegload
jpeg-multiscan: 0
jpeg-chroma-subsample: 4:4:4:4
exif-data: 186 bytes of binary data
resolution-unit: in
...
icc-profile-data: 961644 bytes of binary data
So the vips format image still has the CMYK profile, it's the implicit conversion to RGB on jpg write that drops it.
Thx ps is their a way to get the vipsheader output when using govips that you can tell at first look ?
https://godoc.org/github.com/davidbyttow/govips/pkg/vips
Or do I need to find a other go wrap library specifically for vipsheader?
Sorry, I don't know, I didn't make govips, you would need to ask there. In Python, for example, it's image.get('icc-profile-data')
. Maybe something similar?
Please open a new issue if you have a new question: it'll make it easier for others to find answers.
@jcupitt I am checking if this bug also affected icc_transform
. Currently, nodejs library Sharp is using it and I see error vips_colourspace: no known route from 'srgb' to 'cmyk'
when I try to convert to CMYK with that library.
Sharp is currently not using 8.6.3
so just checking if updating libvips will solve issue for sharp.
Please don't post on closed issues, it just causes confusion.
It's not really a bug -- colourspace
just can't convert to CMYK. Use icc_transform
plus a profile instead.
Sorry I missed your last comment. I will create new one if I need further information.
Quick question. To avoid this message from vipsthumbnail do I need to supply an appropriate icc profile?