Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a way to convert binary data into a data type that will allow ActiveStorage to attach it as an image to my User model

I am hitting an api to get an image that they have stored and use it as the profile pic for our application's users. I'm using Ruby on Rails and ActiveStorage with AWS to attach and store the image. What they send back is this:

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

I tried a lot of different ways to attach it and manipulate the data such as just attaching it as it is, Base64.decode64, Base64.encode64. I also tried creating a new file and then attaching that. Here are some examples:

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"
)

I also tried:

user.profile_pic.attach(out_file)

It keeps either saying attachment is nil or depending on how I manipulate the data it will say not a jpeg file content header type wrong and throw that as an image magick error.

How can I manipulate this data to be able to attach it as an image for our users with ActiveStorage?

like image 835
Alex Gonzalez Avatar asked Mar 04 '23 02:03

Alex Gonzalez


1 Answers

To get this to work I had to add gem "mini_magick" to my gemfile and then use it to decode the image data I was receiving from the api call and then turn it into a blob so that ActiveStorage could handle it.

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"
)
like image 155
Alex Gonzalez Avatar answered Mar 07 '23 02:03

Alex Gonzalez