BETA

「【10分でできる】Railsに画像の動的生成機能をサクッと追加する」が10分でできなかった話とその解決

投稿日:2018-12-01
最終更新:2018-12-01

こんにちは。
今回はこちらの記事(https://qiita.com/codeq_official/items/848c705252075c631e29 )で躓いた話ととりあえずの解決をしたことの備忘録兼報告的な記事です。

別にタイトルでDisっているわけではないというか、むしろ10分でできなくてごめんなさい。

0、環境

Win 10(x64)
Ruby 2.4.5p335
Rails 5.2.1
ImageMagick 7.0.8-14 Q16 x64 2018-10-24(DLL版)
gem MiniMagick 4.9.2

1、躓き

とりあえず上記記事の通りにコードをコピペしたらできなかった。
真っ黒。なんでやねん。
(URLがimages2/ogp2.pngとなっていますがこれはわざとです。真っ黒画面を再現するために、成功した後からもう一度設定し直したやつです)

2、調査

色々調査しました。
以下は一旦上記記事ですべきこと(コントローラー作ったり、routes.rbを修正したり)ができているという前提で進めます。

①ImageMagick
この記事(http://d.hatena.ne.jp/takehikom/20160804/1470343978 )によると、ImageMagickはバージョン7からコマンドを変えたそうです。
何ー!と思ったけど、ちゃんと昔のコマンドを使えるようにインストールできる(http://munibus.hatenablog.com/entry/2017/09/15/215805 )みたいなので、その通りインストールしてみました。
多分これで大丈夫

②MiniMagick
ImageMagickを、昔のコマンドが使えるようにインストールしたものの、やはりちゃんと動くのか心配だったので、動作確認を取りました。
具体的には適当なところでMiniMagickが加工したであろう画像を書き出すというものです。
app/controllers/concerns/ogp_creator.rbに以下を追加

  def self.build(text)
    text = prepare_text(text)
    image = MiniMagick::Image.open(BASE_IMAGE_PATH)
    image.combine_options do |config|        
      config.font FONT
      config.fill 'white'
      config.gravity GRAVITY
      config.pointsize FONT_SIZE
      config.draw "text #{TEXT_POSITION} '#{text}'"
    end
    # 以下を追加
    image.write './app/assets/images/ogpimage.png'
  end

そしたらちゃんと画像が出ました。
ちなみに

  image.write 'ogpimage.png'

と書くだけだとプロジェクトルートフォルダに書き出されます。

③tempfile
image.writeを消してから、次はapp/controllers/images_controller.rbに出てくる.tempfileを疑いました。

class ImagesController < ApplicationController
  def ogp
    text = ogp_params[:text]
    image = OgpCreator.build(text).tempfile.open.read
    send_data image, :type => 'image/png',:disposition => 'inline'
  end

  def ogp_params
    params.permit(:text)
  end
end

なんだこりゃ。
よく分からなかったけど、MiniMagickのAPIドキュメント(https://www.rubydoc.info/gems/mini_magick/MiniMagick%2FImage:tempfile )を読むとFileオブジェクト?っぽいので、適当に改変。

class ImagesController < ApplicationController
  def ogp
    text = ogp_params[:text]
    image = OgpCreator.build(text).tempfile.path
    p image
    # send_data image, :type => 'image/png',:disposition => 'inline'
  end

  def ogp_params
    params.permit(:text)
  end
end

pメソッドは標準出力(rails serverが動いているコマンドプロンプトorターミナル)に出力するというもので、ユーザーフォルダの奥深くのtempファイルのパスが出てました。
これもちゃんと出力されている。っていうか何度もトライしまくったせいでゴミ画像がわんさか・・・(笑)

④send_data
ここまで来たらsend_dataの行が怪しいんだけど、.open.readもよく分からん。
ここ(https://blog.goo.ne.jp/shouchan78-yd/e/63d60a04d6d380e245676abfbe41f9e8 )を参考にsend_dataでちゃんと画像を表示するように書いてもやっぱり真っ黒。
うーん。

分からん。

3、とりあえず解決させる

画像は出力されるんだから別の方法で表示してやれば良い。
元記事では「ビューファイルはいらない」としてましたが、一度コントローラーを削除して、ビューファイルを一緒に作るようにコントローラーを作り直しました。
然る後に、
①config/routes.rbを再編集

  get 'images/ogp', to: 'images#ogp', as: 'images_ogp'

.pngを消しました

②app/views/images/ogp.html.erbを編集

  <h1>Images#ogp</h1>
  <p>Find me in app/views/images/ogp.html.erb</p>
  <%= image_tag('ogpimage.png', :size => '400x210') %>

app/assets/imagesにある画像を読み込むように記述

③app/controllers/concerns/ogp_creator.rbに再度image.writeメソッドを追加

  image.write './app/assets/images/ogpimage.png'

これは先ほどの通りです。

そして結果


出ました。

ちゃんと渡した値を合成してくれています。
gifファイルでも録画したんですが、Qrunchはgifファイルはアップできないのかな?

とにかく、今自分が必要なのは動的画像生成機能なので、これで良しとします。

4、お願い

結局、真っ黒の原因が分からずでした。
ブラウザが怪しいのか、send_dataの行なのか分かりません。
どなたかこの謎が解ける方、コメントをお願いします。

技術ブログをはじめよう Qrunch(クランチ)は、プログラマの技術アプトプットに特化したブログサービスです
駆け出しエンジニアからエキスパートまで全ての方々のアウトプットを歓迎しております!
or 外部アカウントで 登録 / ログイン する
クランチについてもっと詳しく

この記事が掲載されているブログ

@WEkFtOQhlqcyDEsyの技術ブログ

よく一緒に読まれる記事

0件のコメント

ブログ開設 or ログイン してコメントを送ってみよう