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

6

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

我在尝试找到如何将标题位置正确地放置在图片上面。(我使用标题是因为我需要自动换行功能)。

目前,我只能使文本显示在左上角,但我需要手动确定它开始的位置。

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个回答

8
这里提供了使用ImageMagick命令行的答案,使用convert。如果您想在Rmagick中使用此方法,您需要自行移植。
  1. 文本框的大小。当您使用-size NxM caption:"some text"时,文本将自动适应大小为NxM的框。

  2. 文本框的基本位置。您可以使用带参数的-gravity。可能的基本参数有:None、Center、East、Forget、NorthEast、North、NorthWest、SouthEast、South、SouthWest、West。

    这些基本的-gravity操作符将文本框放置在其“口语”名称所示的明显位置。

  3. 更精细的位置设置。但是,您还可以使用-geometry +X+Y来通过像素数将确切位置移动(+X向右移动X个像素,-X向左移动;+Y向上推Y个像素,-Y向下推)。

让我们使用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 


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

一个警告:据我所知,RVG不支持任何形式的文本换行。我是在艰难的道路上发现了这一点。如果你需要文本换行,唯一的选择是创建字幕。除了文本换行之外,我喜欢RVG,因为使用 composite 可以更容易地精确定位到另一张图像顶部。 - Daniel Bonnell

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


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 & y 偏移控制。在这种情况下,文本叠加是从基础画布图像的中心向上偏移30像素进行合成的。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接