目標
refileでユーザーのプロフィール画像を編集した場合、
アップロードする画像をCloud Vision APIで画像解析し、
過激な画像の場合はDBに保存出来なくする。
開発環境
・Ruby: 2.5.7
・Rails: 5.2.4
・Vagrant: 2.2.7
・VirtualBox: 6.1
・OS: macOS Catalina
前提
下記実装済み。
Cloud Vision APIを有効化
1.下記記事の「Geocoding APIを有効化」と同様の手順で、Cloud Vision APIを有効化して下さい。
Geolocation APIを用いて緯度経度を算出する方法
2.ホーム画面に遷移し、IAMと管理をクリック
3.サービスアカウントをクリック
4.サービスアカウントを追加をクリック
5.サービスアカウント名(適当で良い)を入力し、作成をクリック
6.続行をクリック
7.キーを作成をクリック
8.キーのタイプをJSONに設定し、作成をクリック
9.キーが作成された事を確認し、閉じるをクリック
10.完了をクリック
11.キーをアプリケーション直下に移動
Cloud Vision APIの評価について
評価カテゴリー
| カテゴリー | 内容 |
|---|---|
| adult | アダルト画像かどうか |
| spoof | インターネットミームかどうか |
| medical | インターネットミームかどうか |
| violence | 暴力的な画像かどうか |
| racy | 際どい画像かどうか |
評価値
| 評価値 | 度合い |
|---|---|
| UNKNOWN | 解析不可 |
| VERY_UNLIKELY | 非常に低い |
| UNLIKELY | 低い |
| POSSIBLE | 可能性あり |
| LIKELY | 高い |
| VERY_LIKELY | 非常に高い |
実装
1.Gemを導入
評価カテゴリーを問わず、評価値がLIKELY又はVERY_LIKELYを
含む場合はDBに保存しない様に実装をしていきます。
Gemfile
gem 'google-cloud-vision'
ターミナル
$ bundle
2.Cloud Vision APIの設定ファイルを作成し、編集
ターミナル
$ touch lib/vision.rb
lib/vision.rb
require 'base64'
require 'json'
require 'net/https'
module Vision
class << self
def image_analysis(profile_image)
image_annotator = Google::Cloud::Vision::ImageAnnotator.new(
version: :v1,
credentials: JSON.parse(File.open('キーのファイル名') do |f| f.read end)
)
# リクエストパラメータ作成
image = profile_image # 解析させたい画像(引数)
requests_content = { image: { content: image }, features: [{ type: :SAFE_SEARCH_DETECTION }] }
requests = [requests_content]
# Cloud Vision APIに画像を送信
response = image_annotator.batch_annotate_images(requests)
result = response.responses[0].safe_search_annotation.to_h
# 解析結果が「LIKELY」又は「VERY_LIKELY」を含む場合はfalse、それ以外はtrueを返す
if result.values.include?(:LIKELY) || result.values.include?(:VERY_LIKELY)
return false
else
return true
end
end
end
end
3.コントローラーを編集
users_controller.rb
def update
# 画像が編集された場合
if params[:user][:profile_image].present?
# パラメーター(画像)を「tempfile」として開いて変数に代入
profile_image = File.open(params[:user][:profile_image].tempfile)
# Cloud Vision APIで画像分析して、分析結果を変数に代入
result = Vision.image_analysis(profile_image)
else
# 画像が編集されてない場合は「true」を代入
result = true
end
# 解析結果によって条件分岐
if result == true
@user.update(user_params)
redirect_to user_user_path(@user)
elsif result == false
flash[:notice] = '画像が不適切です'
render 'edit'
end
end









