2013-02-15 147 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])