Default color profile of a JPEG file if not sRGB? - imagemagick

I think I am missing the whole point with color profile. I assumed that sRGB was the implicit one for JPEG. But it does not seems to be the case or at least I am doing something wrong with my commands.
Let's take a random image from the web, and use jpgicc to make sure there is no profile:
$ wget https://cloud.githubusercontent.com/assets/1139185/23364727/3da8c474-fcce-11e6-9f39-7e074e78aa33.jpg
$ jpgicc 3da8c474-fcce-11e6-9f39-7e074e78aa33.jpg demo1.jpg
Now let's embed the sRGB.icm profile back in:
$ wget https://raw.githubusercontent.com/mikesplain/imagemagick/master/config/sRGB.icm
$ md5sum sRGB.icm
1d3fda2edb4a89ab60a23c5f7c7d81dd sRGB.icm
$ jpegtran -outfile demo2.jpg -icc sRGB.icm demo1.jpg
And finally apply sRGB.icm:
$ jpgicc demo2.jpg demo3.jpg
So in theory there should be no differences in between demo1.jpg and demo3.jpg, however:
$ compare -metric AE demo1.jpg demo3.jpg null:
106432
So what is the default color profile of a JPEG file if not sRGB.icm (1d3fda2edb4a89ab60a23c5f7c7d81dd) ?

This was an issue with the internal JPEG representation. When I do:
$ jpgicc demo2.jpg demo3.jpg
I decompress a JPEG into an RGB buffer and then convert it back JPEG. So in my case I should have done an extra step:
$ jpgicc demo1.jpg demo4.jpg
Then:
$ compare -metric AE demo3.jpg demo4.jpg null:
0

Related

Convert png images to lossy avif

I try to compress my ~1MB pngs to get a smaller image.
When I compress my images to jpeg with:
for i in card*.png ; do convert -resize 445x625 -background white -flatten "$i" ../medium/"${i%.*}.jpg" ; done
they end up about 100kb
So I tried
for i in card*.png ; do echo $i; convert -resize 445x625 "$i" ../medium/"${i%.*}.avif" ; done
which results in avif images ~400kb, I guess because they are losslessly compressed.
How do I create lossy compressed avif images? And what would be a useful quality level to get images with the text still clearly readeable?
(I use ImageMagick 6.9.10-23 on Ubuntu)
libheif
You can install
apt install libheif-examples
and then use heif-enc to create heif files with:
for i in card*.png ; do echo $i; heif-enc "$i" -o "${i%.*}.avif" ; done
If you need avif format, you need to compile the latest version of libheif, which has the -A option to create avif files.
(There is a section in the README there how to build it on your system. But at least on Ubuntu this is not leading to a running heif-enc)
Better use avifenc:
# Install Homebrew
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
sudo apt install zsh # needed for this pspecific package install
brew install joedrago/repo/avifenc
Now you have the tool to create avif files with the syntax:
avifenc [options] input.[jpg|jpeg|png|y4m] output.avif
(use avifenc --speed 4 --min 20 --max 22 -j 8 to get a higher compression and use all 8 cores)

How does ImageMagick pass options to cwebp Linux

