Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Open and save base64 encoded image data URI in Ruby

Tags:

file

ruby

base64

From several posts I've seen, I am trying this

x = Base64.decode64("data:image/png;base64,iVBOR....")
File.open('test.png','wb') {|file| file.write x}

But then I can't open the image with a viewer, do I have to do something more?

like image 732
sites Avatar asked Apr 14 '13 02:04

sites


2 Answers

Your problem is that you're trying to decode the 'data:image/png;base64,' prefix as Base64 data; that prefix is perfectly valid Base64 data but it is not the Base64 representation of a PNG file. The result is that your test.png file contains a bunch of nonsense followed by some bits that actually are a PNG file. Strip off the data URL prefix before decoding the PNG:

data_url = "data:image/png;base64,iVBOR...."
png      = Base64.decode64(data_url['data:image/png;base64,'.length .. -1])
File.open('test.png', 'wb') { |f| f.write(png) }
like image 170
mu is too short Avatar answered Sep 21 '22 16:09

mu is too short


Instead of using a Regexp, you can also make use of the simple String#index method.

Returns the index of the first occurrence of the given substring or pattern (regexp) in str. Returns nil if not found.

If you have a reasonably sane data source (like JavaScript's .toDataURL() on a canvas), you can rely on the fact that common mimetypes will not contain commas.

dataURL = "data:image/png;base64,iVBOR...."
start = dataURL.index(',') + 1                   # .index used here
x = Base64.decode64 dataURL[start..-1]
File.open('test.png','wb') {|file| file.write x}

If you're working with a free-form user file upload, beware that a few uncommon mime types do contain commas (e.g.: text/x-java-source,java). You can use the more conservative:

start = dataURL.index(';base64,') + 8

If you don't know if you have unprefixed base64 or data URL base64, you can use #index as test:

start = dataURL.index ';base64,'
dataURL = dataURL[(start+8)..-1] if start
x = Base64.decode64 dataURL
like image 32
whitehat101 Avatar answered Sep 17 '22 16:09

whitehat101