Translate a ImageMagick convert shell script to Python/PIL script - image

I'm trying to translate some shell scripts using the convert cmd to python script using PIL.
Here's the original shell script:
convert \
-resize 25% \
+repage \
-background white
-quality 95 \
-flatten \
-gravity center \
-extent 200x200 \
img_a.png img_b.jpg
Here's what I've being able to translate so far:
# Paths
img_a_png_filepath = '/foo/bar/img_a.png'
img_a_name = Path(img_a_png_filepath).stem
img_b_name = f'{img_a_name}.jpg'
img_b_jpg_filepath = f'/foo/bar/{img_b_name}'
# Converting to JPEG
img_a_png = Image.open(img_a_png_filepath)
# -background white
white_bg = Image.new('RGBA',img_a_png.size ,(255, 255, 255, 255))
white_bg.paste(img_a_png, (0, 0), img_a_png)
white_bg = white_bg.convert('RGB')
white_bg.save(img_b_name, 'JPEG')
# -resize 25%
img_b_jpg = Image.open(img_b_jpg_filepath)
img_b_jpg = img_b_jpg.resize((img_b_jpg.size[0]*0.25, img_b_jpg.size[0]*0.25))
img_b_jpg.save(img_b_name, 'JPEG')
I guess the original script is trying to crop from the center with the -gravity center and extent 200x200 but I have no clue how to translate both of those options to PIL.

You're nearly there! You've got the white background, the -flatten (using paste) and the resizing.
You just need to do the -extent from the centre, so...
get the width, and halve it int(im.width/2) and subtract 100 to use as the left edge and add 100 to use as the right edge
get the height and do the same to get top and bottom
crop.
If smaller than 200x200 paste onto a 200x200 canvas.
By the way, there's no need to save the images repeatedly as you are currently doing - just carry on processing what you've got.

Related

Using rmagick to colorize an image like in photoshop

