Can't get gravity to work with RMagick and 'caption' - ruby

I'm using RMagick 2.12.2 with ImageMagick 6.5.6-10 on Snow Leopard. I'm trying to put captions on a collection of photos, and I'm getting the caption to work (i.e. it appears on the image), but I can't get the gravity parameter to work correctly.
No matter what I set it to, I end up with some variation on NorthGravity.
For instance: Setting it to SouthWestGravity gives me NorthWestGravity. Setting it to SouthEastGravity gives me NorthEastGravity. Setting it to CenterGravity gives me NorthGravity.
In other words, I can't get the caption to come down off the top of the image.
I'd consider using "annotate," but I need "caption" so the lengthy caption text for each image will wrap.
What am I doing wrong?
Here's the code:
#!/usr/bin/env ruby
require "rubygems"
require "yaml"
require "RMagick"
include Magick
base_dir = "/Users/mike/Desktop/caption_test"
photo_log = File.open("#{base_dir}/photo_log.yaml" )
YAML::load_documents(photo_log) do |doc|
caption = doc["photo-caption"]
filename = doc["file"]
canvas = ImageList.new.from_blob(open("#{base_dir}/#{filename}") { |f| f.read } )
canvas << Magick::Image.read("caption:#{caption}") {
self.gravity = SouthWestGravity
self.size = "#{canvas.first.columns}"
self.font = "Helvetica Neue"
self.pointsize = 12
self.background_color = "#fff"
}.first
canvas.flatten_images.write("#{base_dir}/images/#{filename}")
end

You've probably long since moved on, but the I found a pretty simple answer to this--use
canvas.append(true).write("#{base_dir}/images/#{filename}")
In other words, you want the append option (use 'true' to stack vertically).

I think your problem is that you're applying the gravity to the dimensions of the caption image rather than the dimensions of the underlying image. Your caption will East/West align itself within its width but because it makes it own height, North/South always just mean North.
You probably want to specify the gravity on the flatten_images call instead which looks possible...

Related

MiniMagick Resize Image

I'm trying to use MiniMagick to resize 2 images and overlay one on top of the other. Heres the code I am using
require "mini_magick"
first_image = MiniMagick::Image.new("spider.jpg")
first_image = first_image.resize("250x250")
second_image = MiniMagick::Image.new("q.png")
second_image = second_image.resize("250x250")
result = first_image.composite(second_image) do |c|
c.compose "Over" # OverCompositeOp
c.gravity "center"
# c.resize("250x250")
end
result.write "output.jpg"
This overlays the images but neither is resized and the overlay image ends up awkwardly cropped. Ive tried making both the same size, making the bigger overlay image smaller and the smaller image bigger, but none seem to work. Any advice would be highly appreciated.

RMagick transparency not working when compositing one image over another

In the following code I'm trying to overlay a transparent square over the image of some mountains. I thought it would work, but by setting background_color = 'none' it doesn't make the image transparent!
The result is a black square over the top left corner - desired result is the black square should be transparent.
require 'open-uri'
require 'RMagick'
image_url = 'http://farm9.staticflickr.com/8446/7937080514_62d7749860.jpg'
bg = Magick::ImageList.new
open(image_url, 'rb') do |f|
bg.from_blob(f.read)
end
layer = Magick::Image.new(200, 200) {
self.background_color = 'none'
}
bg.each do |frame|
frame.composite!(layer, 0, 0, Magick::OverCompositeOp)
frame.strip!
end
bg.write('out.jpg')
Here's my output image:
Edit: I'm on Mac, Lion, ruby 1.9.3p125, ImageMagick 6.7.5-7
Edit 2: This works fine on Heroku! But not on my machine. Heroku has the same version of ImageMagick. Strange :|
For some reason layer.alpha? == false. So I did sq.alpha(Magick::ActivateAlphaChannel) and then it worked!
Reference: http://www.imagemagick.org/RMagick/doc/image1.html#alpha

Add a rectangle to the image using image magic

Good day.
How to impose white_rectangle.jpg on logo.jpg in the image below
using Imagemagic.
And a bonus question: what's Ruby's method can make the task.
def (path_to_image)
# impose white_rectangle.jpg on logo
end
This can easily be accomplished using RMagick:
require 'RMagick'
logo = Magick::Image.read("logo.jpg").first
rect = Magick::Image.read("white_rectangle.jpg").first
result = logo.composite(rect, x, y, Magick::CopyCompositeOp)
result.write "result.jpg"
An alternative is to just draw a white rectangle without using a composite image:
image = Magick::Image.read("logo.jpg").first
gc = Magick::Draw.new
gc.stroke = 'white'
gc.fill = 'white'
gc.rectangle x_start, y_start, x_end, y_end
gc.draw(image)
image.write "result.jpg"
Using ImageMagick command line tools, you can overlay one image with another like this:
$ composite white_rectangle.jpg logo.jpg -geometry +x+y result.jpg

flatten_images with transparent background using RMagick gem

Seems like I'd be able to find this, but can't turn up anything. Have a short script:
require 'rubygems'
require 'RMagick'
img = Magick::ImageList.new("public/images/dev_banner_background.png")
gc = Magick::Draw.new
img.annotate(gc, 0,0,15,130, "| #{ENV['SERVER_TYPE']} Server |") do
self.pointsize = 13
self.rotation = -45
self.kerning = 1
self.stroke = "#ffffff"
self.fill = "#ffffff"
end
picture = img.flatten_images
picture.write("public/images/dev_banner.png")
dev_banner_background.png is a small banner on a transparent background similar to Github's "Fork me on Github" banner.
Works well to overlay this text on the banner (want to overlay on dev/staging servers). But the resulting images has a white background. Assuming it's in the flatten_images call, but can't figure out how to make it flatten with transparency. Anyone?
Found it.
img = Magick::ImageList.new("public/images/dev_banner_background.png")
img.background_color = "none"
gc = Magick::Draw.new
I was trying to set background color in flatten_images, and in the annotate method. I didn't realize that ImageList had a background_color attribute directly, since I didn't see it in the list of instance methods and attributes. Maybe I just missed it.

How to select color of a specific pixel in Rails?

Is it possible to somehow do the following in rails?
Get the color of a specific pixel from a image (for example at location 10px by 10px)
Delete all occurrences of that color from the image (gets replaced with transparent pixels)
Crop image to exclude any outer transparent pixels
Any advise would be greatly appreciated!
Rails? No.
Ruby? Yes.
Check out RMagick: http://rmagick.rubyforge.org/
Here's the code of how I did it using RMagick (thanks Alex Wayne for pointing me to RMagick)...
require 'RMagick'
img = Magick::Image.read("sample.jpg").first
bgcolor = img.pixel_color(1,1)
img.format = "PNG"
img.fuzz = 0.05
img.trim!
img.resize_to_fit!(100, 40)
bg = Magick::Image.new(100,40) { self.background_color = bgcolor }
img = bg.composite(img, Magick::CenterGravity, Magick::OverCompositeOp)
img.write("modified.png")
For my initial requirement (to just remove the outer colors or blank borders), the following is all you need:
require 'RMagick'
img = Magick::Image.read("sample.jpg").first
img.trim!
img.write("sample.jpg")

Resources