我需要在图像(1024x768)上渲染一些文本(unicode、helvetica、白色、22px、粗体)。
这是我到目前为止的代码:
img = Magick::ImageList.new("my_bg_img.jpg")
txt = Magick::Draw.new
img.annotate(txt, 800, 600, 0, 0, "my super long text that needs to be auto line breaked and cropped") {
txt.gravity = Magick::NorthGravity
txt.pointsize = 22
txt.fill = "#ffffff"
txt.font_family = 'helvetica'
txt.font_weight = Magick::BoldWeight
}
img.format = "jpeg"
return img.to_blob
一切都很好,但它不会自动换行(自动换行)以使所有文本适合我定义的区域(800x600)。
我做错了什么?
感谢您的帮助:)
在 Draw.annotate 方法中,宽度参数似乎对渲染文本没有影响。
我遇到了同样的问题,我开发了这个函数,通过添加新行来使文本适合指定的宽度。
我有一个函数可以检查在图像上绘制时文本是否适合指定的宽度
def text_fit?(text, width)
tmp_image = Image.new(width, 500)
drawing = Draw.new
drawing.annotate(tmp_image, 0, 0, 0, 0, text) { |txt|
txt.gravity = Magick::NorthGravity
txt.pointsize = 22
txt.fill = "#ffffff"
txt.font_family = 'helvetica'
txt.font_weight = Magick::BoldWeight
}
metrics = drawing.get_multiline_type_metrics(tmp_image, text)
(metrics.width < width)
end
我还有另一个函数可以通过添加新行来转换文本以适应指定的宽度
def fit_text(text, width)
separator = ' '
line = ''
if not text_fit?(text, width) and text.include? separator
i = 0
text.split(separator).each do |word|
if i == 0
tmp_line = line + word
else
tmp_line = line + separator + word
end
if text_fit?(tmp_line, width)
unless i == 0
line += separator
end
line += word
else
unless i == 0
line += '\n'
end
line += word
end
i += 1
end
text = line
end
text
end
试试这个:
phrase = "my super long text that needs to be auto line breaked and cropped"
background = Magick::Image.read('my_bg_img.jpg').first
image = Magick::Image.read("caption:#{phrase}") do
self.size = '800x600' #Text box size
self.background_color = 'none' #transparent
self.pointsize = 22 # font size
self.font = 'Helvetica' #font family
self.fill = 'gray' #font color
self.gravity = Magick::CenterGravity #Text orientation
end.first
background.composite!(image, Magick::NorthEastGravity, 20, 40, Magick::OverCompositeOp)
background.format = "jpeg"
return background.to_blob
也许它会对某人有所帮助,从上面的答案重构逻辑(没有真正的绘图):
class RMagickTextWrapper
SEPARATOR = ' '.freeze
def initialize(font_size, path_to_font_file = nil)
@drawing = Magick::Draw.new
@drawing.gravity = Magick::NorthGravity
@drawing.pointsize = font_size
@drawing.font_family = path_to_font_file if path_to_font_file
end
def text_with_line_breaks(text, width_of_bounding_box)
return text if text_fit?(text, width_of_bounding_box) || text.exclude?(SEPARATOR)
text.split(SEPARATOR).each_with_object('').with_index do |(word, line), index|
tmp_line = "#{line}#{SEPARATOR}#{word}"
line << text_fit?(tmp_line, width_of_bounding_box) ? SEPARATOR : '\n' if index != 0
line << word
end
end
private
def text_fit?(text, width)
@drawing.get_multiline_type_metrics(text).width < width
end
end
在here找到了一些可以解决问题的代码:)