Display an image received as Tempfile

I’m stuck with the image display in a rails template. I’m getting it from an API as Tempfile and already tried different ways, but still no success. So in a controller the show action looks like this:

def show
  @qrcode = QrcodeService.call(some_id)
end

The result I’m getting in the above action looks like that:

[#<Tempfile:/var/folders/9n/gymcxgn13cjfgs1m8qj41z300000gn/T/download-20210115-4214-1rvb28j (closed)>, 200, ...]

I tried to do that using a custom helper method defined in ApplicationHelper:

def qrcode_preview(qrcode)
    if qrcode[1] == 200
      "<img src='data:image/png;base64,#{Base64.encode64(qrcode.first.read)}'>".html_safe
    else
      '<b>Image not yet ready</b>'
    end
  end

and use in the view:

<%= qrcode_preview(@qrcode) %>

but it fails with:

ActionView::Template::Error (closed stream):
    1: <h2 class="ml-4 text-2xl uppercase">Scan me to sign in</h2>
    2: <%= qrcode_preview(@qrcode) %>

Any idea? Thank you.

I think to have found the answer :slight_smile:

# application_helper.rb

def qrcode_preview(qrcode)
    if qrcode[1] == 200
      data = File.read(qrcode.first) # to get the Tempfile from the response array
      "<img src='data:image/png;base64,#{Base64.encode64(data)}'>".html_safe
    else
      '<b>Image not yet ready</b>'
    end
  end

Then display it in the view template:

<%= qrcode_preview(@qrcode) %>

I think if you haven’t submitted the form it hasn’t been uploaded yet.

In this case, you can show the image that is still in the browser.

It would be something like this:

function readURL(input) {
  if (input.files && input.files[0]) {
    var reader = new FileReader();
    
    reader.onload = function(e) {
      $('#blah').attr('src', e.target.result);
    }
    
    reader.readAsDataURL(input.files[0]); // convert to base64 string
  }
}

$("#imgInp").change(function() {
  readURL(this);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form runat="server">
  <input type='file' id="imgInp" />
  <img id="blah" src="#" alt="your image" />
</form>