Quantcast
Channel: Technology & Process Solutions
Viewing all articles
Browse latest Browse all 5

Rails Image Editor

0
0

 

INTRODUCTION
Rails Ajax Image Editor is an ajaxified application for image manipulation using Rails technologies. This application has been derived from Peter Frueh (http://www.ajaxprogrammer.com) which originally existed in PHP. The PHP application has been modified to support Rails framework by Heurion Consulting (http://www.heurionconsulting.com) for the benefit of the Rails programmers to extend this application.
The original application is available at
http://ajaxian.com/archives/open-source-php-based-ajax-image-editor for use
The features supported by this application are:
  • Loading an temporary image (which already exists in our server)
  • Perform Image cropping (using a crop area)
  • Perform Image Resize (with and without constraints)
  • Perform Rotation (90 degrees CW and CCW )
  • Save image
  • View Saved image
  • View Original Image
TECHNOLOGY
This application has been built by and for Ruby on Rails Technology enthusiasts and also involves the following technologies:
  • Ajax for postback activity
  • JSON(JavaScript object notation) for updating JavaScript image
  • Rmagick for the image manipulation.
CREDITS
We would like to credit Mr. Peter Frueh (http://www.ajaxprogrammer.com) for having developed this application and also providing us the opportunity to modify the code to suit the Ruby on Rails needs.
All credits of Java Script and CSS code belongs to Peter where as all Code of Ajaxification and Ruby on Rails Codes shall belong to Heurion Consulting (http://www.heurionconsulting.com).
This code is under LGPL license and you are allowed to do any modifications or extension to this code to suit your requirements. However you are not allowed to change the credits of either Mr. Peter Frueh (http://www.ajaxprogrammer.com) or Heurion Consulting (http://www.heurionconsulting.com) and they shall remain always.
This library is free software. You can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.

DOWNLOAD AND SETUP
  • Currently the wordpress does not give the option to download the Zip file. To receive the source code, please send an E-Mail to info@heurionconsulting.com
  • Unzip the source file to a suitable location
  • Run “ruby script/server” (for windows) or ./script/server (for others)

Code Walkthrough
The main parts of the application are javascripts and the ruby controller. The notable files are explained as follows:
  • ImageEditor.js – Contains all the code that is necessary to do the image manipulations activity and also to send the post back to the server. This code uses Ajax.Request method to send data to the server. Also the Response is a JSON object which is used to update the client JavaScript image object.
  • PageInfo.js – Helper code for tracking mouse position, used to provide JavaScript Crop border.
  • Imagecontroller_controller.rb – Contains all server code where image manipulation is performed using RMagick and the resulting images are stored and picked from the respective (edit / active / original) folders.
Image Editor JavaScript uses Ajax.Request object to send all the information required for the modification of the image to the server. Along with the request all the parameters that are required to perform necessary image manipulation are sent. Once the server performs the operation and sends back the new results they are cached and the image is updated using JSON.
newAjax.Request(‘/imagecontroller/processImage’, {
synchronous:true, onSuccess: function(request) { if (request.readyState == 4 { var json = eval(“(” + request.responseText + “)”); if (json.imageFound) { ImageEditor.imageName = json.imageName; ImageEditor.w = json.w
ImageEditor.h = json.h; ImageEditor.loaderImage.setAttribute(“src”, “/images/edit/”+json.imageName); } else { document.getElementById(“ImageEditorImage”)
.innerHTML = ‘<span style=”font- size:12px;
color:red;”> Image was not found.</span>’; }
}
},parameters:”imageName=” + ImageEditor.imageName + ((args) ? “&” + args : “”)
})
JSON(Java Script Object Notation) allows us to represent complex objects in a format that can be easily parsed by the JavaScript interpreter. Once parsed, these objects can be interacted with ordinary JavaScript objects, with much less overhead than their XML counterparts. The downside of using JSON is that it is only understood by JavaScript interpreters, and therefore few server-side systems will have the ability to speak JSON easily. Thus, generating the data on the server will typically involve more overhead. Whichever format of data we choose, adopting a data-centric approach will require us to write some extra code to parse the response and decide what to do with it. Once the data to do the image manipulation is transferred in to the server we can utilize the RMagick supported by Ruby to perform operations of the image.
P.S: After each operation we save the image into a new name so that the new name is recognized by the html image tag and resets / updates to the new image.
Henceforth on every modification we add a time stamp to the image name differentiates the old image with the new image.
Part A: Initial Preperations
Before implementing the image, we have to setup initial preparations which are required to do the rest of the image operation. Some of them are identifying active / edit/ original directories, identifying the old and new image names. The following code snippets provides insight about each operation achieved inside the controller:
Code Snippet:
#Registering rmagick
Either in the environment.rb file or on the start of the controller / model you can register the rmagick by using
require ‘rmagick’
#Create the directories
originalDirectory = “#{RAILS_ROOT}/public/images/original/” activeDirectory = “#{RAILS_ROOT}/public/images/active/” editDirectory = “#{RAILS_ROOT}/public/images/edit/”
#Identify the original Image name
imageName = ‘parrots.jpg’
#Prepare the new image name
extn = imageName.split(‘.’).last
newimagename = imageName.gsub(/.jpg/,”)
#new image name
@image2Name = newimagename +”_”+ Time.now.to_i.to_s+”.”+extn
#identify what action to be performed
action = params[:actiontype]
Part B: Final Preperations
Once the images are ready and saved we have to update the javascript with these images. The controller shall get all information of the processed image and sends it to its corresponding view to prepare the JSON object.
Code Snippet:
Controller
#check if the new image is saved, if not then replace the old image name to be the #new image. This occurs for View original and view active cases.
unless File.exists?(File.join(editDirectory,@image2Name))
@image2Name = imageName
end
#get the image and it positions and serialize them to the view
img = with_image()
@w= img.columns
@h= img.rows
View
{imageFound:true,imageName:”<%= @image2Name %>”,x:<%= @x %>,y:<%= @y %>,w:<%= @w %>,h:
<%= @h %>}
JSON Variables
  • ImageFound : Boolean test that the view was called
  • ImageName: Holds the new image name
  • X: top left- x position of the new image
  • Y: top left – y position of the new image
  • W: width of the new image
  • H: height of the new image
Part C: Performing Operations (the mid part)
a) View Original
# copies the image from original directory to edit directory to show the image from the edit directory
FileUtils.cp(originalDirectory+imageName, editDirectory+imageName)
b) View Active
# copies the image from active directory to edit directory to show the image from
# the edit directory
FileUtils.cp(activeDirectory+imageName, editDirectory+@image2Name)
c) Save as Active
img = with_image()
# saving the image with the time stamp in edit directory
save_image(img,@image2Name)
# writing that image in active directory
img.write(File.join(“#{RAILS_ROOT}
/public/images/active/parrots.jpg”))
d) Resize
out_w= params[:w].to_i
out_h = params[:h].to_i
img = with_image()
# resizing the image by the given dimensions
img = img.resize(out_w,out_h)
#saving the resized image to active folder
save_image(img,@image2Name)
e) Crop
@x = params[:x].to_i
@y = params[:y].to_i
@w = params[:w].to_i
@h = params[:h].to_i
img = with_image()
unless @w == 0 or @h == 0
# cropping the image by its x and y postions with width and height
img = img.crop(@x,@y,@w,@h)
end
# saving the croped image to active folder
save_image(img,@image2Name)
f) Rotate
degrees = params[:degrees].to_i
img = with_image()
# rotaing the image by particular degrees
img=img.rotate!(degrees)
# saving the rotated image to active folder
save_image(img,@image2Name)

