0
votes

I have a rails app and I am receiving a base64 encoded string that is an image from an ios app.

I am trying to convert it to a paperclip image.

So far I have:

module Api
    module V1
        class MyController < BaseController
            def image_build 
                begin
                   token = request.headers["HTTP_TOKEN"]
                   @user = User.find_by(user_token: token)
                   @decoded_image = Base64.decode64(params[:image_data])
                   puts @decoded_image[0, 50]
                   @new_stand = Stand.create(:user_id => @user.id, :avatar => @decoded_image)
                   ...

which outputs:

iVBORw0KGgoAAAANSUhEUgAAAPsAAACxCAYAAAACscusAAAAAX
�PNG

IHDR��ˬsRGB���  
Completed 500 Internal Server Error in 90ms (Views: 3.1ms | ActiveRecord: 1.1ms)

How do I convert the base64 string to a proper image file in rails? I have paperclip running from this gem:

gem "paperclip", git: "git://github.com/thoughtbot/paperclip.git"

Notes

The images sent over can be any image from an ios phone so the type can change. I would like to support .gif, .png, .jpg, and jpeg.

In IOS I send over the information like this:

@IBOutlet var image: UIImage
@IBAction func Build(sender: AnyObject) {
    let image_data = UIImagePNGRepresentation(image.image!)
    self.service.createNewImage(notifier: notifier, image: image_data!)
}

then


let strBase64:String = image.base64EncodedStringWithOptions(.Encoding64CharacterLineLength)
let dataDictionary = ["image_data": strBase64]
self.post("image/build", data: dataDictionary).responseJSON

EDIT 1

I have started to attempt to use the paperclip io adapters but it still errors out. This is what I have so far:

                @new_image = Stand.create(:user_id => @user.id)
                encoded_picture = params[:image_data]
                content_type = "image/jpg"
                puts "HERE 1"
                image = Paperclip.io_adapters.for("data:#{content_type};base64,#{encoded_picture}")
                puts "HERE 2"
                image.original_filename = "new_image.jpg"
                puts "HERE 3"
                @new_image.avatar = image
                puts "HERE 4"

                @new_image.cover_image_url = @new_image.avatar.url
                puts "HERE 5"
                @new_image.save

This code gives these errors:

HERE 1
HERE 2
HERE 3
Command :: file -b --mime '/tmp/082995477845923f853c5a48cc6e3cae20160712-26217-s1dngb.jpg'
Command :: identify -format '%wx%h,%[exif:orientation]' '/tmp/8d777f385d3dfec8815d20f7496026dc20160712-26217-1ht7ijm[0]' 2>/dev/null
Command :: identify -format %m '/tmp/8d777f385d3dfec8815d20f7496026dc20160712-26217-1ht7ijm[0]'
Command :: convert '/tmp/8d777f385d3dfec8815d20f7496026dc20160712-26217-1ht7ijm[0]' -auto-orient -resize "160x160>" '/tmp/4a98b13d8ce55141b173bb0ed5cb181220160712-26217-17sazsk'
Command :: identify -format '%wx%h,%[exif:orientation]' '/tmp/8d777f385d3dfec8815d20f7496026dc20160712-26217-1ht7ijm[0]' 2>/dev/null
Command :: identify -format %m '/tmp/8d777f385d3dfec8815d20f7496026dc20160712-26217-1ht7ijm[0]'
Command :: convert '/tmp/8d777f385d3dfec8815d20f7496026dc20160712-26217-1ht7ijm[0]' -auto-orient -resize "40x40>" '/tmp/4a98b13d8ce55141b173bb0ed5cb181220160712-26217-fhdb0w'
HERE 4
Completed 500 Internal Server Error in 654ms (Views: 2.5ms | Searchkick: 15.6ms | ActiveRecord: 7.3ms)
2

2 Answers

1
votes

A lot of useful information you can found in paperclip's repository, for your question i found this:

3.5.0:

  • Feature: Handle Base64-encoded data URIs as uploads

Paperclip::DataUriAdapter handles base64-encoded data.

Just works:

class Photo < ActiveRecord::Base

  before_validation :set_image

  has_attached_file :image

  def set_image
    StringIO.open(Base64.decode64(image_json)) do |str|
      decorate_str(str)
      str.original_filename = "THE_NAME_OF_FILE.jpg"
      str.content_type = "image/jpeg"
      self.image = data
    end
  end

  def decorate_str(str)
    str.class.class_eval { attr_accessor :original_filename, :content_type }
  end

end

Similar way to solve your problem is here.

Paperclip's changelog

0
votes

This seems to work, but I am still working on testing differing image types.

@new_image = Stand.create(:user_id => @user.id)
encoded_picture = params[:image_data]
content_type = "image/jpg"
image = Paperclip.io_adapters.for("data:#{content_type};base64,#{encoded_picture}")
image.original_filename = "new_image.jpg"
@new_image.avatar = image
@new_image.save
@new_image.cover_image_url = @new_image.avatar.url
@new_image.save

I have upvoted the previous answer because it helped me find other resources, but it does not contain an answer for my scenario.