2013-02-15 65 views
15

Carrierwaveを使用してクライアントからRailsバックエンドに画像をアップロードする最適な方法は何ですか?現在、私たちのiOS開発者はファイルをbase64形式で送信していますので、リクエストは次のようになります:Rails Carrierwave Base64画像アップロード

"image_data"=>"/9j/4AAQSkZJRgABAQAAAQABAAD/4QBYRXhpZgAATU0AKgAAAAgAAgESAAMAAAABAAEAAIdpAAQAAAABAAAAJgAAAAAAA6ABAAMAAAABAAEAAKACAAQAAAABAAAAHqADAAQAAAABAAAAHgAAAAD/2wBDAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/2wBDAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/wAARCAAeAB4DAREAAhEBAxEB/8QAHwAAAQUBAQE.... 

私の質問は本当に2つの質問です。別のファイル形式で送信するように教えてください。 base64がこれらのファイルを送信する正しい方法ならば、どうすればキャリアウェーブで扱うことができますか?

+0

iOSアプリは標準のマルチパートファイルアップロードPOSTリクエストを送信できませんか? – Tomdarkness

+0

私は正直にそれについては分かりません。私はiOSでコード化していません – botbot

+0

でも、Railsの観点からはこれが可能であるかどうかをiOS開発者に尋ねると、これはbase_64でエンコードされたデータを扱うのではなく、最も賢明なオプションのようです。 – Tomdarkness

答えて

26

デコードされたデータをファイルに保存し、このファイルをマウントされたアップローダに割り当てることが1つの解決策だと思います。その後、そのファイルを取り除く。

# define class that extends IO with methods that are required by carrierwave 
class CarrierStringIO < StringIO 
    def original_filename 
    # the real name does not matter 
    "photo.jpeg" 
    end 

    def content_type 
    # this should reflect real content type, but for this example it's ok 
    "image/jpeg" 
    end 
end 

# some model with carrierwave uploader 
class SomeModel 
    # the uploader 
    mount_uploader :photo, PhotoUploader 

    # this method will be called during standard assignment in your controller 
    # (like `update_attributes`) 
    def image_data=(data) 
    # decode data and create stream on them 
    io = CarrierStringIO.new(Base64.decode64(data)) 

    # this will do the thing (photo is mounted carrierwave uploader) 
    self.photo = io 
    end 

end 
+0

私は間違いなくこれを試してみます、ありがとう男 – botbot

+0

私は何がメモリ内の解決策になるのだろうか?このソリューションのパフォーマンスに関する懸念はありますか? – botbot

+0

image_data =(data)はどのように呼び出されますか? – botbot

4

古い質問が、私は同じようなことをしなければならなかった、JSONリクエスト経由で渡されたbase64文字列から画像をアップロードする:

その他(インメモリ)ソリューションは、このいずれかになります。これは私がやってしまったものです:

#some_controller.rb 
def upload_image 
    set_resource 
    image = get_resource.decode_base64_image params[:image_string] 
    begin 
    if image && get_resource.update(avatar: image) 
     render json: get_resource 
    else 
     render json: {success: false, message: "Failed to upload image. Please try after some time."} 
    end 
    ensure 
    image.close 
    image.unlink 
    end 
end 

#some_model.rb 
def decode_base64_image(encoded_file) 
    decoded_file = Base64.decode64(encoded_file) 
    file = Tempfile.new(['image','.jpg']) 
    file.binmode 
    file.write decoded_file 

    return file 
end 
0

あなたが簡単にあなたが行うすべての宝石を追加し、

mount_uploader :file, FileUploader 
からあなたのモデルを変更され、 Carrierwave-base64 Gemを使用して、データを自分で処理する必要がないことを達成することができます

mount_base64_uploader :file, FileUploader 

とのthatsそれを

に、今、あなたは簡単に言うことができる:

Attachment.create(file: params[:file]) 
関連する問題