How to add a logo and notes using ImageMagick - command-line

I want to create a contact sheet (thumbnails of images) which needs to have a logo at the top left corner, a set of images and notes appended at the end.
I am trying to achieve this by first converting the notes text to a pdf using:
convert -background white -fill black -font arial.ttf -pointsize 36 -size 1024x128 caption:'This is sample text' textPdf.pdf
Then, creating a contact sheet (thumbnails of images with title and caption) by using montage function which returns a pdf with multiple (6) pages. And,
Finally merging the above two pdfs with the logo as below:
convert logo.jpg montage.pdf textPdf.pdf -background none -append contactsheet.pdf
This however, appends all the pages (6) into a single paged pdf which renders the contact sheet useless as on printing this thumnails become too tiny to be identified.
Is there any other way by which I can add a logo at the top of each of the pages of the montage.pdf and append the textPdf.pdf at the end of the last page of the pdf?
Any help in this would be much appreciated.

If I understand correctly, you have this:
logo.jpg (1 image of unknown dimensions)
montage.pdf (a 6-page PDF with some arbitrary page size)
textPdf.pdf (a 1-page PDF with a very weird page size).
You want to create an output PDF of 7 pages named contactsheet.pdf, where
...the 1st page consists of the logo.jpg with the vertically appended 1st page from montage.pdf
...the 2nd page consists of the logo.jpg with the vertically appended 2nd page from montage.pdf
...the 3rd page consists of the logo.jpg with the vertically appended 3rd page from montage.pdf
...the 4th page consists of the logo.jpg with the vertically appended 4th page from montage.pdf
...the 5th page consists of the logo.jpg with the vertically appended 5th page from montage.pdf
...the 6th page consists of the logo.jpg with the vertically appended 6th page from montage.pdf
...the 7th page consist of the one weird pagesized textPdf.pdf.
This result can be achieved with the following command:
convert \
\( logo.jpg tiled.pdf[0] -background none -append \) \
\( logo.jpg tiled.pdf[1] -background none -append \) \
\( logo.jpg tiled.pdf[2] -background none -append \) \
\( logo.jpg tiled.pdf[3] -background none -append \) \
\( logo.jpg tiled.pdf[4] -background none -append \) \
\( logo.jpg tiled.pdf[5] -background none -append \) \
textPdf.pdf \
contactsheet.pdf
It makes use of the following advanced ImageMagick commandline features:
bracketing sub-commands inside \( ... \) (which each require a space before and after!) to create partial picture results;
using the 0-based [N]-index to address a particular image/frame/page of a multi-page image or PDF file.

Related

How can I merge a signature and my module with an ImageMagick command?

I have this starting situation.
I have a jpg picture (A) with a module in which the signature slot is always in the same place.
I have also a signature (B) jpg picture, separated.
I use a program that allows external calls, but one single line only.
Is there an ImageMagick single command line command that allows me to do
Put Image (B) into image (A) at a specific x,y,height and width
Consider WHITE #FFFFFF as the alpha channel for image (B)
?
I am looking since a while now but haven't figured anything out.
Thanks
In ImageMagick, you would first make white transparent and then overlay B onto A. You need to use parentheses processing to keep the processes separate but in the same command line.
Unix syntax for ImageMagick 6:
convert imageA \( imageB -transparent white \) -geometry WxH+X+Y -compose over -composite result
or possibly
convert imageA \( imageB -transparent white -resize WxH \) -geometry +X+Y -compose over -composite result
Best if you provide your input images for demonstration.
See
https://legacy.imagemagick.org/Usage/basics/#parenthesis
https://legacy.imagemagick.org/Usage/compose/#compose
https://legacy.imagemagick.org/Usage/windows/

ImageMagick: composite 4 edges from one image into another, side-by-side

