Welcome toVigges Developer Community-Open, Learning,Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
551 views
in Technique[技术] by (71.8m points)

Rails 6: how use send_data to display a binary image and apply styles

I'm getting an image file as binary data in a controller action:

  def show
    @result = QrcodeService.call(id)

    send_data @result.body, type: 'image/png', disposition: 'inline'
  end

The QrCodeService is just calling an external API to get an image using httparty gem.

The corresponding view template is defines as follows:

<h2>Scan Me</h2>
<%= image_tag @result %>

The problem is that the fetched images is displayed bu there are no styles, - the background is just black:

<body style="margin: 0px; background: #0e0e0e; height: 100%" data-new-gr-c-s-check-loaded="14.991.0" data-gr-ext-installed=""><img style="-webkit-user-select: none;margin: auto;" src="http://localhost:3000/qrcode"></body>

Even if I remove the call to <%= image_tag @result %> the <h2>Scan Me</h2> is not displayed either. What's wrong with the use of send_data? It seems like the method replace completely the body content? I have nothing at all on the page, just the image...

More of that, when looking at the logs in the console, there the same requests hit twice to get the image:

Started GET "/qrcode" for 127.0.0.1 at 2021-01-12 10:31:33 +0100
Processing by QrcodeController#show as HTML
  Rendering text template
  Rendered text template (Duration: 0.0ms | Allocations: 1)
Sent data  (0.5ms)
Completed 200 OK in 374ms (Views: 0.3ms | ActiveRecord: 0.0ms | Allocations: 2116)


Started GET "/qrcode" for 127.0.0.1 at 2021-01-12 10:31:33 +0100
Processing by QrcodeController#show as HTML
  Rendering text template
  Rendered text template (Duration: 0.0ms | Allocations: 1)
Sent data  (1.0ms)
Completed 200 OK in 319ms (Views: 0.8ms | ActiveRecord: 0.0ms | Allocations: 2126)

and when you try to navigate back in the browser with its navigation buttons, the URL in the URI field changes but not the page content.

How is it possible to display an image fetched as binary data and keep/apply the CSS styles?


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

I was inspired by the answer provided by Anna and replace the use of send_data in the controller with the instance variable as follows:

def show
    @result = QrcodeService.call(server_id)
end

Then create a helper method in ApplicationHelper class:

  def qrcode_preview(blob)
    if blob.code == 200
      ('<img src="data:image/jpg;base64,%s">' % Base64.encode64(blob)).html_safe 
    else
      '<b>Image not yet ready</b>'
    end
  end

Sure, it can be modified as you want (styles, text, etc.). And, finally use the helper method in the show view template as follows:

<h2>Your QR Code to sign in</h2>
<%= qrcode_preview(@result) %>

Voilà.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to Vigges Developer Community for programmer and developer-Open, Learning and Share
...