Vision APIをrailsに導入する


google cloud platformの設定

[ホーム画面]
①プロジェクトを作成する

[プロジェクト画面]
<認証情報>
②APIキー発行
 制限は全て「なし」とする
<ライブラリ>
③好きなapiを選択し、「有効にする」を押す。

ここでは、例としてVision APIを使用する。

    〜Vision APIのイメージ〜
  [引数]            [戻り値]
猫の画像 ▶ (Vision API) ▶ 配列 [頭, 猫, 目]

Rails作業環境の設定

①.envファイルを作成
右クリック [new file] "/.env"と命名

gemfile
gem 'dotenv-rails'

②プロジェクトと関連付けるためのAPIキーを記入

.env
GOOGLE_API_KEY="APIキーの値"

③libにライブラリの呼び出し設定を記載。

lib/vision.rb
require 'base64'
require 'json'
require 'net/https'

module Vision
  class << self
    def get_image_data(image_file)
      # APIのURL作成
      api_url = "https://vision.googleapis.com/v1/images:annotate?key=#{ENV['GOOGLE_API_KEY']}"

      # 画像をbase64にエンコード
      base64_image = Base64.encode64(open("#{Rails.root}/public/uploads/#{image_file.id}").read)

      # APIリクエスト用のJSONパラメータ
      params = {
        requests: [{
          image: {
            content: base64_image
          },
          features: [
            {
              type: 'LABEL_DETECTION'
            }
          ]
        }]
      }.to_json

      # Google Cloud Vision APIにリクエスト
      uri = URI.parse(api_url)
      https = Net::HTTP.new(uri.host, uri.port)
      https.use_ssl = true
      request = Net::HTTP::Post.new(uri.request_uri)
      request['Content-Type'] = 'application/json'
      response = https.request(request, params)

      # APIレスポンス出力
      JSON.parse(response.body)['responses'][0]['labelAnnotations'].pluck('description').take(3)
    end
  end
end

④configでlibに作成したファイルを読み込む記述を追加

config/application.rb
:
:
    config.load_defaults 5.2
    config.paths.add 'lib', eager_load: true # 追加
:
:

⑤記述の例
解析結果のカテゴリーを関連付けて保存するテーブルを作る。
解析したい画像が保存されているテーブルがphotosだとすれば、アソシエーションも考慮して、photo_idとする。

scheme.rb

  create_table "tags", force: :cascade do |t|
    t.string "name"
    t.integer "photo_id"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
  end
bash
   rails db:migrate
controller

    #Visionモデルに画像を渡すと、その画像の解析し、当てはまるカテゴリーを配列として返す。
    tags = Vision.get_image_data(photo.image)
    #該当したタグの配列をeach文で小分けにしてcreateする。
    #1対多の便利な機能、「親.子供create」と記述すれば、親_idが勝手に保存される。   
    tags.each do |tag|
      photo.tags.create(name: tag)
    end

view
<div class="tag-box">
  <% @photo.tags.each do |tag| %>
    <span class="label"><%= tag.name %></span>
  <% end %>
<?div>

こんなかんじになる。