Cloud functions Circle Image Imagemagick - firebase

I would like to convert uploaded pictures to Firebase Storage into circled images using Cloud functions and resize them.
Having a look at the documentation of ImageMagick I am wondering about the syntax to use for this task. Using the below to resize the image which works like a charm. But how would I add the commands into this and which ones to use best?
return spawn('convert', [tmpFilePath, '-resize', '250x250', tmpFilePath]);

I don't know what a 'circle image' means, but perhaps applying Vignette effect?
convert -size 250x250 plasma: -background white -vignette 0x0 output.png
So your command may be...
return spawn('convert', [
tmpFilePath,
'-resize', '250x250',
'-background', 'white',
'-vignette', '0x0',
tmpFilePath
]);

emcconville probably has the simplest method. You may just need to make the background transparent and replace the plasma image with a real image.
If you want the outside to be transparent, be sure to save your output to PNG or TIFF and not JPG. JPG does not support transparency.
Input:
convert lena.jpg -background none -vignette 0x0 output.png
However, the circle's perimeter will not extend to the edges of the image.
To make it do that, you have to change the arguments as follows:
convert lena.jpg -background none -vignette 0x0+0+0 output2.png
But here is another method that is a bit longer and more complex (assuming you have a square image).
If by "circled images" you mean make the outside of a circle the size of the image transparent, you can do that in ImageMagick command line as follows:
1) Read the image (and somehow get its size)
2) Then create a new image the same size and fill with black and draw a white circle supplying the center point and any point on the perimeter
3) Put the circle image into the alpha channel of the original
Original:
Unix Syntax. (For Windows remove the \s in the following)
convert lena.jpg \( -size 256x256 xc:black -fill white -draw "circle 128,128 128,255" \) -alpha off -compose copy_opacity -composite result.png
In Unix syntax one can get the dimensions of the input image as follows:
WxH=`convert -ping lena.jpg -format "%wx%h" info:`
ww=`echo $WxH | cut -dx -f1`
hh=`echo $WxH | cut -dx -f2`
ww2=`convert xc: -format "%[fx:$ww/2]" info:`
hh2=`convert xc: -format "%[fx:$hh/2]" info:`
hhm1=$((hh-1))
convert lena.jpg \( -size ${ww}x${hh} xc:black -fill white -draw "circle $ww2,$hh2 $ww2,$hhm1" \) -alpha off -compose copy_opacity -composite result2.png
If you do not have a square image, then you must use the minimum dimension of the input image as the circle diameter. This also works for a square image.
Input:
dim=`convert -ping monet2.jpg -format "%[fx:min(w,h)]" info:`
dim2=`convert xc: -format "%[fx:$dim/2]" info:`
dimm1=$((dim-1))
convert monet2.jpg \( -size ${dim}x${dim} xc:black -fill white -draw "circle $dim2,$dim2 $dim2,$dimm1" \) -alpha off -gravity center -compose copy_opacity -composite result4.png
If we use the vignette method on a non-square image, then you will get an elliptical region.
convert monet2.jpg -background none -vignette 0x0+0+0 output3.png

Related

Composing a new graphic in R with magick from multiple existing images

I've created a table with the excellent gt package. Since it was a long table, my code creates the table in two halves. I save both halves to disk as png files then use the magick package's image_append() to composite them side-by-side as a new png file. All good.
Now, with magick, I'd like to compose a final graphic with a logo, some title text and source notes using image_annotate(), and my saved table, all laid out nicely.
I'm stuck trying to understand the right way to do that. I have all the graphical pieces, but I don't know how to create new, blank graphic with magick and then lay those pieces out in the locations I want them so that the finished product looks like this:
There are a lot of ways to create text images in Imagemagick. But here is likely the easiest for you to use and convert to R. The following is command line Imagemagick.
Logo:
Table Text Image:
Steps: (In subsequent command)
- Line 1: load imagemagick convert
- Line 2: create 500x500 white background image
- Line 3: insert the logo image at +20+20 relative to top left
- Line 4: add title text via -annotate
- Line 5: add sub-title text via -annotate
- Line 6: insert the preformed table image below those
- Line 7: add the source notes text via -annotate
- Line 8: save the resulting png file to disk
Command:
convert \
-size 500x500 xc:white \
rainbow_logo.png -gravity northwest -geometry +20+20 -compose over -composite \
-font arial -fill black -pointsize 48 -annotate +125+15 "TITLE TEXT" \
-font arial -fill black -pointsize 32 -annotate +125+65 "SUB-TITLE TEXT" \
lorem.png -gravity northwest -geometry +20+140 -compose over -composite \
-font arial -fill black -pointsize 18 -annotate +20+455 "SOURCE NOTES" \
result2.png
Result:

gm identify syntax get image width and height

I am trying to get the height and width of a jpeg image in the commandline.
I typed
gm identify img300.jpg
and get a long line that outputs JPEG 3264x2448+0+0 DirectClass 8-bit 1.8Mi 0.000u 0m:0.000002s
I looked in the manual for the gm command and it says I can get just the image dimensions with the -density option.
http://www.graphicsmagick.org/identify.html#ident-opti
So I tried
gm identify -density img300.jpg
[Option requires an arguement]
gm identify img300.jpg -density
[no such file or directory]
debian 9, latest graphicsmagick package is the environment.
You can get the width like this:
gm identify -format %w image.png
256
And the height like this:
gm identify -format %h image.png
80
If you want height in a variable:
h=$(gm identify -format %h image.png)
If you want both in variables in one go:
read w h < <(gm identify -format "%w %h" image.png )
echo $w, $h

