Search code examples
ruby-on-railsrubygoogle-app-engineruby-on-rails-4google-cloud-vision

How to upload an image at url for Google Vision API - Ruby


How do I upload an S3 URL image properly for Google Vision?

I am attempting to send an image (saved at an AWS S3 URL) to Google Vision with Base64 encoding per the 2nd option in the documentation listed below:

Images sent to the Google Cloud Vision API can be supplied in two ways:

  1. Using Google Cloud Storage URIs of the form gs://bucketname/path/to/image_filename

  2. As image data sent within the JSON request. Because image data must be supplied as ASCII text, all image data should be escaped using base64 encoding.

I am using the Google-Cloud-Vision Gem.

I have tried this previous answer about Base64 encoding, with a minor modification:

require 'google/cloud/vision'
require 'base64'
require 'googleauth'
require 'open-uri'

encoded_image = Base64.strict_encode64(open(image_url, &:read))

@vision = Google::Cloud::Vision.new
image = @vision.image(encoded_image)
annotation = @vision.annotate(image, labels: true, text: true)

I have tried images at AWS URLs and images at other urls.

Every time I get this error from the Google-Cloud-Vision gem: ArgumentError: Unable to convert (my_base_64_encoded_image) to an image

Update - successfully encoded and decoded image in ruby only

I have confirmed that this code: encoded_image = Base64.strict_encode64(open(image_url, &:read)) works via the following:

# Using a random image from the interwebs
image_url = "https://storage.googleapis.com/gweb-uniblog-publish-prod/static/blog/images/google-200x200.7714256da16f.png"
encoded_image = Base64.strict_encode64(open(image_url, &:read))

### now try to decode the encoded_image
File.open("my-new-image.jpg", "wb") do |file|
  file.write(Base64.strict_decode64(encoded_image))
end
### great success

So what's google's problem with this? I am properly encoded.


Solution

  • If you are going to use Google-Cloud-Vision gem, you need to follow the gem documentation (uses non encoded images), maybe he did that under the hood..

    Based on the documentation of the gem google-cloud-vision , you can convert your image like the code bellow

    open image_url do |img|
      @vision = Google::Cloud::Vision.new
    
      image = @vision.image(img)
      # you can also use the class method from_io
      # image = Google::Cloud::Vision::Image.from_io(img, @vision)
    
      annotation = @vision.annotate(image, labels: true, text: true)
    end