ImageMagick Mogrify: batch with watermark - imagemagick

I have a strange probleam with running ImageMagick mogrify on several files. I use conversion string to make several transformation on images, which results in thumbnails. The command with the conversion string runs fine on single file, however when ran on a batch of files, it sometimes fails. Here is the command (windows command line):
"C:\Program Files\ImageMagick-6.3.5-Q16\mogrify" \
-format jpg \
-thumbnail 400x400">" \
-background white \
-gravity center \
-extent 400x400 \
-draw "image src-over 0,0 0,0 '//dell1/Oracle/files/watermark.png'" \
-path \\dell1\Oracle\files\pictures\cj4uoveomiggda97kmqttn0400 \
\\dell1\Oracle\files\pictures\59\59p5huflk2cnv9drf3r1d65ef9_wc \
\\dell1\Oracle\files\pictures\7v\7vi3q26cdidk8bproslhhmlkab_wc \
\\dell1\Oracle\files\pictures\ft\ft0iqkjk08cli8k0iltgmdmfo5_wc
and it fails with message "mogrify: Non-conforming drawing primitive definition `image'."
But I've found out, that this happens only when inserting a wattermark. I've also found out that when I change order of the 3 files which are to be processed, the mogrify runs fine, which is pretty strange. I have no idea why this happens and how to get rid of it.
PS: I execute this command from a java application, so using a batch file with repeated calling of convert command is not acceptable solution for me.
Any clues appreciated, many thanks.

Solved this by installing newer version of ImageMagick :/

Related

Merge a sequence of JPEG images into a grid losslessly with FFmpeg

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:

Run convert from ImageMagick script file