EXTENSIONS TO CODE
  • In this application the image shown in the browser is already in the server. We are taking a single image and modifying around it. We can extend this application by loading user images by using any standard upload methodology. One of the notable Ajax upload feature is what is available in the photo gallery application available in the book “Ajax on Rails” by O’reilly Publications. The code for uploading files from client side is:

<div class=”upload_container”>
<% form_for :photo, Photo.new,
:url => photos_url(:usertemplate_id => @usertemplate),
:html => { :multipart => true, :target => “uploader”,
:id => “photo_upload” } do |f| %>
<%= f.file_field :file, :size=>”17″ %><br />
<%= submit_tag “Upload”,:onClick => “Photo.upload();” %>
<%= hidden_field_tag “photo_id”, photoposition %>
<% end %>
</div>

  • In this application we are currently providing editing the image by crop, resize and rotate using Rmagick. Image rotation is done for 90 degrees clockwise and anticlockwise directions only. We can extend this application by rotating the image in any degrees by Rmagick.
img = Magick::Image::read(File.join(Directory,file)).first
img.rotate!(degrees)
P.S: Note when you are rotating the image, background changes into whitespace. It can be removed by Rmagick img.matte_floodfill(x,y) concept. (Not supported in IE6)
  • In this application we are currently resizing the image by giving values in the text. We can extend this application by using grips on the edges of image instead of using text. We can resize the image by dragging the grips in and out.

- HEURION CONSULTING INFORMATION RELEASE



Viewing all articles
Browse latest Browse all 5

Latest Images

Trending Articles





Latest Images