Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Positioning a caption over a background using Rmagick or ImageMagick

I have a background image that I want to add a text box to.

I am trying to figure out how to position a caption in the right spot on top of it. (I'm using caption because I need the word wrap feature).

Right now, I'm only able to get the text to show on the top left corner, but I need to be able to manually position where it starts.

require 'RMagick'
require 'Pry'
include Magick

text = "Lorem ipsum dolor sit amet"

img =  ImageList.new('template001.jpg')
img <<  Magick::Image.read("caption:#{text}") {
  self.fill = '#FFFFFF'
  self.font = "Helvetica"
  self.pointsize = 32
  self.size = "550x400"
  self.background_color = "none"
}.first

a = img.flatten_images

a.write("out.jpg")
like image 522
xeroshogun Avatar asked Apr 17 '15 17:04

xeroshogun


2 Answers

Here is an answer for the ImageMagick command line using convert. If you want to use this method with Rmagick, you'll have to port it yourself.

  1. Size of the text box. When you use -size NxM caption:"some text", the text will fit automatically into the box with the size NxM.

  2. Basic location of the text box. You can use -gravity with arguments. Possible basic arguments are: None, Center, East, Forget, NorthEast, North, NorthWest, SouthEast, South, SouthWest, West.

    These basic -gravity operators place the text box into the obvious spots indicated by their "speaking" names.

  3. Finer-grained location setting. However, you can additionally use -geometry +X+Y to shift the exact locations by a number of pixels (+X shifts X pixels to the right, -X shifts to the left; +Y pushes by Y pixels to the top, -Y pushes towards the bottom).

Let's use a box with 270 pixels width and 70 pixels height. Here is the command I used, at first with a short text:

mytext="Cheers\!"

convert                            \
  -background '#0008'              \
  -gravity center                  \
  -fill white                      \
  -size 260x70 caption:"${mytext}" \
   funny-santa.jpg                 \
  +swap                            \
  -gravity south                   \
  -composite                       \
   funny-santa---1.jpg 

Here is the result (original image on top, image with text on bottom):

If you want to put longer text into the same box, just use longer text :-)

Look here:

mytext="Dear Kids\! One day you'll learn everything about Santa Claus. On that day, please also remember what they told you about Jesus."

convert                            \
  -background '#0008'              \
  -gravity center                  \
  -fill white                      \
  -size 260x70 caption:"${mytext}" \
   funny-santa.jpg                 \
  +swap                            \
  -gravity south                   \
  -composite                       \
   funny-santa---2.jpg 

Now shift the text box by 60 pixels to the right and by 30 pixels to the top:

mytext="Dear Kids\! Pushing text boxes around to place captions at precise locations inside an image is easy."

convert                            \
  -background '#0008'              \
  -gravity center                  \
  -geometry +60+30                 \
  -fill white                      \
  -size 260x70 caption:"${mytext}" \
   funny-santa.jpg                 \
  +swap                            \
  -gravity south                   \
  -composite                       \
   teaching-santa.jpg 

like image 173
Kurt Pfeifle Avatar answered Oct 29 '22 00:10

Kurt Pfeifle


I usually use Magick::RVG for this:

# Create a canvas of the required size
rvg = Magick::RVG.new(550, 400) do |canvas|

  # Set the background image
  canvas.background_image = Magick::Image.read("bg.jpg").first

  # Create a style group for font and fill options
  canvas.g.styles(font_size: 21, fill: "#FFFFFF", font: "Helvetica") do |grp|

    # Output text at the desired location
    grp.text(150, 150, "caption:Lorem ipsum dolor sit amet")
  end
end

# Extract canvas as an image
img = rvg.draw

# Set the color profile to sRGB
img.colorspace = RGBColorspace

# Output as a PNG (you'll want to write this output to a file or save in a db)
img.to_blob { self.format = 'PNG' }
like image 23
infused Avatar answered Oct 29 '22 02:10

infused