🙅‍♂️

【Rails】Vision AIを使用して不適切な画像を投稿させない機能をつくる

2023/11/02に公開

Gaol

不適切な画像を投稿させない

VisionAI概略

Googleのサービスの一つで、画像の解析を行うAPIの一種。
以下のようなことが出来る。

  • 画像からオブジェクトの分類や位置を自動検出
  • 画像のテキストを認識して作業を自動化
  • 不適切なコンテンツを検出して排除      等

実装

※今回は実装のみ(SAFE_SEARCH_DETECTION)を記述。APIの登録などは省略。

visionファイルをlibフォルダの直下に作成。
vision.rb
require "base64"
require "json"
require "net/https"

module Vision
  class << self
    def images_analysis(image_file)

      api_url = "https://vision.googleapis.com/v1/images:annotate?key=#{ENV["GOOGLE_API_KEY"]}"
      
      base64_image = Base64.encode64(image_file.tempfile.read)

      params = {
        requests: [{
          image: {
            content: base64_image
          },
          features: [
            {
              type: "SAFE_SEARCH_DETECTION"
            }
          ]
        }]
      }.to_json

      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)
      result = JSON.parse(response.body)

      if (error = result["responses"][0]["error"]).present?
        raise error["message"]
      elsif
        result_arr = result["responses"].flatten.map do |parsed_image|
          parsed_image["safeSearchAnnotation"].values
        end.flatten
          if result_arr.include?("POSSIBLE") || result_arr.include?("LIKELY") || result_arr.include?("VERY_LIKELY")
            false
          else
            true
          end
      end
    end
  end
end

vision.rbの記述は以上で、今回は画像のファイルを複数枚投稿した際に一枚でも不適切な画像が含まれているかを確認したいので、コントローラーにその記述をしていく。また、画像を複数枚登録するのはfacilityの部分になるので、このコントローラーのcreate部分にその内容を記述していく。(ネスト構造になっているので、綺麗なコードではないとおもいやすが、そこはご了承。)

facilities_controller.rb
  # 新規登録
  def create
    # Facilityモデルの初期化
    @facility = Facility.new(facility_params)
    @facility.end_user_id = current_end_user.id
    if facility_params[:images].present?
      facility_params[:images].each do |image|
        result = Vision.images_analysis(image)
        if result == false
          flash.now[:alert] = "画像が不適切です。最初から入力して下さい。"
          render :new
          return
        end
      end
    end
      # FacilityモデルをDBへ保存
      if @facility.save
        # showページへ画面遷移
        flash[:notice] = "記事を投稿しました。"
        redirect_to facility_path(@facility.id)
      else
        flash.now[:alert] = "もう一度入力してください。"
        render :new
      end
  end
  
  # 登録内容更新
  def update
    @facility = Facility.find(params[:id])
      if facility_params[:images].present?
        facility_params[:images].each do |image|
          result = Vision.images_analysis(image)
          if result == false
            flash[:notice] = "画像が不適切です。更新をやり直してください。"
            redirect_to facility_path(@facility) and return
          end
        end
      end
      if @facility.update(facility_params)
        flash[:notice] = "記事を更新しました。"
        redirect_to @facility
      else
        flash[:notice] = "更新が失敗しました..."
        redirect_to facility_path(@facility)
      end
  end
  :
  :
  # ※private部分は記事投稿用に一部内容を省略。(:area_introductionのあとを省略)
    private
  def facility_params
    params.require(:facility).permit(:loker_name, :area_name, :area_introduction ... images: [])
  end

自作した lib/vision.rb を読み込むために、config/application.rb に以下の記述を追記

config/application.rb
:
:
module CoinLooker
  class Application < Rails::Application
    # Initialize configuration defaults for originally generated Rails version.
    config.load_defaults 6.1
    
    # 追記
    + config.paths.add 'lib', eager_load: true

    # Configuration for the application, engines, and railties goes here.
    #
    # These settings can be overridden in specific environments using the files
    # in config/environments, which are processed later.
    #
    # config.time_zone = "Central Time (US & Canada)"
    # config.eager_load_paths << Rails.root.join("extras")
  end
end

SAFE_SEARCH_DETECTIONでできること

カテゴリ
adult ポルノ画像と非ポルノ画像を区別
spoof 元画像に対するあからさまで滑稽な、または不快な改変であるか
medical 手術、病気、体の一部の生々しい画像を含んでいるか
violence 殺人や射撃、血、血のりといった場面や物を含むもの
racy 際どい画像か

参照記事

https://zenn.dev/crinoid/articles/f41a4a09753a71

https://qiita.com/Neko-wo-kau/items/52b2c496d202ad7cf144

Discussion