Rails
MiniMagick
ActiveStorage

Active Storageで添付した画像ファイルのピクセル情報を取得する

概評

  • Active Storageで添付した画像ファイルを扱うにはmini_magickを使う
  • 画像ファイルをmini_magickで処理するときは MiniMagick::Image.read(xxx.yyy.download) 経由にする
  • ピクセル情報は MiniMagick::Imageの get_pixelsで取得する

背景

機械学習で画像取得するrailsアプリ作ろうと思って、railsで画像を保存する方法を調べていたらactive storageに興味がわき、使ったら予想以上に便利だったので紹介。

参考

環境

  • rails 5.2.1 (5.2でOK)
  • imagemagick (入っていなければbrewとかapt-getとかでインストールしてださい。)

ActiveStorageを使えるようにする

まず、active_storageのインストールをする

rails active_storage:install

そうすると、下記のようなmigrationファイルが作成されます。このファイルはとくに何もしなくてOKです。

db/migrate/20180917060213_create_active_storage_tables.active_storage.rb
# This migration comes from active_storage (originally 20170806125915)
class CreateActiveStorageTables < ActiveRecord::Migration[5.2]
  def change
    create_table :active_storage_blobs do |t|
      t.string   :key,        null: false
      t.string   :filename,   null: false
      t.string   :content_type
      t.text     :metadata
      t.bigint   :byte_size,  null: false
      t.string   :checksum,   null: false
      t.datetime :created_at, null: false

      t.index [ :key ], unique: true
    end

    create_table :active_storage_attachments do |t|
      t.string     :name,     null: false
      t.references :record,   null: false, polymorphic: true, index: false
      t.references :blob,     null: false

      t.datetime :created_at, null: false

      t.index [ :record_type, :record_id, :name, :blob_id ], name: "index_active_storage_attachments_uniqueness", unique: true
    end
  end
end

上記ファイルをmigrationします。

rails db:migrate

画像ファイルを扱いたいモデルに下記記述を追加します。たとえば、Foodモデルにhogeという名前で画像ファイルを扱いたい場合は以下のような感じ。

app/models/food.rb
class Food < ApplicationRecord
  has_one_attached :hoge
end

画像処理をしたいので、下記のgemもインストール。
Gemfile

gem 'mini_magick'

これで、準備OK。

ActiveStorageをコンソール上でファイルを添付する

webのフォームを使う例は、今回は特に説明しません。前述の参考に示したリンクに詳しいです。

コンソールで画像を添付するには attach をつかいます。

例えば、 public/images 配下に画像ファイルを配置しているとしているとしたら下記のような感じです。

> food = Food.first
> food.hoge.attach(io: File.open("public/images/#{ファイル名}"), filename: 'image.jpg', content_type: 'application/jpeg')

添付したファイルをmini_magickに渡してピクセル情報を取得する

downloadメソッドでデータを取得して、取得したdataを MiniMagick::Image.read で読み込みます。

rails c で以下実行します

food = Food.first
data = food.hoge.download # downloadメソッドでデータが取得できる
mini_magick_obj = MiniMagick::Image.read(data) データを読み込む

ピクセル情報を取得するにはget_pixelsをつかいます。

mini_magick_obj.get_pixels

所感

  • Active storage便利。carrierwaveと違って、 モデルにカラムを追加しないでいい のがgood。少なくともlocalで扱う限りは、設定最小限で画像がすぐ使える。
  • すくなくとも、プロトタイプで画像ファイルを扱うなら、active storageで十分だとおもう。