An Image manipulation service for Google App Engine. Also contains a drop-in replacement for ImageScience
Switch branches/tags
Nothing to show
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Failed to load latest commit information.


Image Manipulation on Google app Engine

Image-GAE is a library that wraps google's ImageService. It is intented for usage on Google App engine with JRuby.


Just copy all the files to your app, make sure warbler includes them and then simply require image-gae.rb


Use it like this:

image ='public/clown.jpg')
image.to_s   #or  
# => "data string"

You can also make a new Image object by simply passing a data string

@image ="data string")

Currently all of google's image manipulation methods except for composite images. This means you can rotate, resize, crop and flip your images. The syntax for this is really straigthforward

image ="data string")


image.flip   #flips horizontal
image.flip(:horizontal) #default



#Bonus method from google that tries to enhance colour

The power lies in chaining the methods:'public/clown.jpg').resize(100,100).rotate(90).flip.to_s


Maby you feel that learning yet another image manipulation syntax is cumbersome. I can hardly imagine that because syntax is really simple. Anyway, people have numerous reasons to stick to old syntaxes. The most compelling argument is not having to rewrite code for something like GAE. The easier it is for people to port their app to GAe the more usefull it will be. That is why I also included a simple drop-in interface for ImageScience

require 'legacy/imagescience.rb'
include GAE::Legacy

ImageScience.with_image('public/clown.jpg') do |img|
  img.cropped_thumbnail(100) do |thumb|
    return thumb.to_s

All the methods of ImageScience are supported. It should behave exactly like ImageScience does. There is however 1 slight problem. Google Engine app's cannot write files to the filesytem. This means that the following will never work.

ImageScience.with_image('public/clown.jpg') do |img|
  img.cropped_thumbnail(100) do |thumb|'public/clown_thumb.jpg')

To overcome this I simply added a .to_s method that returns the image data as a String. You can then either directly return this data, memcache it or store it through google DataStore.

I understand that this still means you have to modify code. If you still want minimal effort porting your code I suggest you monkeypatch the class and add save yourself. Then you can store it the way you want(probably DataStore).

But both of these approaches leave you with a problem if you want manipulate an image that you didn't include with your deploy. For example a user uploaded image or a previously modified image. You cannot simply write it to a tempfile and then open them with ImageScience.with_image. To overcome this problem I added a simple with_image variation called with_image_data. You just use it like this:

ImageScience.with_image('public/clown.jpg') do |img|
  @datastring = img.to_s
#Or get your @datastring from DataStore, Memcache or post/put params
ImageScience.with_image_data(@datastring) do |img|
  img.cropped_thumbnail(100) do |thumb|
    # => Jeeh, another datastring let's store it safely!

I realize this still means you need you sometimes have to do quite a lot of work to make it work. I personally think this is not a big problem as it gives your app quite some advantages. For example it becomes much easier to scale to app(That is the actual reason why you cannot write to filesystem). If you wanted to scale your app with amazon for example you also need to modify your code cause you probably want to send your images to S3.

If you still feel that modifying your code is to much of a trouble perhaps the google app engine is just nothing for you. But ofcourse you can also MonkeyPatch ruby File class and use Datastore as a virtual filesystem. That would be quite a cool project, you can let search the datastore first and then the read-only harddisk (to simulate file overwriting) You can Cache things with memcache(If that makes it faster). When you are done drop me a note will you?


Created by Bas Wilbers

Released under the ruby licence