I'm running
$ cat /etc/os-release
PRETTY_NAME="Debian GNU/Linux 9 (stretch)"
NAME="Debian GNU/Linux"
VERSION_ID="9"
VERSION="9 (stretch)"
ID=debian
I'm also running ImageMagick 6.9.
I'd like to convert a PDF image into WebP. AFAIK, out of the box, ImageMagick on Linux cannot convert to WebP, so I sudo apt-get install webp which installs cwebp.
cwebp allows to specify the -q parameter, and ImageMagick allows to specify the -quality parameter.
When I run $ cwebp -q 90 image.png -o image.webp, it takes cwebp around 8 seconds to convert it. If I run convert image.png -quality 90 image.webp, it takes ImageMagick around 30 seconds to convert it. It seems like the -quality parameter is not passed through to cwebp. It also may be the case that convert attempts to run a lossless conversion, which in cwebp is achieved with an explicit -lossless flag.
I run the test commands for a 10 MB test png image.
I would like to achieve 8 second conversion times with convert command. How can I do it?
I realize you want imagemagick, but if you are able to consider alternatives, libvips can do pdf -> webp quickly at the command line, and without any configuring.
For example, with this PDF (Audi R8 brochure) on my 2015 laptop, I see:
$ time convert -density 600 r8.pdf[3] -quality 90 x.webp
real 0m36.699s
user 0m23.787s
sys 0m1.628s
$ vipsheader x.webp
x.webp: 9921x4961 uchar, 3 bands, srgb, webpload
Which I think is broadly in line with the times you are seeing.
With libvips, I see:
$ time vips copy r8.pdf[dpi=600,page=3] x.webp[Q=90]
real 0m7.195s
user 0m6.861s
sys 0m0.505s
$ vipsheader x.webp
x.webp: 9921x4961 uchar, 3 bands, srgb, webpload
The same result, but within your 8s time budget.
You can set a lot of other webp options if you want more control over compression.
It turns out, that the delegates are invoked using the rules in /etc/ImageMagick-6/delegates.xml.
It lists a bunch of rules on how to convert between different types of images.
For my case, the png->webp conversion, I needed the string:
<delegate decode="png" encode="webp" command=""cwebp" -quiet %Q "%i" -o "%o""/>
While in this file I don't know the -quaility parameter value, and there seems to be no way to capture it.
However, if you wish to keep the value of the -q parameter for cwebp, you have the option of hard-coding the -q $YOUR_VALUE right into the command inside the delegate tag.
This solution is still slower than invoking cwebp directly, since ImageMagick can take up to 8 seconds before invoking the delegate.

.CDR to .SVG Convert Using ImageMagick

I am on CentOS 6.4 and trying to convert .CDR to .SVG Convert Using ImageMagick using SSH command.
my 1.cdr file is in /var/www/vhosts/website.com/httpdocs/test/1.cdr
once converted to SVG it should be created in the same folder
Tried the following command:
convert /var/www/vhosts/website.com/httpdocs/test/1.cdr image.svg
The Error I am getting is:
sh: mplayer: command not found convert: Delegate failed "mplayer"
"%i" -really-quiet -ao null -vo png:z=3' #
delegate.c/InvokeDelegate/1032. convert: missing an image filename
image.svg' # convert.c/ConvertImageCommand/2800.
Not sure what does that mean ?
In order to convert CDR files you need to install uniconvertor for CDR delegate.
List of all delegates:
convert -list delegate
By default it outputs:
cdr => "uniconvertor" "%i" "%o.svg"; mv "%o.svg" "%o"
Install uniconvertor. For example, on Ubuntu it’s:
sudo apt-get install python-uniconvertor
Then run:
convert image.cdr -flatten -thumbnail '512x512' image.png
Or, with zoom cropping:
convert image.cdr -flatten -thumbnail '512x512^' -gravity center -crop 512x512+0+0 +repage image.png
And you’re done.
I convert to PNG here but you may use your own output format.
python-uniconvertor is part of inkscape.
It does not exist by itself.
Ubuntu/Mint recently removed all the old Python stuff, for Corel Draw I have to fire up the WinXP VM & Corel and export something Linux understands, usually PNG, a favourite
CDR & WMF files are pretty much dead to Linux, ImageMagick can still handle WMF though.

Can't install GhostScript in ImageMagick

