Search code examples
sinatraimagermagick

RMagick & Sinatra: send picture to view without storing


Currently I am writing a Sinatra app that gets some pictures from user and returns a new picture.

There's part of haml form:

  %input{type:'file', name:'user_image'}

And there's a code from handler: (montage is another picture)

  source_userpic = params[:user_image][:tempfile]
  blob = File.open(source_userpic).read
  userpic = ImageList.new
  userpic.from_blob(blob)
  resized_img = userpic.scale(montage.columns,
                              montage.rows)
  resized_img.opacity = MaxRGB/3

Then two images are "layered" with composite and stored (don't need)

  final_picture = ImageList.new
  final_picture << montage.composite(resized_img, 0, 0, OverCompositeOp)


  final_picture.write("./public/uploads/#{DateTime.now}.jpg" # dirty (for example)

Next, I need to show a final_picture with ajax. There are two obvious problems: first, I don't need to save a final_picture - it's just preview, second, I must write code to avoid filenames conflicts...

How to send a final_picture to view? to_blob method? But what's next?


Solution

  • I solved that by using the data URI scheme.

    require 'base64'
    
    final_picture.format = "jpeg" # whatever
    # Using a to_blob method to create a direct-to-memory version of the image.
    # Then encode it to base64 string
    data_uri = Base64.encode64(final_picture.to_blob).gsub(/\n/, "") 
    @image_tag = '<img alt="preview" src="data:image/jpeg;base64,%s">' % data_uri
    
    haml:'pages/preview'
    

    Then display a picture by

    = @image_tag
    

    Not sure if it's best solution