Search code examples
ruby-on-railsvue.jscarrierwaveminimagick

Minimagic not showing the correct font defined in the image creation


# frozen_string_literal: true

class UserUploader < ApplicationUploader
  include CarrierWave::MiniMagick

  def generate_image(text)
    tmp_path = File.join(Dir.tmpdir, "#{SecureRandom.hex}.png")

    MiniMagick::Tool::Convert.new do |img|
      img.size "500x200"
      img.xc "white"            # Background color
      img.gravity "Center"      # Center the text
      img.pointsize "36"        # Font size
      img.fill "black"          # Text color
      img.draw "text 0,0 '#{text}'"
      img.font "#{Rails.root.join('public', 'font', 'Franklin_Gothic_Heavy_Regular.ttf')}"
      img << tmp_path           # Save image to this path
    end

    File.open(tmp_path)  # Return file handle
  end
end

I am sending params from the frontend and the font which I am using on the frontend is Franklin_Gothic_Heavy_Regular.ttf defined in app/assets/fonts/Franklin_Gothic_Heavy_Regular.ttf

For using it in the uploader I have added the same font file in public/font/Franklin_Gothic_Heavy_Regular.ttf but when image is stored it doesn't show the correct font.

I am using vuejs on the front end and rails on backend. Please help me fix this.

ImageMagick info

Version: ImageMagick 7.1.0-58 Q16-HDRI x86_64 20802 https://imagemagick.org
Copyright: (C) 1999 ImageMagick Studio LLC
License: https://imagemagick.org/script/license.php
Features: Cipher DPC HDRI Modules OpenMP(5.0) 
Delegates (built-in): bzlib fontconfig freetype gslib heic jng jp2 jpeg jxl lcms lqr ltdl lzma openexr png ps raw tiff webp xml zlib
Compiler: gcc (4.2)

puts img.command.join(" ") returns

magick convert -size 500x200 xc:white -gravity Center -pointsize 36 -fill black -draw text 0,0 'Testing Font' -font /Users/Documents/work/company/public/font/Franklin_Gothic_Heavy_Regular.ttf /var/folders/tc/3b0wh1xs7z7dms5rxj1l23_00000gn/T/74a90ba3c194bda014cb2706a3fcdd32.png

Solution

  • In the docs for -draw

    You can set the primitive color, font, and font bounding box color with -fill, -font, and -box respectively. Options are processed in command line order so be sure to use these options before the -draw option.

    So all you should need to do is change the order

    MiniMagick::Tool::Convert.new do |img|
      img.size "500x200"
      img.xc "white"            # Background color
      img.gravity "Center"      # Center the text
      img.pointsize "36"        # Font size
      img.fill "black"          # Text color
      img.font "@#{Rails.root.join('public', 'font', 'Franklin_Gothic_Heavy_Regular.ttf')}"
      img.draw "text 0,0 '#{text}'"
      img << tmp_path           # Save image to this path
    end
    

    As an aside the use of the class name MiniMagick::Tool::Convert appears to be deprecated. Instead you can just use MiniMagick.convert.