2013-02-15 5 views
15

Каков наилучший способ загрузки изображения с клиента на сервер Rails с использованием Carrierwave. Сейчас наш разработчик IOS посылает в файлах как base64, так что запросы поступают в так:Rails Carrierwave Base64 Загрузка изображения

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

Итак, мой вопрос действительно два вопроса. Должен ли я сказать ему отправить другой формат файла? Если base64 - это правильный способ отправки этих файлов, то как мне с ними работать в wavewave?

+0

Является ли приложение iOS неспособным отправить стандартный запрос на отправку POST-файла с несколькими файлами? – Tomdarkness

+0

Я честно не уверен в этом. Я не кодирую в iOS – botbot

+0

Я тоже, но я бы спросил у вашего разработчика iOS, возможно ли это, как с точки зрения Rails, это похоже на наиболее разумный вариант, а не на обработку кодированных данных base_64. – Tomdarkness

ответ

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

+0

Мне любопытно, что бы не было в памяти решение было бы? Должен ли я беспокоиться о производительности с этим решением? – botbot

+0

Как будет вызываться image_data = (data)? – botbot

4

Старый вопрос, но я должен был сделать подобную вещь, загружать изображения из base64 строку, которая была передана на через запрос JSon. Это то, что я в конечном итоге делает:

#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]) 
Смежные вопросы