How to render text on image with RMagick and Word wrap?

六月ゝ 毕业季﹏ 提交于 2019-12-06 09:58:23

问题


I need to render some text (unicode, helvetica, white, 22px, bold) on a image (1024x768).

This is my code so far:

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

Its all fine but its not automatically breaking the lines (Word wrap) to fit all the text into my defined area ( 800x600 ).

What am I doing wrong?

Thanks for helping :)


回答1:


On the Draw.annotate method the width parameter doesn't seem to have an effect on the rendering text.

I have faced the same problem and I developed this functions to fit the text to a specified width by adding new lines.

I have a function to check if a text fit a specified width when drawed on image

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

And I have another function to transform the text to fit in the specified width by adding new lines

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



回答2:


Try this:

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:#{my_text}") 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



回答3:


Found some code here that does the trick :)



来源:https://stackoverflow.com/questions/11788216/how-to-render-text-on-image-with-rmagick-and-word-wrap

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!