Convert picture to binary BASE64 - ruby-on-rails

How do I convert a picture to binary BASE64 and send it by post to another API to be saved?
It looks something like:
User imports a photo through the HTML form and it transforms it to binary BASE64 code:
base64_encode = Base64.encode64(img_from_fild_form)
The data is sent to another API (media):
options = { :auth_key=>01qw6, :post_id=>20, :base64_encode=>base64_encode }
HTTParty.post('localhost:9000/save_image', options)

if the input is from a rails form then it probably as easy as:
Base64.encode64(params[:key_for_file].read)
the uploaded file is likely an instance of ActionDispatch::Http::UploadedFile

It should be as easy as:
require 'base64'
base64_encoded = Base64.encode64(img_from_file_form)
Hope that helps. :)

Related

Ruby: Is there a way to specify your encoding in File.write?

TL;DR
How would I specify the mode of encoding on File.write, or how would one save image binary to a file in a similar fashion?
More Details
I'm trying to download an image from a Trello card and then upload that image to S3 so it has an accessible URL. I have been able to download the image from Trello as binary (I believe it is some form of binary), but I have been having issues saving this as a .jpeg using File.write. Every time I attempt that, it gives me this error in my Rails console:
Encoding::UndefinedConversionError: "\xFF" from ASCII-8BIT to UTF-8
from /app/app/services/customer_order_status_notifier/card.rb:181:in `write'
And here is the code that triggers that:
def trello_pics
#trello_pics ||=
card.attachments.last(config_pics_number)&.map(&:url).map do |url|
binary = Faraday.get(url, nil, {'Authorization' => "OAuth oauth_consumer_key=\"#{ENV['TRELLO_PUBLIC_KEY']}\", oauth_token=\"#{ENV['TRELLO_TOKEN']}\""}).body
File.write(FILE_LOCATION, binary) # doesn't work
run_me
end
end
So I figure this must be an issue with the way that File.write converts the input into a file. Is there a way to specify encoding?
AFIK you can't do it at the time of performing the write, but you can do it at the time of creating the File object; here an example of UTF8 encoding:
File.open(FILE_LOCATION, "w:UTF-8") do
|f|
f.write(....)
end
Another possibility would be to use the external_encoding option:
File.open(FILE_LOCATION, "w", external_encoding: Encoding::UTF_8)
Of course this assumes that the data which is written, is a String. If you have (packed) binary data, you would use "wb" for openeing the file, and syswrite instead of write to write the data to the file.
UPDATE As engineersmnky points out in a comment, the arguments for the encoding can also be passed as parameter to the write method itself, for instance
IO::write(FILE_LOCATION, data_to_write, external_encoding: Encoding::UTF_8)

How to open base64 spreadsheet on Ruby

I've been trying to manipulate a file that's base64 encoded that I'm recieving from my client.
I'm currently using https://github.com/zdavatz/spreadsheet/blob/master/GUIDE.md to manipulate it, however, there doesn't appear to be any way to open a file directly from the base64 blob, or should I write it and then read from it? can't that a potential security threat for the server?
for example, if I recieve a file :
file = params[:file] with contents:
data:application/vnd.ms-excel;base64,0M8R4KGxGuEAAAAAAAAAAAAAAAAAAAAAOwADAP7
(should I remove the data:application/vnd.ms-excel;base64, ?)
I'd like to open it with this:
Spreadsheet.client_encoding = 'UTF-8'
book = Spreadsheet.open "#{Rails.root}/app/assets/spreadsheet/event.xls"
(or with a blob or temp fle)
Sorry if it's pretty obvious, been looking for hours and there's not much info about it available, tried creating a temp file first but I don't think that's supported and there's not much I can get from the docs.
Shot in the dark: Maybe decode it, write to binary-enabled tempfile, and then feed that to Spreadsheet?
tmpfile = Tempfile.new.binmode
tmpfile << Base64.decode64(params[:file])
tmpfile.rewind
book = Spreadsheet.open(tmpfile)

Decoding Base64-encoded file in Rails takes too long

I get image files sent from an Android app to my Rails API. I decode the images using this:
StringIO.new(Base64.decode64(image[1]))
The issue is that it takes too much time; on heroku it takes even longer.
Is there another way to do this that's faster and more efficient?
You can also use this for decode base64:
# this method for decode base64 code to file
def parse_image_data(image[1])
base64_file = image[1]
ext, string = base64_file.split(',')
ext = MIME::Types[base64_file].first.preferred_extension if ext.include?("base64")
tempfile = Tempfile.new(["#{DateTime.now.to_i}", ".#{ext}"])
tempfile.binmode
tempfile.write Base64.decode64(string)
tempfile.rewind
tempfile
end

Rails save file as image

I use webdav protocol. gem 'net_dav' it's old but usefull
when i get file through it i receive it like this \xFF\xD8\xFF\xE0\x00\x10JFIF\x00\x01\x01\x01\x00H\x00H\x00\x00\xFF\...
How to convert to real image .jpg or .png?
you will have to decode this base64 string and then save file, something like
File.open('file_name.jpg', 'wb') do|f|
f.write(Base64.decode64(base_64_encoded_string))
end

Base64 Encode Image and Save it later to a file

I have an application where an admin can upload an image. I save the image in a file and also base64 encode (using Base64.strict_encode method of ruby) & save in my DB. This is so that when later someone deleted the physical file from the HDD/Server, I can still generate it back by base64 decoding it (Base64.decode method) and save in a file.
But the encoding and decoding didn't go well as the image get damaged and I'm unable to view it after save.
I checked the output of the Base64.strict_encode against the result when I used http://www.base64-image.de/ to encode the file, they were different.
Can anyone help me with this? What am I doing wrong? What am I not doing?
ENCODING THE IMAGE DURING UPLOAD:
imageLoc = image.image.to_s
logger.info '>>>>>>' + (Base64.strict_encode64(open(imageLoc).read)).to_s
image_data = Base64.strict_encode64(File.open(imageLoc, 'rb').read)
CategoryImage.update_image_data(image.id,image_data)
DECODING WHEN IMAGE FILE IS LOST:
File.open(File.join(APP_CONFIG['image_storage_location'], image[:image]), 'wb') { |f|
content = image[:image_data]
content.gsub!('\\r', "\r")
content.gsub!('\\n', "\n")
f.write(Base64.decode64(content))
f.close
}
ENCODED IMAGE FROM THE SITE (base64-image.de): https://shrib.com/cYLKfEe1?v=nc
ENCODED IMAGE FROM MY CODE: https://shrib.com/CODE-encoded%20image?v=nc
EDIT
When I replaced the encoded image data in my DB with the one I generated from the above named website, my image was regenerated and viewable. So the real is with the encoding.
Had once a similar issue, solved it by replacing the File.read method with IO.binread(imageLoc). Hope it helps. :)

Resources