Загрузка изображений Rails Carrierwave Base64
Каков наилучший способ загрузки изображения с клиента в бэкэнд Rails с использованием Carrierwave. Сейчас наш разработчик iOS отправляет файлы в качестве base64, поэтому запросы поступают следующим образом:
"image_data"=>"/9j/4AAQSkZJRgABAQAAAQABAAD/4QBYRXhpZgAATU0AKgAAAAgAAgESAAMAAAABAAEAAIdpAAQAAAABAAAAJgAAAAAAA6ABAAMAAAABAAEAAKACAAQAAAABAAAAHqADAAQAAAABAAAAHgAAAAD/2wBDAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/2wBDAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/wAARCAAeAB4DAREAAhEBAxEB/8QAHwAAAQUBAQE....
Итак, мой вопрос - это действительно два вопроса. Должен ли я сказать ему отправить другой формат файла? Если base64 - это правильный способ отправки этих файлов, то как мне с ними работать в несущей?
Ответы
Ответ 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 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
Ответ 2
Старый вопрос, но мне пришлось сделать аналогичную вещь, загрузите изображение из строки 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
Ответ 3
Вы можете легко достичь этого, используя Carrierwave-base64 Gem, вам не нужно самостоятельно обрабатывать данные, все, что вы делаете, это добавить драгоценный камень и изменить свою модель из
mount_uploader :file, FileUploader
к
mount_base64_uploader :file, FileUploader
и вот, теперь вы можете легко сказать:
Attachment.create(file: params[:file])