2

Im using the phoenix framework to create a webpage and created an upload form to give the user the possiblity to upload a profil picture.

    def update(conn, %{"id" => id, "user" => %{"photo" => file}}) do
     if(File.exists?(file.path)) do

     case File.read(file.path) do
      {:ok, body}      -> data = IO.iodata_to_binary(body)
                          changeset = Whiteboard.File.changeset(%Whiteboard.File{}, %{user_id: currentuser.id, name: file.filename , data: data})

so that works and the binary data is in the database as bytea/binary.

Now my question: How do I render the binary data in the phoenix html.eex file to show the image again?

edit: found one solution

def render("image.html", %{:height => height, :width => width, :data =>   data, :datatype => datatype}) do
  pic = Base.encode64(data)

Phoenix.HTML.raw("<img src=\"data:image/"<>datatype<>";base64,"<>pic<>"\" height=\""<>height<>"\" width=\""<>width<>"\">")

end
murphy1312
  • 553
  • 9
  • 18

1 Answers1

3

While browsers support adding base64 image URLs, I would suggest that you take the traditional approach that caches can use more easily, and create a new Phoenix route that serves up the image.

To do this, you simply need to emit the correct mime type header and instead of rendering a template you simply place the contents of the column into the connection directly.

You should probably inspect the first few bytes to see if it matches a whitelist of known formats. You can search for what these bytes are here: http://www.garykessler.net/library/file_sigs.html

asonge
  • 1,259
  • 9
  • 10
  • So the advantages would be in performance - cache? Can you give me an example, how to do it this way? (sry i only work 2 weeks with phoenix/elixir) – murphy1312 Feb 14 '16 at 13:30
  • 1
    I'm just talking about normal HTTP caching. If you use other pieces of information to describe when the last time that file changed was or use an etag, clients could cache that image, and you could reduce your bandwidth usage. I wouldn't worry about it at first. – asonge Feb 14 '16 at 13:39