I'm using Perl 5.16 with ImageMagick 6.8 (probably old by now, but it works :). I'm trying to extract all 4 edge regions from one image and composite them into another image, side-by-side, oriented vertically.
I can extract edges and rotate them, but I can't get the offset in the target image right. The edges end up on top of each other. I tried x=>$marg, translate=>"$marg,0", geometry with an offset: no dice. Variables: $marg = the edge width, $im = source, $im2 = target, $ext = extracted region
# left edge
$ext=sprintf("%dx%d+%d+%d",$marg,$h,0,0);
$res=$im2->Composite(image=>$im,compose=>Over,extract=>$ext);
# top edge
$ext=sprintf("%dx%d+%d+%d",$w,$marg,0,0);
$geo=sprintf("%dx%d+%d+%d",$marg,$h,0,0);
$res=$im2->Composite(image=>$im,compose=>Over,extract=>$ext,rotate=>90,translate=>"$marg,0");
I haven't used the PerlMagick bindings for years, but I imagine you would want to create each of your 4 edge strips and then use +append to lay them out horizontally, side-by-side. Here's a crude example, just in Terminal:
magick -size 20x50 xc:red xc:lime xc:blue +append result.png
More specifically addressing your question, and starting with this image:
that would look like this:
#!/bin/bash
magick ~/sample/images/blocks-RGB.png -resize 100x100 +repage -write MPR:orig +delete \
\( MPR:orig -gravity northwest -crop 30x+0+0 \) \
\( MPR:orig -gravity northwest -crop x30+0+0 -rotate 90 \) \
\( MPR:orig -gravity southwest -crop x30+0+0 -rotate 90 \) \
\( MPR:orig -gravity northeast -crop 30x+0+0 \) \
+append result.png
Hopefully you can see the parallels with PerlMagick. The first line creates a copy of the image to work with, the second line crops the left edge, the third line crops the top edge, the fourth line crops the bottom edge, the fifth line crops the right edge and the last line appends the four cropped pieces side-by-side.

Imagemagick commands to resize, rotate, wrap, and combine images

I'm currently using Photoshop to resize, rotate randomly, and wrap images randomly to create this type of montage....
Comic Covers
I got to thinking that kind of thing should be doable in Imagemagick. I know how to use all of the commands separately, and I can do random rotations and wraps using BASH, but getting a single image out of individual images is eluding me.
Assume that the source pictures are different sizes but should be resized to 250px wide. The images will be named image1.jpg, image2.jpg, etc. Also assume that the destination should be 1000x1000px. Depending on how many pictures I have, the whole 1000x1000 image may not be covered - I understand this. I mainly use BASH, but I have several different environments and shells available to me.
Using ImageMagick 6 or 7, if you have enough memory to read in all your images at once you can resize them, randomly rotate them, and place them all in random locations on a 1000x1000 canvas with a command like this...
convert granite: -duplicate 11 -resize 250x \
-background none -gravity center -extent 1000x1000 \
-distort SRT "%[fx:rand()*45-22.5]" -virtual-pixel tile \
-distort affine "%[fx:w/2],%[fx:h/2] %[fx:rand()*w],%[fx:rand()*h]" \
-flatten result.png
That uses the ImageMagick built-in image "granite:" duplicated 11 more times. Replace "granite: -duplicate 11" with a list of your input files.
It starts by resizing them all to 250 pixels wide, then placing them each in the center of a 1000x1000 transparent canvas.
The real work is done in the distort operations. First "-distort SRT" rotates each image a random amount between -22.5 and +22.5 degrees. Then the "-distort affine" relocates each image to a random location within the canvas. Any part of an image going beyond the canvas will be rolled back into the opposite side. That makes the result suitable for tiling.
This command flattens everything onto a transparent background wherever it might show between the images. Add "-background blue" just before the "-flatten" operation to change the background to blue, for example.
This works on my IM 6 in bash. For IM 6 in Windows change the continued line backslashes "\" to carets "^". For IM version 7 change "convert" to "magick".
Here is a bash Imagemagick 6 script that takes a list of images. You can replace it with your images. It uses subshell processing to avoid needing to write temporary images to disk. It saves the images in a miff: format as one file from the loop. Then it pipes the multipage miff: file to -layers merge, which overlays the images onto the 1000x1000 transparent base image. For Imagemagick 7, replace convert with magick.
list="lena.jpg barn.jpg mandril3.jpg zelda1.jpg"
convert -size 1000x1000 xc:none result.png
(
for img in $list; do
angle=`convert xc: -format "%[fx:round(-22.5+45*(rand()))]" info:`
xoff=`convert xc: -format "%[fx:round(1000*rand())]" info:`
yoff=`convert xc: -format "%[fx:round(1000*rand())]" info:`
#echo >&2 "angle=$angle; xoff=$xoff; yoff=$yoff"
convert "$img" -resize 250x -background none -rotate $angle -set page +${xoff}+${yoff} miff:-
done
) | convert result.png - -layers merge +repage result.png
If you have enough resources to hold all the images at once, then you can also do it in one command line as follows:
convert -size 1000x1000 xc:none \
\( lena.jpg barn.jpg mandril3.jpg zelda1.jpg -virtual-pixel none -background none \
+distort SRT "0,0 %[fx:250/w] %[fx:-22.5+45*rand()] %[fx:rand()*1000],%[fx:rand()*1000]" \) \
-layers merge +repage result.png
Cool, I'll try fmw42's script, but this is a script I came up with. It generates temporary files (which it deletes) and several convert commands, but it does work....
# Create blank montage...
convert -size 750x750 xc:black montage.jpg
for file in $(ls hall*.jpg | grep -v halloweencovers.jpg); do
echo $file
angle=$RANDOM; let "angle %= 32"; let "angle = angle - 16"; let "angle = angle * 5"
offsetx=$RANDOM; let "offsetx %= 75";let "offsetx = offsetx * 10"; offsetx="+$offsetx"
offsety=$RANDOM; let "offsety %= 75";let "offsety = offsety * 10"; offsety="+$offsety"
# Create blank image...
convert -size 750x750 xc:transparent blank.png
# create 250px image and rotate....
convert $file -resize 250x -alpha set -background none -rotate $angle out.png
# add 250px image to blank 750x750 canvas
convert blank.png out.png -composite output.png
# offset and wrap blank canvas with output image
convert output.png -roll ${offsetx}${offsety} output2.png
# merge montage with offset image
convert montage.jpg output2.png -composite montage.jpg
# clean up
rm -f out.png output.png output2.png blank.png
done

