Search code examples
rubyutf-8fontsrmagick

Multilingual text with rmagick


I'm using rmagick to annotate images programatically with text. The text will need to support a range of languages including Chinese, Korean, English among others. The font requirements I'm dealing with are very specific, and the font chosen for English supports a wide variety of western languages, but it doesn't support Chinese or Korean. I'll have other fonts for those languages.

The approach I have in mind is to map character ranges to particular fonts and programmatically tell rmagick what font to use based on that. Am I missing anything obvious, or is this a good approach to take?


Solution

  • Here is how I ended up solving this:

    def font_for(verb)
      return "#{Rails.root}/app/uploaders/fonts/Gotham-Bold.ttf" if verb =~ /\p{Latin}/
      return "#{Rails.root}/app/uploaders/fonts/ArialUnicode.ttf"
    end
    

    That method will take some text and return the path to an appropriate font face. Regex's character property matching comes in handy here! Then i can use the font_for method inside my rmagick script for annotating an image.

      def create_image_with_text
        canvas = Magick::ImageList.new
        canvas.new_image(640, 480)  {self.background_color = "white"}
        text = Magick::Draw.new
        text.font = font_for "english"
        text.pointsize = 23
        text.gravity = ::Magick::NorthGravity
        text.annotate(canvas, 0,0,0,28, "ENGLISH") { self.fill = '#343434' }
        text.font = font_for self.verb
        text.pointsize = 65
        text.gravity = ::Magick::CenterGravity
        text.annotate(canvas, 0,0,0,18, self.verb.upcase) { self.fill = '#343434' }
        tempfile = Tempfile.new(['new_center_stripe', '.jpg'])
        canvas.write tempfile.path
        self.image.store!(tempfile)
      end
    

    It is worth noting that this simplistic approach wouldn't handle input with mixed languages.