How to watermark animated GIFs and combine 2 ImageMagick commands together? - windows

I am on a Windows 7 machine using imagemagick from the command line.
The following code works to add watermarks to images:
composite \
-watermark 30% \
-gravity south \
the_watermark.png \
pic_to_be_watermaked.png \
watermark_completed.png
Problems are:
It doesn't work when I try to watermark an animated GIF
How to use this watermark command in conjunction with the command below?
This command takes all the PNGs inside the folder "static_images" and combines them into an animated GIF. It also makes sure that the image is 350px in width and the height is kept to the proper aspect ratio. It also gives the image some fuzz and sets the speed of the animation to 4 and makes sure it loops infinitely:
convert \
-resize 350x350 \
-fuzz 1.6% \
-delay 4 \
-loop 0 \
static_images/*.png \
-layers OptimizePlus \
-layers OptimizeTransparency \
animated_gif.gif
Questions:
How can I combine the watermark command with the one above?
How can I get the watermark commmand to work with animated GIFs?

Is this the result you'd like to see?
The trick is to watermark each PNG source file first, then create the GIF from the watermarked PNGs.
So it's the result of these two commands. First, create the watermarked PNGs:
for i in sample_images/000*.png; do
convert \
"${i}" \
sample_images/the_watermark.png \
-gravity south \
-composite \
sample_images/$(basename "${i}")_wm.png;
done
Note, I didn't use your exact composite command because it didn't create a readable watermark, only some blurring on the meant area...
Second, convert the watermarked PNGs to an animated GIF:
convert \
-resize 350x350 \
-fuzz 1.6% \
-delay 4 \
-loop 0 \
sample_images/*_wm.png \
-layers OptimizePlus \
-layers OptimizeTransparency \
animated_gif.gif
Is this what you meant to do?

Related

ffmpeg - Text fontcolor is changed (faded) because of alpha(I think). Is there any possibility to avoid this behavior?

I am using following command
ffmpeg -i ~/Desktop/input.mp4 -filter_complex "color=black:100x100[c];\
[c][0]scale2ref[ct][mv]; \
[ct]setsar=1,split=1[t1]; \
[t1]drawtext=text='Test Text 1':fontsize=36:fontcolor=#13348b\
,split[text1][alpha1]; \
[text1][alpha1]alphamerge,rotate=30:ow=rotw(30)\
:oh=roth(30):c=black#0[txta1]; \
[mv][txta1]overlay=x='min(0,-H*sin(30))+500':\
y='min(0,W*sin(30))+350':shortest=1" \
~/Desktop/result.mp4 -y
I think alpha is the problem, but I don't know how to avoid it.
Yes, you're using the text layer as alpha as well, and since the text isn't pure white, it won't be fully opaque. When I originally posted the command in your Q, the drawtext filter couldn't draw text on a transparent canvas and retain the transparency. That has since been rectified. So, the command is simpler now.
ffmpeg -i ~/Desktop/input.mp4 -filter_complex \
"color=black#0:100x100,format=yuva444p[c]; \
[c][0]scale2ref[ct][mv]; \
[ct]setsar=1,drawtext=text='Test Text 1':fontsize=36:fontcolor=#13348b, \
rotate=30:ow=rotw(30):oh=roth(30):c=black#0[txta1]; \
[mv][txta1]overlay=x='min(0,-H*sin(30))+500':\y='min(0,W*sin(30))+350':shortest=1" \
~/Desktop/result.mp4 -y

Eliminate slow speed factor in ffmpeg and image-magic commands

The basic idea of these commands is to create a compare, (A compare has defined a jpeg from past and one from the present, combine such as they will slide on each other and show before after images.)
e.g. https://media.evercam.io/v1/cameras/1lowe-scnoe/compares/lower-jreyh.gif
All the commands are written below, doing these operations
Resize before after image.
create a Gif using both images.
Add a log to Gif.
Create an MP4 file of from GIF.
Create a thumbnail from mp4 file.
the logo is:
we are making animation and mp4 files using FFmpeg and ImageMagick commands such as
ffmpeg -i before_image.jpg -s 1280x720 before_image_resize.jpg
ffmpeg -i after_image.jpg -s 1280x720 after_image_resize.jpg
The above commands are first to resize both images which are going to be used in animation.
This command is being used for creating a gif.
convert after_image_resize.jpg before_image_resize.jpg -write mpr:stack -delete 0--1 mpr:stack'[1]' \\( mpr:stack'[0]' -set delay 25 -crop 15x0 -reverse \\) mpr:stack'[0]' \\( mpr:stack'[1]' -set delay 27 -crop 15x0 \\) -set delay 2 -loop 0 temp.gif
This command to add a logo to the animation.
convert temp.gif -gravity SouthEast -geometry +15+15 null: evercam-logo.png -layers Composite compa-efxfphu.gif
Then to create an mp4 file as
ffmpeg -f gif -i compa-efxfphu.gif -pix_fmt yuv420p -c:v h264_nvenc -movflags +faststart -filter:v crop='floor(in_w/2)*2:floor(in_h/2)*2' compa-efxfphu.mp4
then to create a thumbnail from this mp4.
ffmpeg -i compa-efxfphu.mp4 -vframes 1 -vf scale=640:-1 -y thumb-compa-efxfphu.jpg
Is there any possibility to reduce any of these steps? This all takes a lot of time, I am merely interested in both convert commands, can we make them into one command?
Or do you see any chance to reduce these all 4 in one? any input will be so thankful.
Updated Answer
Here is my best shot at this, it runs in about 50% of the time of the original answer...
convert -depth 8 -gravity southeast -define jpeg:size=1280x720 \
logo.png -write MPR:logo +delete \
\( before.jpg -resize '1280x720!' MPR:logo -geometry +15+15 -composite -write MPR:before \) \
\( after.jpg -resize '1280x720!' MPR:logo -geometry +15+15 -composite -write MPR:after \) \
+append -quantize transparent -colors 250 -unique-colors +repage -write MPR:commonmap +delete \
MPR:after -map MPR:commonmap +repage -write MPR:after +delete \
MPR:before -map MPR:commonmap +repage -write MPR:before \
\( MPR:after -set delay 25 -crop 15x0 -reverse \) \
MPR:after \( MPR:before -set delay 27 -crop 15x0 \) \
-set delay 2 -loop 0 -write anim.gif \
-delete 1--1 -resize 640x thumb.jpg
Here's my thinking...
set the depth to 8 as we are using JPEG, set gravity and initialise libjpeg's "shrink-on-load" feature,
load the logo and save to MPR as we will be using it twice,
start some "aside processing" inside (...) to load the before image, resize it, paste on the logo and save to MPR for later use,
repeat previous step for the after image,
append the before and after images together and calculate a combined colormap suitable for both and save it,
map both before and after images to new, combined colormap,
delete all junk,
animate one way,
animate the other,
make animation endless, and save animation to GIF,
delete all except first frame, resize that and save as thumbnail.
Original Answer
Still a work in progress, but you can avoid the first two invocations of ffmpeg and do the resizing within ImageMagick, and also paste the logos on top in one go like this:
convert -gravity southeast logo.png -write MPR:logo \
\( before.jpg -resize '1280x720!' MPR:logo -geometry +15+15 -composite -write MPR:before \) \
\( after.jpg -resize '1280x720!' MPR:logo -geometry +15+15 -composite -write MPR:after \) \
-delete 0--1 \
MPR:before \( MPR:after -set delay 25 -crop 15x0 -reverse \) \
MPR:after \( MPR:before -set delay 27 -crop 15x0 \) \
-set delay 2 -loop 0 temp.gif
You can probably also create the thumbnail with that command too, if you change the last line from:
-set delay 2 -loop 0 temp.gif
to
-set delay 2 -loop 0 -write temp.gif \
-delete 1--1 -resize 640x thumbnail.jpg
You can also speed things up and reduce memory usage by using libjpeg's "shrink-on-load" feature. Basically, you tell it before reading the disk how big a file you need and it only reads a subset of the file thereby reducing I/O time and memory pressure:
convert -gravity southeast logo.png -write MPR:logo \
\( -define jpeg:size=1280x720 before.jpg -resize ... \
\( -define jpeg:size=1280x720 after.jpg -resize ...
That reduces the time by around 25-30% on my machine.
Here's my thinking...
set the gravity first as it is a setting and remains set till changed,
load the logo and save to an MPR because we will need to paste it twice and reading from disk twice is slow,
start some "aside processing" inside (...) to load the before image, resize it, paste on the logo and save to MPR for later use,
repeat previous step for the after image,
delete all junk,
animate one way,
animate the other,
make animation endless, and save animation to GIF,
delete all except first frame, resize that and save as thumbnail.
Keywords: animation, wiper effect, animated GIF

Create two sizes of an image using one ImageMagick command

I am using ImageMagick to generate small size JPEG versions of large TIFF images. For each TIFF image I must generate two smaller JPEG versions.
I am currently using two convert commands:
convert.exe 4096-by-3072px-120mb.tif -resize "1024x>" -strip -interlace Plane 1024px-wide-for-web.jpg
convert.exe 4096-by-3072px-120mb.tif -resize "1600x>" -strip -interlace Plane 1600px-wide-for-web.jpg
Converting TIFF to JPEG one-by-one is taking too much time. This approach is inefficient as each image is loaded across the network and processed twice. It will get worse as I plan to create more sizes for each TIFF (think 10,000 TIFFs x 5 sizes).
So, is it possible to generate two or more output files of different sizes using a single ImageMagick command?
Yes, it is possible, using the -write option:
convert 4096-by-3072px-120mb.tif -resize "1600x>" -strip -interlace Plane \
-write 1600px-wide-for-web.jpg -resize "1024x>" 1024px-wide-for-web.jpg
which rescales the input image to 1600 pixels wide, writes it out, then rescales the result to 1024 pixels wide and writes that. It's important to write the images in descending order of size, to avoid loss of quality due to scaling to a small size and then back up to a larger one.
If you prefer to rescale both images from the input image, use the +clone
option:
convert 4096-by-3072px-120mb.tif -strip -interlace Plane \
\( +clone -resize "1024x>" -write 1024px-wide-for-web.jpg +delete \) \
-resize "1600x>" 1600px-wide-for-web.jpg
In this case the order of writing images does not matter.
Here is an alternate command that uses memory program register:
magick.exe 4096-by-3072px-120mb.tif -write mpr:main +delete ^
mpr:main -resize "1024x>" -quality 80 -interlace Plane -strip -write 1024px-wide-for-web.jpg +delete ^
mpr:main -resize "1280x>" -quality 80 -interlace Plane -strip -write 1280px-wide-for-web.jpg +delete ^
mpr:main -resize "1600x>" -quality 80 -interlace Plane -strip -write 1600px-wide-for-web.jpg +delete ^
mpr:main -resize "2048x>" -quality 80 -interlace Plane -strip 2048px-wide-for-web.jpg
When tested:
the files generated with this command were identical to those created by separate convert commands
this command was twice as fast compared to separate commands
Note: ^ is the line continuation character on Windows.

Imagemagick - split image and pipe to convert?

I wish to split and image and then turn it into an animated gif with a single command.
At the moment, I'm doing
mogrify -resize 200%x100% -crop 50%x100% image.jpg
Then I can do
convert -delay 25x100 -loop 0 image-0.jpg image-1.jpg movie.gif
Is there a way that I can pipe the output of mogrify to the input of convert?
I tried running
convert -delay 25x100 -loop 0 <(mogrify -crop 50%x100% m.jpg :-) test.gif
But it failed with the error
mogrify: no decode delegate for this image format `/tmp/magick-bHWzk1Xl' # error/constitute.c/ReadImage/532.
convert: no decode delegate for this image format `/tmp/magick-mVXjCXLd' # error/constitute.c/ReadImage/532.
convert: missing an image filename `test.gif' # error/convert.c/ConvertImageCommand/3011
Close, but I think you're missing an extra '-'
Try :
mogrify -resize 200%x200% -crop 50%x100% -delay 10 input.jpg | convert - -delay 25x100 -loop 0 input-0.jpg input-1.jpg output.gif
This does throw an error, but works. It will also destroy the original, so you might want to use an output filename eg:
mogrify -resize 200%x200% -crop 50%x100% -delay 10 -write output.jpg input.jpg | convert - -delay 25x100 -loop 0 output-0-0.jpg output-0-1.jpg output.gif
This will also complain, but also works as you require.

ImageMagick: Is it possible to remove "Crop marks"?

I'm using ImageMagick to create a a thumb of a PDF.
/opt/local/bin/convert \
"$inputFile[0]" \
-geometry 157x200 \
-colorspace RGB \
"$ThumbFile"
But lastly we got PDF with "crop marks" (for bleeding).
Is there an option that I can use to don't take those?
How can I do this?
Example:
I would like to have only the content of the second image.
I ended by indicating to image magick to grab only the trim box:
/opt/local/bin/convert \
-geometry 157x200 \
-colorspace RGB \
-define pdf:use-trimbox=true \
"$inputFile[0]" \
"$ThumbFile"
The very simple to use -shave N parameter will remove N pixels depth from each edge of the image.
For example:
convert \
original.gif \
-shave 30 \
result.gif
This will shave of the 30 outmost rows/columns of pixels from each edge of the original image.
This also works for PDF input pages (and PNG output thumbnails, for example):
convert \
some.pdf[0] \
-scale 25% \
-shave 30 \
result.png

Resources