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)
Related
I have a sequence of images that are blocks of a larger image, which together make up the whole image. The blocks are the result of splitting the original image along evenly spaced horizontal and vertical lines, so they don't have weird dimensions.
Is there a way to combine them with FFmpeg (or something else like ImageMagick) without re-encoding the images?
This answer suggests the hstack or vstack FFmpeg filter, but my image blocks aren't necessarily the full width or the full height of the original image.
Like this:
Perhaps this could be achieved with multiple FFmpeg commands using hstack or vstack (I'd prefer just one command though). Or with a complex filter?
e.g.
Edit: I tried using filter_complex with FFmpeg:
ffmpeg -i 0.jpg -i 1.jpg -i 2.jpg -i 3.jpg -i 4.jpg -i 5.jpg \
-filter_complex "[0][1]hstack=inputs=2[row 0]; \
[2][3]hstack=inputs=2[row 1];
[4][5]hstack=inputs=2[row 2];
[row 0][row 1][row 2]vstack=inputs=3[out]" \
-map "[out]" -c copy out.jpg
but it can't filter and copy streams at the same time.
You can do that with ImageMagick. However, it will decompress and recompress your jpg files. You will lose some quality.
Unix Syntax for IM 6:
convert \
\( 0.jpg 1.jpg +append \) \
\( 2.jpg 3.jpg +append \) \
\( 4.jpg 5.jpg +append \) \
-append \
mona_lisa.jpg
If using Windows remove the \ from the parentheses and replace the end of line \ with ^.
If using IM 7, replace convert with magick.
I found an interesting patch from 2010 against libjpeg which adds this feature to jpegtran. It won't split blocks, so your images will need to be multiples of 8 or even 16 pixels in each axis.
Unfortunately it's against the libjpeg 6b as distributed for ubuntu10. This includes some patches from 8d and doesn't really correspond neatly to any official libjpeg version (as far as I can see).
You need to download the ubuntu10.04 sources, extract their libjpeg, and patch that. The steps are:
wget http://old-releases.ubuntu.com/releases/releases/10.04/release/source/ubuntu-10.04-src-1.iso
Now open that ISO and pull out the files from ubuntu/pool/main/libj/libjpeg6b. Archive Manager can do this, perhaps there's some scriptable tool as well.
Now run:
# original sources
tar xf libjpeg6b_6b.orig.tar.gz
cd jpeg-6b
# apply ubuntu patches
zcat ../libjpeg6b_6b-15ubuntu1.diff.gz | patch
# apply jpegtran patches
patch < ../append-jpeg6b.patch
./configure
make
sudo make install
That will install the modified jpegtran to /usr/local.
Given 0.jpg and 1.jpg:
You can run it like this:
jpegtran -appright 1.jpg 0.jpg > join.jpg
To make:
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.
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.
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...
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