Есть ли способ преобразовать двоичные данные в тип данных, который позволит ActiveStorage присоединить его в качестве изображения к моей модели пользователя - PullRequest
3 голосов
/ 22 апреля 2019

Я нажимаю на api, чтобы получить изображение, которое они сохранили, и использовать его в качестве картинки профиля для пользователей нашего приложения.Я использую Ruby on Rails и ActiveStorage с AWS для прикрепления и сохранения изображения.Они отправляют обратно следующее:

{"status"=>"shared", "values"=>[{"$objectType"=>"BinaryData", "data"=>"/9j/4AAQSkZJRgABAQAASABIAAD/4QBMRXhpZgAAT.....KK5tT/9k=", "mime_type"=>"image/jpeg", "metadata"=>{"cropped"=>false}}]}

Я пробовал много разных способов присоединить его и манипулировать данными, например, просто прикрепить его как есть, Base64.decode64, Base64.encode64.Я также попытался создать новый файл и затем прикрепить его.Вот несколько примеров:

data = Base64.decode64(Base64.encode64(response[:selfie_image]["values"][0]["data"]))

user.profile_pic.attach!(
   io: StringIO.new(open(data).read),
   filename: "#{user.first_name}_#{user.last_name}_#{user.id}.jpg",
   content_type: "image/jpeg"
)

data = Base64.decode64(Base64.encode64(response[:selfie_image]["values"][0]["data"]))

out_file = File.new("#{user.first_name}_#{user.last_name}_# . {user.id}.jpg", "w")
out_file.puts(data)
out_file.close

user.profile_pic.attach(
 io: StringIO.new(open(out_file).read),
 filename: "#{user.first_name}_#{user.last_name}_#{user.id}.jpg",
 content_type: "image/jpeg"
)

Я также пытался:

user.profile_pic.attach(out_file)

Он либо говорит, что вложение равно нулю, либо в зависимости от того, как я манипулирую данными, которые он будетНе говорите, что неправильный тип заголовка содержимого файла JPEG, и выбросьте это как ошибку изображения.

Как я могу манипулировать этими данными, чтобы иметь возможность прикрепить их в качестве изображения для наших пользователей с ActiveStorage?

Ответы [ 2 ]

2 голосов
/ 22 апреля 2019

В командной строке ImageMagick вы можете использовать функцию inline: для декодирования данных base64 в gif или jpg. Изображение base64 здесь имеет прозрачность, его лучше всего сохранить в формате gif или png.

convert 'inline:data:image/gif;base64,
R0lGODlhIAAgAPIEAAAAAB6Q/76+vvXes////wAAAAAAAAAAACH5BAEAAAUALAAA
AAAgACAAAAOBWLrc/jDKCYG1NBcwegeaxHkeGD4j+Z1OWl4Yu6mAYAu1ebpwL/OE
YCDA0YWAQuJqRwsSeEyaRTUwTlxUqjUymmZpmeI3u62Mv+XWmUzBrpeit7YtB1/r
pTAefv942UcXVX9+MjNVfheGCl18i4ddjwwpPjEslFKDUWeRGj2fnw0JADs=
'  b64_noseguy.gif


enter image description here

Но вы все равно можете сохранить его в JPG. Прозрачность будет потеряна, а фон будет черным.

convert 'inline:data:image/jpeg;base64,
R0lGODlhIAAgAPIEAAAAAB6Q/76+vvXes////wAAAAAAAAAAACH5BAEAAAUALAAA
AAAgACAAAAOBWLrc/jDKCYG1NBcwegeaxHkeGD4j+Z1OWl4Yu6mAYAu1ebpwL/OE
YCDA0YWAQuJqRwsSeEyaRTUwTlxUqjUymmZpmeI3u62Mv+XWmUzBrpeit7YtB1/r
pTAefv942UcXVX9+MjNVfheGCl18i4ddjwwpPjEslFKDUWeRGj2fnw0JADs=
'  b64_noseguy.jpg


enter image description here

См. https://imagemagick.org/Usage/files/#inline

Извините, я не знаю эквивалента в RMagick

1 голос
/ 22 апреля 2019

Чтобы это заработало, мне нужно было добавить gem "mini_magick" в мой gemfile, а затем использовать его для декодирования данных изображения, которые я получил от вызова API, и затем превратить их в BLOB-объект, чтобы ActiveStorage мог с ним справиться.

data = response[:selfie_image]["values"][0]["data"]
decoded_data = Base64.decode64(data)
image = MiniMagick::Image.read(decoded_data)
image.format("png")
user.profile_pic.attach(
    io: StringIO.new(image.to_blob),
    filename: "#{user.id}_#{user.first_name}_#{user.last_name}.png",
    content_type: "image/jpeg"
)
...