質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

ImageMagick

ImageMagickとは、画像の表示や操作を行うオープンソースのソフトウェアです。プログラムはCで書かれており、GIFやJPEG、PDFなど画像ファイルフォーマット100種類以上に対応しています。

Q&A

解決済

1回答

732閲覧

mini_magickで2種類の文字列を画像内に描画したい

taishiaaaaa

総合スコア30

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

ImageMagick

ImageMagickとは、画像の表示や操作を行うオープンソースのソフトウェアです。プログラムはCで書かれており、GIFやJPEG、PDFなど画像ファイルフォーマット100種類以上に対応しています。

0グッド

0クリップ

投稿2018/12/17 04:08

前提・実現したいこと

Rubyのmini_magick gemを使って2種類の文字列を特定の画像の上から描画したい。

試したこと

下記のリンクのページを参考に文字列を画像に描画することは出来たのですが、フォントサイズやフォントが異なる文字列をもう一つ追加で描画する方法が思いつきません。(フォントサイズがタイトル40px、中身20pxのように2種類表示を画像内に描画したい)

自分なりに考えた方法としては
一度、1つ目の文字列を画像に描画し保存
その保存した画像をもう一度読み込んで、更にもう2つ目の文字列を描画し保存

という手順は思いついたのですが

  1. 似たようなコード群を2回も書くのもスマートではない
  2. 2度も保存と読み込みを繰り返したくない

これらの理由から、コード群が一箇所で完結するようなもっとスマートな方法を探しています。

こちらが参考にしているページです

helper

1module InvitesHelper 2 3 class InvitesHelper 4 require 'mini_magick' 5 require 'securerandom' 6 7 BASE_IMAGE_PATH = './app/assets/images/i.png'.freeze 8 GRAVITY = 'center'.freeze 9 TEXT_POSITION = '0,0'.freeze 10 FONT = './app/assets/fonts/genjyuubold.ttf'.freeze 11 FONT_SIZE = 65 12 INDENTION_COUNT = 11 13 ROW_LIMIT = 8 14 15 class << self 16 # 合成後のFileClassを生成 17 def build(text) 18 text = prepare_text(text) 19 @image = MiniMagick::Image.open(BASE_IMAGE_PATH) 20 configuration(text) 21 end 22 23 # 合成後のFileの書き出し 24 def write(text) 25 build(text) 26 @image.write uniq_file_name 27 end 28 29 private 30 31 # uniqなファイル名を返却 32 def uniq_file_name 33 "#{SecureRandom.hex}.png" 34 end 35 36 # 設定関連の値を代入 37 def configuration(text) 38 @image.combine_options do |config| 39 config.font FONT 40 config.gravity GRAVITY 41 config.pointsize FONT_SIZE 42 config.draw "text #{TEXT_POSITION} '#{text}'" 43 end 44 end 45 46 # 背景にいい感じに収まるように文字を調整して返却 47 def prepare_text(text) 48 text.scan(/.{1,#{INDENTION_COUNT}}/)[0...ROW_LIMIT].join("\n") 49 end 50 end 51 end 52end 53

controller

1 2include InvitesHelper 3 4  def create 5 @invite = Invite.new(invite_params) 6 if @invite.save 7 InvitesHelper.build(@invite.content).tempfile.open.read 8 InvitesHelper.write(@invite.content) 9 redirect_to user_invite_path(id: @invite.id) 10 else 11 render "new" 12 end 13 end

Inviteモデルのオブジェクトが保存されると、中身の文字列contentが画像内に描画されるようになっています。今回はこれに加えてフォントサイズが異なる文字列titleも描画したいと思っています。

ここに書いたコード自体はリンク先のものと殆ど一緒です。
お手数ですが、ここのコードが読みづらくコードの詳細を確認したい場合はリンク先をご覧ください。

回答いただけたら幸いです。よろしくお願いします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

自己解決

Helper

1module InvitesHelper 2 3 class InvitesHelper 4 require 'mini_magick' 5 require 'securerandom' 6 7 #content 8 BASE_IMAGE_PATH1 = './app/assets/images/i.png'.freeze 9 GRAVITY1 = 'center'.freeze 10 TEXT_POSITION1 = '0,200'.freeze 11 FONT1 = './app/assets/fonts/genjyuubold.ttf'.freeze 12 FONT_SIZE1 = 30 13 INDENTION_COUNT1 = 11 14 ROW_LIMIT1 = 8 15 16 #title 17 GRAVITY2 = 'center'.freeze 18 TEXT_POSITION2 = '0,0'.freeze 19 FONT2 = './app/assets/fonts/genjyuubold.ttf'.freeze 20 FONT_SIZE2 = 60 21 INDENTION_COUNT2 = 11 22 ROW_LIMIT2 = 8 23 24 class << self 25 # 合成後のFileClassを生成 content 26 def build1(text) 27 text = prepare_text1(text) 28 @image = MiniMagick::Image.open(BASE_IMAGE_PATH1) 29 configuration1(text) 30 end 31 32 # title 33 def build2(text) 34 text = prepare_text2(text) 35 configuration2(text) 36 end 37 38 # title 39 def write2(text) 40 build2(text) 41 @image.write uniq_file_name 42 end 43 44 45 private 46 47 # uniqなファイル名を返却 content 48 def uniq_file_name 49 "#{SecureRandom.hex}.png" 50 end 51 52 # 設定関連の値を代入 content 53 def configuration1(text) 54 @image.combine_options do |config| 55 config.font FONT1 56 config.gravity GRAVITY1 57 config.pointsize FONT_SIZE1 58 config.draw "text #{TEXT_POSITION1} '#{text}'" 59 end 60 end 61 62 # 背景にいい感じに収まるように文字を調整して返却 content 63 def prepare_text1(text) 64 text.scan(/.{1,#{INDENTION_COUNT1}}/)[0...ROW_LIMIT1].join("\n") 65 end 66 67 # title 68 def configuration2(text) 69 @image.combine_options do |config| 70 config.font FONT2 71 config.gravity GRAVITY2 72 config.pointsize FONT_SIZE2 73 config.draw "text #{TEXT_POSITION2} '#{text}'" 74 end 75 end 76 77 # title 78 def prepare_text2(text) 79 text.scan(/.{1,#{INDENTION_COUNT2}}/)[0...ROW_LIMIT2].join("\n") 80 end 81 end 82 end 83end

controller

1InvitesHelper.build1("タイトル") 2InvitesHelper.write2("コンテンツ")

同じコードを名前分けして
1つ目の文字列を描画 → writeで書き出さずにbuildして@imageに代入 → その@imageで2つ目の文字列を描画 → @imageをwriteで書き出して完了
ざっくり説明ですみません。
もし同じ問題で悩んでいる方(いないとは思いますが)がこの回答を見ても理解できなかったら僕にフォローなりなんなりください。

投稿2018/12/18 09:38

taishiaaaaa

総合スコア30

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問