2013-02-15 109 views
15

什麼是使用Carrierwave將客戶端上的圖像上傳到Rails後端的最佳方式。現在我們的iOS開發者正在發送的文件爲base64,所以請求進入這樣的:Rails Carrierwave Base64圖像上傳

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

所以,我的問題實際上是兩個問題。我應該告訴他發送不同的文件格式嗎?如果base64是發送這些文件的正確方法,那麼我如何在carrierwave中處理它們?

+0

iOS應用程序無法發送標準的多部分文件上傳POST請求嗎? – Tomdarkness 2013-02-15 18:02:59

+0

我真的不確定。我不會在iOS中編寫代碼 – botbot 2013-02-15 21:09:44

+0

也不是,但我會問你的iOS開發人員,如果從Rails的角度來看,這是可能的,這似乎是最明智的選擇,而不是處理base_64編碼數據。 – Tomdarkness 2013-02-15 21:11:08

回答

26

我認爲一種解決方案可以將解碼後的數據保存到文件,然後將該文件分配給安裝的上傳器。之後,擺脫那個文件。

其他(內存)解決方案可以是這樣:

# 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 2013-02-15 22:23:49

+0

我很好奇什麼內存不是解決方案?我應該對這個解決方案的性能表示擔憂嗎? – botbot 2013-02-15 22:53:51

+0

如何調用image_data =(數據)? – botbot 2013-02-16 06:28:56

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

就可以輕鬆實現,使用Carrierwave-base64 Gem你不必自己處理數據,你要做的就是從

mount_uploader :file, FileUploader 
添加寶石和改變你的模型

mount_base64_uploader :file, FileUploader 

和完蛋了,現在你可以輕鬆地說:

Attachment.create(file: params[:file])