Imagemagick command line, combine two different sized images

I'd like to use "convert" (or whatever) from Imagemagick to combine two different sized images. I'd like them to be aligned at the bottom left corners. For example, I have two images:
trans_alpha.png (a transparent 42x37 blank image)
and shadow.png (a 68x23 image, which I want overlaid on trans_alpha.png aligned at the bottom left)
The result I'd like would be a 68x37 image, NOTE these sizes are examples only, I don't want to put the size into the command line, I just want to use the sizes from the input images.
I have tried a lot of combinations without success:
Attempt no. 776 (close, but aligned to top left, not bottom left)..:
convert trans_alpha.png -background none shadow.png -gravity SouthWest -layers merge +repage result.png
Attempt no. 841 (aligned correctly, but result image isn't wide enough)...
convert trans_alpha.png shadow.png -gravity SouthWest -composite result.png
Hopefully that makes sense.
Thanks,
Paul
In answer to my own question (courtesy of the clever people on www.imagemagick.org)
convert \
trans_alpha.png shadow.png \
-flip \
-background none \
-mosaic \
-flip \
result.png
Imagemagick includes many useful transformations, but occasionally still it lacks the one you need. Since your original images are PNG lossless bitmaps, you can convert both to long-form PBM or a related format like long-form PPM. The advantage of these forms is that they represent the entire image, pixel by pixel, in plain text, which one can write a program -- usually a fairly short program -- to process any way one likes. As storage formats, PBM and PPM are egregiously inefficient, but they are likewise egregiously easy to manipulate, and that's what you want.
The pbm(5) manpage (available for example on Debian/Ubuntu systems in the netpbm package) is well written and explains the process clearly.
I am unable to test at the moment but you can use -page with layers so something like this might work but you may need to calculate the Y offset:
convert \
trans_alpha.png \
-background none \
shadow.png \
-page +0+10 \
-layers merge \
+repage \
result.png
You may not need the -background none

How to have multiple favicon sizes, yet serve only a 16x16 by default?

Generally it is considered good practice to serve favicon.ico in multiple sizes, because that way it looks better when a shortcut is made or the site is pinned (IE9). The size of a favicon easily increases tenfold by doing so though, which results in slower site loading (in my case the 16x16 favicon is 1kb, the 16, 32, 64=30kb).
Sites like Facebook and Yahoo serve a 16x16 favicon by default that is <1kb, but when you pin these sites, the image used is proper size. I assume the larger picture is loaded only when needed, which fixes the dilemma. I have unsuccessfully been trying to figure out how these sites do this. Does anybody know this?
Update:
My original answer is below, however, since writing this post I believe there may be a better way to handle Favicons with HTML 5. I would create a 32x32 favicon (only that size) for Internet Explorer 9 and below but use other methods for creating higher resolution favicons (PNG file type) for other browsers including mobile devices. You can see my answer here for additional information.
Original Answer to Question:
Here is how it can be done:
Download png2ico. Extract to c:\
Create your Icons in your favorite program. Create a 64x64, 32x32, 16x16. (Note: 64x64 is probably not needed and will increase file size. However, use at least 32x32 and 16x16) Save as icon-64.png (for 64x64 size) icon-32.png (32x32) and icon-16.png (16x16) in the same folder as png2ico. Keep the colors to a minimum.
Open Command Prompt - Change directories to the png2ico folder. (cd \png2ico)
Once in the right directory run this command:
png2ico.exe favicon.ico --colors 16 icon-64.png icon-32.png icon-16.png
Note: The difference in file size for the addition of a 64x64 size icon increased the file by 2kb. I would just use 32x32 and 16x16. (Run same code as above removing icon-64.png)
Grab the favicon.ico file from the png2ico folder. Upload it to the server add <link rel="shortcut icon" href="http://example.com/favicon.ico" /> to the header and you are good to go.
While you are at it go ahead and create Icons for iPad and iPhone. You can find more info on recommended sizes here and how to implement them into your site.
Also more general info on Favicons can be found here.
Note: I do not know if this is how Facebook or Yahoo do theirs but this answers your question of how it can be done.
The Facebook "favicon.ico" contains two sizes: 16x16 and 32x32. I'm sure you know how to combine two ico images into one, however, the "trick" is they're using two extremely optimized images.
I've found that Photoshop creates bloated PNG files, and bloated ICO files. (Note: Photoshop requires a plugin to create ICO files.)
The best way I've found to create tiny, optimized ICO files is to use a well-known free image editor called "Gimp". In short, just follow this tutorial for creating ICO files:
https://www.catalyst.net.nz/news/creating-multi-resolution-favicon-including-transparency-gimp
Important Tip: When you get to the step for saving your .ico image and you can specify the bits-per-pixel (bpp), change it to 4bpp or something similiar (you'll have to experiment to see how low you can go without degrading the image quality).
Using the instructions above, I was able to create a 1kb favicon that contains 16x16 and 32x32 images. In comparison, the smallest I could get the same favicon using Photoshop, plugins, and various other tools was 5kb.
Or you could just log into any linux box with ImageMagick installed, rename your source image (with a resolution of at least 256x256 pixels and a PNG format file) to 'favicon.png', and run the following command:
convert favicon.png -bordercolor white -border 0 \
\( -clone 0 -resize 16x16 \) \
\( -clone 0 -resize 32x32 \) \
\( -clone 0 -resize 48x48 \) \
\( -clone 0 -resize 57x57 \) \
\( -clone 0 -resize 64x64 \) \
\( -clone 0 -resize 72x72 \) \
\( -clone 0 -resize 110x110 \) \
\( -clone 0 -resize 114x114 \) \
\( -clone 0 -resize 120x120 \) \
\( -clone 0 -resize 128x128 \) \
\( -clone 0 -resize 144x144 \) \
\( -clone 0 -resize 152x152 \) \
\( -clone 0 -resize 180x180 \) \
\( -clone 0 -resize 228x228 \) \
-delete 0 -alpha off -colors 256 favicon.ico
And you'll have your favicon.ico with most well-known formats baked right into one file.
Also, be sure to checkout the favicon cheat sheet # https://github.com/audreyr/favicon-cheat-sheet for more favicon information.
Windows batch file, which creates multiple sized .PNGs and merge them to one .ICO file:
#echo off
set inkScape="C:\SOFTWARE\GRAPHIC\INKSCAPE\inkscape.exe"
set imageMagick="C:\SOFTWARE\DEVELOPER\IMAGEMAGICK\magick.exe"
set fileName=favicon
set importType=svg
set exportType=png
set exportDpi=300
set imageSizes=(16 24 32 48 57 60 64 70 72 76 96 114 120 128 144 150 152 180 192 196 256 300 320 400 450 460 480 512 600)
for %%s in %imageSizes% do (
%inkScape% -z -f %~dp0%fileName%.%importType% -w %%s -h %%s -e %~dp0%fileName%-%%sx%%s.%exportType% -d %exportDpi%
echo CREATED: %fileName%-%%sx%%s.%exportType%
set e=%fileName%-%%sx%%s.%exportType%
call :concat (e)
)
%imageMagick% %exportFileNames%"%~dp0%fileName%.ico"
echo MERGED IN: %fileName%.ico
pause goto :eof
:concat (e) (
set exportFileNames=%exportFileNames%"%~dp0%e%"
)
If you don't need the .PNG files, you can delete (or remove) them by del FILE or you save all PNGs inside a directory you can remove (after %imageMagick% %exportFileNames%"%~dp0%fileName%.ico").
Hope it helps somebody. :)
If you like scripts, I wrote one to convert any image to a multi-resolution favicon using ImageMagick.
http://blog.lavoie.sl/2012/11/multi-resolution-favicon-using-imagemagick.html
For your question about why Facebook and Yahoo are able to have high-res "pinned" images, it is because they also have apple-touch-icon and og:image.