Download latest version of ImageMagick. Unpacked it. Installing Ghostscript like this:
$ sudo apt-get install ghostscript
After that try to configure ImageMagick:
$ ./configure --with-gslib
$ make
$ make install
After that i try to conver PDF to jpg
$ sudo /usr/local/bin/convert in.pdf out.jpg
And i see this mistake
convert: no decode delegate for this image format `/tmp/magick-BzHdr4Kp-00000001' # error/constitute.c/ReadImage/544.
convert: Postscript delegate failed `in.PDF': Нет такого файла или каталога # error/pdf.c/ReadPDFImage/678.
convert: no images defined `out.jpg' # error/convert.c/ConvertImageCommand/3044.
What i'm doing wrong?
Try the following convert commands to see more precisely what's possibly going wrong:
convert a.pdf -debug coder a.jpg
convert a.pdf -debug all a.jpg
There will possibly be a lot of output going to stderr. Amongst the lines you may see where IM is looking for Ghostscript. Also, try
convert -list delegate
convert -list delegate | grep --color -E '(eps|pdf)'
to find with which exact commandlines ImageMagick tries to run Ghostscript (it may call gsx instead of gs, or it may look for it in /usr/local/bin/...). If you find any deviations from your real Ghostscript installation, you can possibly fix it by editing delegates.xml.
convert -list configure
will show you how ImageMagick is configured (and if, for example, gs was during compile-time in the list in DELEGATES variables). Here you also find where to look for delegates.xml:
convert -list configure | grep CONFIGURE_PATH
should list the directory where this (as well as some more) *.xml settings files are located which control how convert et al. behave...

Converting JPEG colorspace (Adobe RGB to sRGB) on Linux

I am generating thumbnails and medium sized images from large photos. These smaller photos are for display in an online gallery. Many of the photographers are submitting JPEG images using Adobe RGB. I have been asked if the thumbnail and medium size images can use sRGB as the images as is appear "flat" in some browsers.
I'm currently using ImageMagick to create the smaller versions. It has a -colorspace option, but that doesn't seem to do what I want.
Is there any other way to do this? Also, do you think this is worthwhile?
You can use the ImageMagic -profile option:
convert image.jpg -profile <adobe.icc> -profile <sRGB.icc> new_image.jpg
See here for more details:
http://www.imagemagick.org/Usage/formats/#color_profile.
Have you tried using Little CMS? This command will convert an image with a special color profile (i.e. Adobe RGB 1998) to one with no color profile but the same effective colors:
jpgicc -q100 input.jpg output.jpg
I'm setting JPEG quality to 100 here.
The following thread in the ImageMagick forum discusses exactly this in some detail: http://www.imagemagick.org/discourse-server/viewtopic.php?f=1&t=16464
I now use this bash script to convert any picture (including CMYK) to sRGB:
http://alma.ch/scripts/any2srgb
It requires icc profiles for images which don't have embedded profiles. These can be found easily on the web. For example on Adobe's site: http://www.adobe.com/cfusion/search/index.cfm?term=icc+profile&siteSection=support%3Adownloads
Here is a summary (untested) of what the full script does (without it's resize and other options). It requires profiles and ImageMagick. On Debian-based systems: apt-get install icc-profiles imagemagick.
#!/bin/bash
srgb=sRGB.icm
cmyk=ISOwebcoated.icc
# extract possible color profile
profile="${f/%.*/.icc}"
convert "$f" "icc:$profile" 2>/dev/null
if cmp -s "$profile" "$srgb" ; then
# embedded profile is already srgb. Nothing to do
exit
fi
if [ -s "$profile" ]; then
# we have an embedded profile, so ImageMagick will use that anyway
convert "$f" -profile "$srgb" +profile '*' "$outfile"
else
# no embedded profile in source
if identify -format "%r" "$f" | grep -q CMYK; then
# CMYK file without embedded profile
convert "$f" -profile "$cmyk" -profile "$srgb" "$outfile"
fi
fi
Re-exporting the image using Krita seems to work well enough for me:
krita my_img.jpg --export --export-filename my_img_in_srgb.jpg
Krita is an open source Photoshop/Paint, with a(n extremely limited) command line interface. Install it with
sudo apt install krita

Resources