Batch blur images using multiple cores

I'm trying to blur the bottom section of thousands (>50,000) of images using imagemagick. Image resolution is 800x600. The command line code (below) works, but takes a long time. Is there any way that this can be run in parallel, and hopefully called from within R using system()?
I got this code off the internet, so I'm not sure if it's the best way to even achieve this objective? Any help would be greatly appreciated. Thanks in advance!
(OS = OSX El Capitan)
cd /Users/Desktop/test_images
list=$(ls *.jpg)
for img in $list; do
convert $img \
\( -size 800x525 xc:black -size 800x75 xc:white -append \) \
-compose blur -define compose:args=6 -composite \
cd /Users/Desktop/test_images/results/$img
done
cd
I think this command does something very similar to what you are doing but is FAR quicker. See if you like the effect:
convert start.jpg \( +clone -crop +0+525 -blur x4 \) -gravity south -composite result.jpg
If that works, you can use GNU Parallel just as before:
parallel 'convert {} \( +clone -crop +0+525 -blur x4 \) -gravity south -composite results/{}' ::: *.jpg
You can also put that lot in a script called BlurTitle like this:
#!/bin/bash
parallel 'convert {} \( +clone -crop +0+525 -blur x4 \) -gravity south -composite results/{}' ::: *.jpg
and then make it executable with:
chmod +x BlurTitle
and call it from R with:
system("./BlurTitle")
or from the Terminal with:
./BlurTitle
If you get "Argument list too long", you can express it the other way around like this by sending the arguments on stdin rather than after the command:
cd /path/to/images
find . -name \*.jpg -print0 | parallel -0 'convert {} \( +clone -crop +0+525 -blur x4 \) -gravity south -composite results/{}'

How to colorize a black-transparent PNG icon with ImageMagick

How do I a colorize a black PNG image that has a transparent background using ImageMagick?
Use case:
You have several PNG images like this:
And I want to colorize them like this:
I want to use ImageMagick's convert command, allowing for scripting to process hundreds of icons at a time.
You can use one of the following commands:
$ convert input.png +level-colors "red", output.png
$ convert input.png +level-colors "rgb(255,0,0)", output.png
$ convert input.png +level-colors "#ff0000", output.png
Note that the , character is important here. On the left side of the , character we tell convert which color should replace black and on right side what color should replace white. Therefore nothing should be given after the , character.
Source
... how do I colorize black & transparent PNG images [...] to colorize them like this [...] using ImageMagick
The -fill <COLOR> option works fantastic for this purpose. You can replace "#1bbfc9" with a human-readable name (e.g. "red") or an HTML color code.
convert target-black.png -fill "#1bbfc9" -colorize 100 target-blue.png
... allowing to script and process hundreds of icons at a time
Using the find command, you can recurse hundreds.
Warning: This will replace the originals.
find path/to/files -iname '*.png' -exec convert "{}" -fill "#1bbfc9" -colorize 100 "{}" \;
With ImageMagick, you can process a whole folder of images at one time with mogrify rather than convert if you want all the same color. Create a new output directory to hold the colorized files. Then cd to the folder holding your images.
cd path_to/image_folder
mogrify -format png -path path_to/new_folder -fill "cyan" -colorize 100 *.png
Where replace path_to with your actual path.
You may use color names, hex colors or rgb(...) colors in the fill command, but enclose them in quotes on Linux/Mac OSX. Quotes are not needed for Windows, but should not cause any issues if double quotes.
See mogrify

graphicsmagick - tips for optimizing montage and composite?

for a little photo booth application have this problem:
I have 4 pictures, which i would like to tile together, using montage. The result get a 150px border using a transparent PNG and composite. But because the "frame" is larger than the base image, I have to add an additional convert to add artificial 150px border around the tiled image.
This is functional but very slow and seems not very elegant:
gm montage -geometry +20+20 -tile 2x2 /home/pi/dev/*.jpg miff:- | gm convert -border 150x150 miff:- miff:- | gm composite /home/pi/dev/rahmen.png miff:- /home/pi/dev/partyknipse.JPG
Is there any way I could optimize this and speed up the process? Get rid of the convert?
I guess the -geometry parameter of the composite could be useful, but didn't fully understand it so far.
This is roughly what it should look like in the end:
red border is a png, the four grey boxes are the tiled image
Not sure how long your operations take, or what you expect, but here are a couple of ideas...
Assume I have im1.jpg through m4.jpg which are the 4 small images and a larger red frame that is a "hollow" PNG with a transparent hole in the middle.
Firstly, if you were to switch to ImageMagick (rather than GraphicsMagick) you could do it all in one go with:
convert frame.png -background white -flatten \
im1.jpg -geometry +80+80 -composite \
im2.jpg -geometry +260+80 -composite \
im3.jpg -geometry +80+200 -composite \
im4.jpg -geometry +260+200 -composite result.png
Second, you could try something like this batching GraphicsMagick and storing intermediate steps in memory (MPR = Magick Program Register) which is effectively a named lump of RAM:
{ echo convert frame.png -background white -flatten mpr:frame;
echo montage -geometry +20+20 -tile 2x2 im*.jpg mpr:images;
echo composite mpr:images -geometry +100+40 mpr:frame result.png; } | gm batch -prompt off

Resources