I am trying to stitch (thousands) of images together via coordinate system using ImageMagick. Because the command is so long, I can't pass it via CLI, but have to save it to a script to load later.
The script looks like this:
script.txt
convert
( foo.png -repage +0+0 )
( bar.png -repage +0+37 )
-layers merge
out.png
I then run magick.exe -script script.txt
But get the following error:
magick.exe: unable to open image 'convert': No such file or directory # error/blob.c/OpenBlob/3457.
magick.exe: no decode delegate for this image format `' # error/constitute.c/ReadImage/512.
The -script command is for ImageMagick 7. You must explicitly -write the output in the script command. See http://www.imagemagick.org/Usage/bugs/IMv7_Scripting.txt
For example, here is a simple script file that I call testscript
#!/path/to/magick -script
rose: -scale 200% -write big_rose.png
To run it you simple use:
magick -script testscript
So for your command, try the script as
#!/path/to/magick -script
( foo.png -repage +0+0 ) ( bar.png -repage +0+37 ) -layers merge -write out.png
(Note I have written it as one line. If you want to use multiple lines, then you must use Windows line ending character, ^, at the end of each line to show continuation to the next line)
Then call it as
magick -script yourscript

Resize indexed PNG image with ImageMagick while preserving color map

I am using custom batch script to make resized copies (33% and 66%) of all PNG images in folder. Here is my code:
for f in $(find /myFolder -name '*.png');
do
sudo cp -a $f "${f/%.png/-3x.png}";
sudo convert $f -resize 66.67% "${f/%.png/-2x.png}";
sudo convert $f -resize 33.33% $f;
done
It works fine, except when the original image is indexed. In this case the smaller version of the image is RGB (so even larger file size then original image).
I have try several versions but not worked. One that I guess supposed to sort this out was fallowing:
for f in $(find /myFolder -name '*.png');
do
sudo cp -a $f "${f/%.png/-3x.png}";
sudo convert $f -define png:preserve-colormap -resize 66.67% "${f/%.png/-2x.png}";
sudo convert $f -define png:preserve-colormap -resize 33.33% $f;
done
But it doesn't work.
EDIT:
This is updated co, but it still doesn't work as it supposed to (see the attached image-left is original, right is resized):
for f in $(find /myFolder -name '*.png');
do
sudo cp -a $f "${f/%.png/-3x.png}";
numberOfColors=`identify -format "%k" $f`
convert "$f" \
\( +clone -resize 66.67% -colors $numberOfColors -write "${f/%.png/-2x.png}" +delete \) \
-resize 33.33% -colors $numberOfColors "$f"
done
Original image:
Scaled version:
Use "-sample" instead of "-resize" to preserve the color set. This causes the resizing to be done by nearest-neighbor color selection rather than any kind of interpolation.
Otherwise, the colormap ends up with more than 256 colors and the png encoder can't preserve it, due to the 256-color limit on the size of a PNG PLTE chunk. I cannot guarantee that you'll like the appearance of the result, though.
Also, be sure you are using a recent version of ImageMagick.
I'm not observing this problem with the current release (6.9.3-7). Your script works fine and produces clean -2x and -3x images.
There are several things to address here...
find vs glob
You say you want to process all files in a folder, then you use find which will search down into sub-directories as well. If you just want to process files in the current directory, you can let bash do the globbing directly for you. So, instead of
for f in $(find . -name "*.png"); do
you can just do:
shopt -s nullglob
for f in *.png; do
Performance
You run convert twice and load the original image twice, and that is not very efficient. You can run a single process that loads a single image and resizes to two different sizes and writes both to disk. So, instead of
for ...; do
convert ...
convert ...
done
you can write the following to start one convert, read the image once, clone it in memory and write it out, delete the spare copy in memory and then resize the original image and re-save that.
for ...; do
convert "$f" \
\( +clone -resize 66.67% -write "${f/%.png/-2x.png}" +delete \) \
-resize 33.33% "$f"
done
Palette
It seems you actually only want to output palettised (indexed) images with "any" colormap rather than with a "specific" colormap. Glenn's answer is perfect if you want to retain a specific colormap. However, if any colormap is ok, you can use -colors to reduce the colours in the resulting image to a level where the PNG library can make the decision to create a palettised image. Glenn knows a lot more than me about that as he wrote it! However, I think if you reduce the colours to 250 (or so) you will probably get a 256 entry colormap and if you reduce the colours to around 60 or so, you will get a 64 entry colourmap. So, you would do:
shopt -s nullglob
for f in *.png; do
sudo cp ... ...
convert "$f" \
\( +clone -resize 66.67% -colors 250 -write "${f/%.png/-2x.png}" +delete \) \
-resize 33.33% -colors 250 "$f"
done
You can try experimenting with other numbers of colours and see how that affects filesize - the number you need will depend on your images.

.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.

How to convert a JPEG image into SVG format using ImageMagick?

How to convert a JPEG image into SVG format using ImageMagick?
you'll need to use potrace and convert to a bitmap first.
$convert input.jpg output.ppm
$potrace -s output.ppm -o svgout.svg
Actually, with a complete installation of a recent version of ImageMagick it should be as easy as:
convert some.jpeg some.svg
Of course, ImageMagick cannot do it all by itself -- it uses delegates (helper programs) to handle SVG input or output. (This has been pointed out by other answers already.)
To see a (partial) list of all delegates (and their respective commands), run
convert -list delegate
To see the config file where all the delegate secrets hide, see
convert -list delegate | grep delegates.xml
To see a (partial) list of SVG handling delegates, run
convert -list delegate | grep -i svg
However, ImageMagick likes to put some of its external helper utilities into 'stealth' mode and doesn't necessarily reveal their presence when using above commands.
Just look into the delegates.xml file itself. On my system it's:
grep -i svg /opt/local/etc/ImageMagick/delegates.xml | grep -i --color stealth
<delegate decode="autotrace" stealth="True" \
command=""/opt/local/bin/convert" "%i" \
"pnm:%u"\n\
"/opt/local/bin/autotrace" \
-input-format pnm \
-output-format svg \
-output-file "%o" "%u""/>
<delegate decode="svg:decode" stealth="True" \
command=""/opt/local/bin/inkscape" "%s" \
--export-png="%s" \
--export-dpi="%s" \
--export-background="%s" \
--export-background-opacity="%s" \
> "%s" 2>&1"/>
As you may see, on my system the ImageMagick installation automatically uses (amongst others)...
...inkscape to convert SVG to PNG;
...autotrace to convert PNM to SVG;
Of course, one could argue the benefits of rather using autotrace directly -- but that would require to manually convert the whatever-input-format to PNM first. So for this preliminary step you'd probably use ImageMagick anyway...
You'll actually need some software or code to vectorize your image in between, as jpg is a raster format, while SVG is a vector format. I don't think imagemagick alone can do that for you.

Resources