So I have this base image:
And in photoshop I do a basic layer color overlay, with the rgb colors:
r: 244, g: 93, b: 0
This gives me the amazingly vibrant:
What I'm trying to do is colorize the same image in rmagick, so if I do the following colorize:
img = Magick::Image.read('brush.png').first
img = img.colorize(100, 100, 100, Magick::Pixel.new(244, 93, 0, 1))
img.format = 'png'
img.to_blob
It gives me this really washed out orange image:
My questions is, how do I colorize this image with those rgb params in imagemagick / rmagick, to get the same vibrant color that I got in photoshop.
Thanks.
At the commandline, I think you want something like this:
convert brush.png \( +clone -fill "rgb(244,93,0)" -colorize 100% \) -compose colorize -composite out.png
So, with the +clone I am creating another layer the same size as your image and entirely filling it 100% with your orange colour and then composing it over your image with the -composite to blend the opacity and colour.
I really don't speak Ruby, but I think it will be along these lines:
#!/usr/bin/ruby
require 'RMagick'
include Magick
infile=ARGV[0]
img=Magick::Image.read(infile).first
w=img.columns
h=img.rows
ovl=Image.new(w,h){self.background_color=Magick::Pixel.new(244*256,93*256,0)}
img.composite!(ovl,0,0,Magick::ColorizeCompositeOp)
img.write('result.png')
Mark Setchell's command line works for me (Windows), with slight modifications...
convert greyscale.png +clone -fill "rgb(244,93,0)" -colorize 100% -compose colorize -composite colour.png
Found this link on recolouring with rmagick...
ftp://belagro.com/Redmine/ruby/lib/ruby/gems/1.8/gems/rmagick-2.12.0/doc/colorize.rb.html
Based on the code in the above link, with the greyscale conversion removed, does the example below work (I don't have ruby)?
# load the greyscale image
img = Magick::Image.read('greyscale.png').first
# Colorize with a 100% blend of the orange color
colorized = img.colorize(1, 1, 1, '#A50026')
# save the colour image
colorized.write('colour.png')
Used a colour picker to get the hex of your orange colour - rgb(244,93,0) = #A50026

A script that finds a matching color to the photo

I'm a graphic designer and often I make websites. I am looking for a script (may ultimately be even software) that finds ONE matching color to the photo. A very good illustration of this is that page: https://unsplash.com/grid If refered your mouse on the picture it shows a matching color. This is a screenshoot that I show this issue: https://dl.dropboxusercontent.com/u/65947165/qu1.png
I would use ImageMagick and find the average colour by resizing the image to 1 pixel x 1 pixel and converting that pixel to text, like this:
convert photo-1414637104192-f9ab9a0ee249.jpg -resize 1x1! -colorspace RGB txt:
# ImageMagick pixel enumeration: 1,1,255,rgb
0,0: (0,21,3) #001503 rgb(0,21,3)
So rgb(0,21,3) is the green leaf with the drop of water from your example. You can have it as sRGB like this:
convert photo-1418479631014-8cbf89db3431.jpg -resize 1x1! txt:
# ImageMagick pixel enumeration: 1,1,255,srgb
0,0: (141,109,91) #8D6D5B srgb(141,109,91)
If you want it as an image, you would do this:
convert photo-1414637104192-f9ab9a0ee249.jpg -resize 1x1! -scale 1000 output.jpg
This is the first image from your example page...
I don't really speak PHP, but this should be close:
<?php
$image = new Imagick('input.jpg');
$image->resizeImage(1,1,Imagick::FILTER_BOX,1);
$pixel = $image->getImagePixelColor(0,0);
print $pixel->getColorAsString();
$colors = $pixel->getColor();
print_r($colors);
?>
Output
srgb(55.259%,42.2065%,34.9279%)Array
(
[r] => 141
[g] => 108
[b] => 89
[a] => 1
)

Shift hue on existing image(s) via imagemagick -modulate from Photoshop Hue/Saturation values

I am trying to shift the hue of this image (and others like it) with varying gradients, etc from the "blue" to another color as defined by my designer from the mockups done in Photoshop.
I've attached 2 Hue/Saturation screens from Photoshop with HSL values for purple and orange but using -modulate in Imagemagick via this ruby code:
# burnt orange - works
hue = 25.0 # must be a decimal
sat = 100
bri = 0
# purple - does not work
#hue = 266.0 # must be a decimal
#sat = 100
#bri = 0
# formula from -modulate http://www.imagemagick.org/Usage/color_mods/#modulate
h = ( hue * 100/180 ) + 100
system("convert -define modulate:colorspace=HSB home_tab_back_right.png -modulate #{h},#{sat},#{bri} #{h}-#{sat}-#{bri}-home_tab_back_right.png")
This will work for the burnt orange image, but not for purple and other colors I've been given.
I have had more success by passing "modulate:colorspace=HSB" than without, but still not able to consistently plugin values received from Photoshop and have it take the base blue image and shift the hue.
Can this be done?
I noticed a bug in the above code. The ImageMagick "-modulate" option actually expects the numbers in the order of: $brightness, $saturation, $hue.
I needed to turn "original.png" images in subfolders from the original Blue color, to Red and Green versions.
This is what I used for Red:
for dir in *; do convert -define modulate:colorspace=HSB $dir/original.png -modulate 100,100,180 $dir/original_red.png; done;
This is what I used for Green:
for dir in *; do convert -define modulate:colorspace=HSB $dir/original.png -modulate 100,100,270 $dir/original_green.png; done;
Note that in above, I kept the Brightness and Saturation the same as original (100) and tuned the Hue (180 for Blue > Red, and 270 for Green > Red).
Hope this is helpful!

Write a string with caption method using MiniMagick

I'm trying to write a string over a image. Currently I'm using MiniMagick and I can resize and overlap two images, but when I try write a multiline string using caption nothing happens to final image, it's still same as before.
Here is my current code:
image = MiniMagick::Image.open('template.jpg')
image.combine_options do |c|
c.background '#0008'
c.fill '#666'
c.gravity 'center'
c.size '100x50'
c.caption "Lets write some big string here... zzzzz I hope this work =)"
end
image.write('final.jpg')
My refs:
http://www.imagemagick.org/Usage/annotating/
ImageMagick multiline text and background image
http://www.imagemagick.org/www/command-line-options.html#caption
Thanks all
I ended using a system call to get rid this problem, here is the code:
Subexec.run "convert -background '#fff0' \\
-fill '#003300' \\
-gravity west \\
-size 560x180 \\
-pointsize 19 \\
-font \'#{font_path}\' \\
caption:\"#{caption}\" \\
#{photo_path} \\
+swap \\
-gravity NorthWest \\
-geometry +333+113 \\
-composite #{photo_path}"
You need to use Convert with MiniMagick. And caption is great because it will wrap and adjust according to the size, as long as you don't put in pointsize. The syntax is a little tricky though because there aren't many Rails examples out there.
file = Paperclip::Tempfile.new(["processed", ".jpg"])
MiniMagick::Tool::Convert.new do |img|
img.background '#0008'
img.fill '#666'
img.gravity 'center'
img.size '100x50'
img << "caption: Lets write some big string here... zzzzz I hope this work =)"
img << file.path
end
model.picture = file
model.save
file.unlink
Note: You have to add file path last

Cut circle out of image with RMagick

I want to cut a circle out of an image using rmagick.
Here's an example of what I'd like to be able to accomplish:
-->
It seems like I want to use http://studio.imagemagick.org/RMagick/doc/draw.html#circle to cut a circle, and then clip_path to mask it, but the docs aren't very clear. Would anyone be able to point me in the right direction?
require 'rmagick'
im = Magick::Image.read('walter.jpg').first
circle = Magick::Image.new 200, 200
gc = Magick::Draw.new
gc.fill 'black'
gc.circle 100, 100, 100, 1
gc.draw circle
mask = circle.blur_image(0,1).negate
mask.matte = false
im.matte = true
im.composite!(mask, Magick::CenterGravity, Magick::CopyOpacityCompositeOp)
im.write 'walter_circle.png'
This is how I would do it with Imagemagick and php:
// Canvas the same size as the final image
exec("convert -size 800x533 xc:white white.jpg");
// The mask
exec("convert -size 800x533 xc:none -draw \"fill black circle 400,265 400,50\" write_mask.png");
// Cut the whole out of the canvas
exec("composite -compose Dst_Out write_mask.png white.jpg -matte step.png");
// Put the canvas over the image and trim off excess white background
exec("convert IMG_5745.jpg step.png -composite -trim final.jpg");
You should be able to follow the process?
Cleanup tempory images afterwards - I tend to save the tempory images in a .miff format and then write a loop to delete all .miff images afterwards. Alternativly just leave them and if you use the same name for the tempory images they will be overwritten every time the code is run.

Resources