Josh Smith
Josh Smith

Reputation: 15028

How do you handle base64 encoded files in Elixir?

I'm trying to figure out how to take an existing JSON API where the client is uploading a base64 encoded image, for example:

data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7

...and turn it into a file to use it for processing in the arc library.

How are you supposed to decode this and turn it into a useable file?

Upvotes: 4

Views: 8538

Answers (2)

Dogbert
Dogbert

Reputation: 222168

First step is to extract the Base 64 data. Then you can use Base.decode64!/1 and File.write!/2.

If you're guaranteed to get only image/gif, you can do:

iex(1)> input = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"
iex(2)> "data:image/gif;base64," <> raw = input
iex(3)> raw
"R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"
iex(4)> File.write!("a.gif", Base.decode64!(raw))
:ok

or if you're only guaranteed to get base64 with any file type, can you do:

iex(1)> input = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"
iex(2)> {start, length} = :binary.match(input, ";base64,")
{14, 8}
iex(3)> raw = :binary.part(input, start + length, byte_size(input) - start - length)
"R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"
iex(4)> File.write!("a.gif", Base.decode64!(raw))
:ok

Both these snippets will write the file to a.gif which you can use for whatever you want. If you want to create temporary images, I would suggest storing them somewhere inside System.tmp_dir/1 and then deleting them after use.

Upvotes: 15

Josh Smith
Josh Smith

Reputation: 15028

It looks like the following may work:

{:ok, file} = File.open "test.gif", [:write]
{:ok, image_string} = Base.decode64("R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7")
IO.binwrite file, image_string

I'm going to leave this up here in case someone has a better solution than this, but this appears to at least do the job.

Upvotes: 3

Related Questions