Madogiwa Blog

主に技術系の学習メモに使っていきます。

minimagickで生成した画像をDBに保存したときに`ArgumentError (invalid byte sequence in UTF-8)`が発生したときの対処法

minimagickを最近ちょっと使っているのですが、合成した画像を保存する際に、めちゃめちゃハマったので対応方法をメモしておきますφ(・

事象

画像に文字を合成してMiniMagick::Imageインスタンスを返すImageBuilder::PostThumbnail.buildの返り値からバイナリ文字列を取得し、保存しようとしたところArgumentError: invalid byte sequence in UTF-8が発生した。

[3] pry(main)> p.thumbnail = ImageBuilder::PostThumbnail.build("hoge").tempfile.open.read
[4] pry(main)> p.save
   (0.2ms)  BEGIN
   (0.2ms)  ROLLBACK
ArgumentError: invalid byte sequence in UTF-8

解決策

返り値からバイナリ文字列を取得する際にbinmodeを呼び出してからバイナリ文字列を取得することで解決できました🙌

[6] pry(main)> p.thumbnail = ImageBuilder::PostThumbnail.build("hoge").tempfile.open.binmode.read
[7] pry(main)> p.save
   (0.2ms)  BEGIN
  PostImage Load (4.7ms)  SELECT "post_images".* FROM "post_images" WHERE "post_images"."post_id" = $1  [["post_id", 5]]
  Post Update (2.2ms)  UPDATE "posts" SET "thumbnail" = $1, "updated_at" = $2 WHERE "posts"."id" = $3  [["thumbnail", "<17691 bytes of binary data>"], ["updated_at", "2018-12-01 12:58:39.176813"], ["id", 5]]
  ActsAsTaggableOn::Tagging Load (0.9ms)  SELECT "taggings".* FROM "taggings" WHERE "taggings"."taggable_id" = $1 AND "taggings"."taggable_type" = $2  [["taggable_id", 5], ["taggable_type", "Post"]]
   (4.7ms)  COMMIT
=> true

binmodeを使うとバイナリモードでファイルを開くことが出来るみたいですね👀
詳細はよくわかってないのですが、今回は画像のバイナリ文字列が取得したかったので、binmodeを使ったほうがよかったみたいです🤔

参考

class IO (Ruby 2.5.0)#binmode