[rails]base64エンコードされた画像をcarrierwaveに保存する


[まとめ] 現在開催中のKindleセール情報はこちら

Ruby 2.1.4, Rails 4.1.7 で確認

前回はcarrierwaveを使ってPOSTされた画像ファイルの保存を行うAPIを作ってみました。

今回はファイルではなく、base64エンコードされた画像データをpostして保存するのを試してみました。

ファイルアップロードを行った画像を、jsでcanvasを使って編集しbase64形式で再度アップロードする、といった際に使えると思います。

前回のcontrollerに機能を追加します。

1. base64形式の画像データを保存できるようにする

  • concern追加

app/controllers/concerns以下に carrierwave_base64_uploader.rb として以下のファイルを保存します。

  • user_controllerにupdate_base64アクションを追加

concernをincludeするとbase64画像保存メソッドがuserコントローラ内で使用可能になります。

# app/controllers/user_controller.rb

class UserController < ApplicationController
  include CarrierwaveBase64Uploader

  def update
    raise ArgumentError, 'invalid params' if params[:name].blank? || params[:profile].blank?

    user = User.find_or_create_by(name: params[:name])
    user.profile_image = params[:profile]
    user.save!

    render json: {
      name: user.name,
      profile_url: user.profile_image.url
    }
  end

  def update_base64
    raise ArgumentError, 'invalid params' if params[:name].blank? || params[:profile].blank?

    user = User.find_or_create_by(name: params[:name])
    user.profile_image = base64_conversion(params[:profile_base64])
    user.save!

    render json: {
      name: user.name,
      profile_url: user.profile_image.url
    }
  end
end

updateアクションとupdate_base64アクションはほとんど同じなので処理をまとめます。

とりあえずprivateメソッドにまとめましたがこんな感じでいいんでしょうか。。。

# app/controllers/user_controller.rb

class UserController < ApplicationController
  include CarrierwaveBase64Uploader

  def update
    raise ArgumentError, 'invalid params' if params[:name].blank? || params[:profile].blank?
    user_update
    update_response
  end

  def update_base64
    raise ArgumentError, 'invalid params' if params[:name].blank? || params[:profile_base64].blank?
    user_update
    update_response
  end

  private

  def user_update
    @user = User.find_or_create_by(name: params[:name])
    @user.profile_image = params[:profile] ? params[:profile] : base64_conversion(params[:profile_base64])
    @user.save!
  end

  def update_response
    render json: {
      name: @user.name,
      profile_url: @user.profile_image.url
    }
  end
end
  • routing追加
# config/routes.rb

Rails.application.routes.draw do
  post 'user/update'
  post 'user/update_base64'
end

とりあえずこれでbase64エンコード画像のアップロードAPIができました。

2. curlコマンドでAPIにアクセスしてみる

  • アプリケーション起動
./bin/rails s
  • base64エンコード画像を作成
irb -r base64 -r open-uri

'data:image/png;base64,' + Base64.strict_encode64(open('https://blog.hello-world.jp.net/wp-content/plugins/social-media-widget/images/default/64/twitter.png').read)

出力された文字列をコピーしておきます。

(base64エンコード画像作成の詳細に関してはこちらを参照)

  • curlで画像アップロード
curl -F 'name=test' -F 'profile_base64=base64文字列を貼る' http://localhost:3000/user/update_base64

# {"name":"test","profile_url":"http://localhost:3000/uploads/user/profile_image/1/base64.jpeg"}

APIのレスポンスに書いてあるprofile_urlをブラウザで開いてみると、画像がアップロードされていることを確認できます。

これでファイルアップロード、およびbase64形式でのアップロードが可能になりました。

参考

[まとめ] 現在開催中のKindleセール情報はこちら