i_use_the_internet
i_use_the_internet

Reputation: 614

MiniMagick wrap text on image

On Rails 5.2.1, I am attempting to use MiniMagick to write text on an image. The problem is, it overflows beyond the bounds of the image's width for long texts.

I have attempted to use draw, label, annotation and caption methods from here but none give me the right result. caption does not even add the text to the image.

This is my code:

      temp_img = MiniMagick::Image.open(url_for(@post.image))
      img_width = temp_img[:width]

      temp_img.combine_options do |c|
        c.gravity 'North'
        c.draw "text 0, 0 '#{top_txt}'"
        #c.annotate '0,0', "'#{top_txt}'" (same result)
        #c.caption "'#{top_txt}'" (same result)
        #c.label "'#{top_txt}'" (same result)
        c.gravity 'South'
        c.draw "text 0, 0 '#{bot_txt}'"
        #c.annotate '0,0', "'#{bot_txt}'" (same result)
        #c.caption "'#{bot_txt}'" (same result)
        #c.label "'#{bot_txt}'" (same result)
        c.stroke('#000000')
        c.strokewidth 1
        c.fill('#FFFFFF')
        c.size "#{img_width}x"
        c.pointsize '40'
        c.font "#{Rails.root.join('public', 'font',
        'Franklin_Gothic_Heavy_Regular.ttf')}"
      end

This is my result: enter image description here The closest I have seen to a solution is this but is too messy.

Could there be a better way?

Upvotes: 0

Views: 2739

Answers (2)

Michael Wiltbank
Michael Wiltbank

Reputation: 141

You need to use Convert with MiniMagick and the syntax is a little tricky because there isn't many examples with Ruby for it.

caption_string = "caption: #{top_txt}"

MiniMagick::Tool::Convert.new do |img|
  img.gravity 'north'
  img.stroke '#000000'
  img.strokewidth 1
  img.fill '#FFFFFF'
  img.size "#{img_width}x"
  img.pointsize '40' #don't add this if you want it to adjust according to size
  img.font "#{Rails.root.join('public', 'font',
    'Franklin_Gothic_Heavy_Regular.ttf')}"
  img << caption_string
  img << url_for(@post.image)
end

Upvotes: 0

fmw42
fmw42

Reputation: 53081

Sorry, I do not know Minimagick. But in ImageMagick command line there is label: that automatically fits text to some dimension such as the image width. See https://imagemagick.org/Usage/text/#label. If MiniMagick does not support that directly, then perhaps you could use Ruby/Rmagick commands. See https://github.com/minimagick/minimagick (methods section), assuming RMagick supports a label: like method. Note that with label: and caption: you have to create a new image with with your text on a transparent background and then composite it over your original image.

Here is an example:

Input:

enter image description here

convert image.png \( -size 639x -background none -font Arial -fill black label:"The quick brown fox jumps over the lazy dog" \) -gravity center -compose over -composite result.png


enter image description here

Upvotes: 3

Related Questions