使用Rmagick或ImageMagick在自然背景上定位标题

时间:2015-04-17 17:35:31

标签: ruby-on-rails ruby image-processing imagemagick rmagick

我有一个背景图片,我想添加一个文本框。

我试图弄清楚如何将标题放在它上面的正确位置。 (我使用标题,因为我需要自动换行功能)。

现在,我只能在左上角显示文字,但我需要能够手动定位它开始的位置。

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")

4 个答案:

答案 0 :(得分:5)

以下是使用convert的ImageMagick命令行的答案。如果你想在Rmagick上使用这个方法,你必须自己移植它。

  1. 文本框的大小。当您使用-size NxM caption:"some text"时,文字会自动放入尺寸为NxM的框中。

    < / LI>
  2. 文本框的基本位置。您可以将-gravity与参数一起使用。可能的基本论点是:无, 中央, 东, 忘记, 东北, 北, 西北, 东南, 南, 西南, 西。

    这些基本的-gravity运算符将文本框放入由他们的&#34;说&#34;表示的明显位置。名。

  3. 更细粒度的位置设置。但是,您还可以使用-geometry +X+Y将精确位置移动多个像素(+X将X像素移位到向右移动-X向左移动; +Y按Y像素向上推,-Y向下移动。

  4. 让我们使用宽270像素,高70像素的盒子。这是我使用的命令,首先是一个简短的文字:

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

    结果如下(原始图像在顶部,图像底部有文字):

    如果您想将较长的文字放入同一个框中,只需使用较长的文字: - )

    看这里:

    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 
    

    现在将文本框向右移动60个像素,向右移动30个像素:

    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 
    

答案 1 :(得分:2)

我通常会使用Magick::RVG

# 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' }

答案 2 :(得分:1)

使用Magick::Draw,并查询文字指标以定位文字。

require 'RMagick'
include Magick

text = "Hello\nworld"

img = ImageList.new('wizard:')
draw = Draw.new() {
  self.fill = '#FF00FF'
  self.font = "Helvetica"
  self.pointsize = 32
}
draw.text_align(RightAlign)
# Query font metrics for positioning (or get_multiline_type_metrics)
text_metrics = draw.get_type_metrics(text)
draw.text(img.columns, text_metrics.height, text)
draw.draw(img)

enter image description here

答案 3 :(得分:0)

是的,您可以控制文本在图像上的显示位置。实际上,您可以创建两个单独的图像,然后将它们组合在一起。

canvas是您要在其上复合的基本图像。 overlay_text是最重要的文本块。

require 'RMagick'
include Magick

the_text = 'This is the text how will it wrap????'
canvas = ImageList.new("some_input_file.png") 

overlay_text = Image.read("caption:#{the_text}") do
  self.size = "300x200"
  self.font = "Tahoma"
end.first

result = canvas.composite(overlay_text, Magick::CenterGravity, 0,-30, Magick::OverCompositeOp)

result.write('out.png')

overlay_text数据块使用caption,这会自动缩放the_text以适应self.size

如果您愿意,可以使用self.pointsize = 20修复字体大小,但如果您的文字大于拟定的大小,则会裁剪它。

获得两张图片后,您可以使用Image#composite(source_image, gravity, x, y, composite_operator)进行合成,这样可以获得标准重力和x&amp; y偏移控制。在这种情况下,文本叠加层从基础画布图像的中心向上合成30像素。