Flex Image now has special effects
October 26th, 2006
This information is now old. A new version of the plugin can be found here with lots of instructions and examples.
A bunch of super useful image processing functions has been added to the FlexImage toolbox. Now it can do more than just resize and crop an image. FlexImage now has the ability to add borders, shadows, and overlays.
|
=> | |
Update or install:
ruby script/plugin install http://beautifulpixel.com/svn/plugins/flex_image
For full documentation see the rdoc
But for the eager and impatient, here are some examples. They are posted along with the controller code that generated them.
(The sample image here is me boarding a train in Paris from my recent vacation.)
Simple resize.

flex_image :action => 'show',
:class => MyImage,
:size => 200
Resize with crop and a drop shadow.

flex_image :action => 'show',
:class => MyImage,
:size => 200,
:crop => true,
:shadow => true
Stick a logo in the corner.

flex_image :action => 'show',
:class => MyImage,
:size => 200,
:overlay => {
:file => 'public/images/overlays/logo.png',
:alignment => :bottom_right,
:offset => 5,
}
Add a funky border.

flex_image :action => 'show',
:class => MyImage,
:size => 200,
:overlay => {
:file => 'public/images/overlays/border.png',
:size => :stretch_to_fit,
}
Add a white border and a blue drop shadow on an orange background.

flex_image :action => 'show',
:class => MyImage,
:size => 200,
:border => {
:size => 10,
:color => 'white'
},
:shadow => {
:blur => 20,
:offset => 8,
:background => color(255, 128, 0),
:color => color(0, 0, 255),
:opacity => 1
}
Mix it all together with a custom tailored action.

def show
image = MyImage.find(params[:id])
image.resize!(:size => 200)
image.overlay!(
:file => 'public/images/overlays/logo.png',
:alignment => :bottom_right,
:offset => 5
)
colors = %w( white red orange yellow green blue indigo violet )
colors.reverse.each do |a_color|
image.border!(
:width => 10,
:color => a_color
)
end
image.overlay!(
:file => 'public/images/overlays/watermark.png',
:size => :scale_to_fit
)
image.shadow!
render_flex_image(image)
end
39 Responses to “Flex Image now has special effects”
Sorry, comments are closed for this article.
June 28th, 2007 at 11:05 PM
Wow.. the new update is absolutely cool! Thank you!
June 28th, 2007 at 11:05 PM
I was wondering if it might be possible to add a crop! method to allow direct image cropping without resizing.
I’ve got an uploaded image that I would like to store in the database, and process when displayed. Between the upload and display, an admin type would select the coordinates and size to crop the image. Then before display, the image would be cropped, then the cropped image would be resized.
Similar to the code below:
I added the following to the model.rb, but since i’ve got it set up as an external, I can’t commit the changes, nor migrate it to my dev site. I’d like to keep the plugin as an external, so I was wondering if you could add this in some form in the official version (after making sure it works… :)
June 28th, 2007 at 11:05 PM
Heh. I just realized I can just stick that code directly into my model…
Either way, it might be helpful for other people to be able to crop with specific coordinates.
June 28th, 2007 at 11:05 PM
I have added a crop! method
I did chang the API around a bit to specify
:fromand:sizebut used your code as a base. Thanks for the contribution.If anyone else has ideas for features, just voice up and let me know. Or even better, post the method here.
June 28th, 2007 at 11:05 PM
It seems your moving the code into a separate section has caused a bunch of method_missing errors.
I can’t call resize! or crop! on my model anymore.
June 28th, 2007 at 11:05 PM
I should clarify. My functional tests work fine, and the controller actions are properly working in those tests, but when I try to view an image in the real world, I get the undefined method error for resize! and crop!, which is strange.
I’ve added my email address into the top here, if you need me to send along some code.
June 28th, 2007 at 11:05 PM
I had this problem before with rails development class reloading. It doesn’t always reload the right files. And worst of all, it never happened to me.
I moved the require line to inside the
FlexImage::Modelclass. Please let me know if that fixed it for you.June 28th, 2007 at 11:05 PM
It would be great if overlay could take an in-memory image. For example:
June 28th, 2007 at 11:05 PM
You got it.
overlay!now takes:fileor:image.This:
is now the exact same as:
image.overlay! :image => Magick::Image.read('foo/bar.jpg').firstJune 28th, 2007 at 11:05 PM
Flex Image is just great, thank you very much for this easy to use and fun plugin!
The one problem that I have, is that larger images are sometimes only partially uploaded (like http://www.minga.de/product_images/show/78.png?). My system is running on a mongrel server and I use the pre_process_image. Does anybody have similar problems or know where to look to get this fixed?
June 28th, 2007 at 11:05 PM
I have seen once or twice before because I aborted the upload by closing the loading browser tab or something. If it’s happening with no interference, than I am not sure what to tell you.
I use mongrel on windows in development, and have not noticed this. And Lighttpd on Linux works fine as well.
Sorry I can’t be more help.
June 28th, 2007 at 11:05 PM
Disclaimer: I am supplementing my JavaEE skills with rails and am a complete noob.
Ok So I have a site I would like to have advert banner administration done with. So fleximage sounds perfect. But in my ignorance I can’t seem to get it to display.
Herre is my sqlmy modelview<%=h @adverts.send(column.name) %> <%= image_tag url_for(:controller => 'admin', :action => 'show', :id => @adverts) %>I can only assume I am missing something glaring.
Thanks in advance
June 28th, 2007 at 11:05 PM
Matt: Do you have a controller action to display the images? Your image tag has to have the url for an action that renders your image.
#controller class AdminController < ActionController::Base def image @advert = Adverts.find(params[:id]) end end #app/views/admin/image.flexi @image.resize! :size => '640x480'Now you can call up this image with:
June 28th, 2007 at 11:05 PM
Sqlite doesn’t seem to like MEDIUBLOB. And with filesystem storage Fleximage wants to save Nil as data attribute wich causes errors if the ’:null=>false’ part is used in the migration. At least with sqlite.
Other than this: FANTASTIC! This is sooo coool! Thank you!
June 28th, 2007 at 11:05 PM
Sadly, I have never used sqlite. If anyone can provide the migration format or sql to make it work with sqlite, I will update the generators in the plugin.
Basically it just needs to a binary column of sufficient size. In MySQL that is a medium blob.
Sorry I can’t be more help.
June 28th, 2007 at 11:05 PM
First of all, thanks for this great plugin! It does a great job.
Recently, I discovered that some of my thumbnails have big file sizes. With big I mean 120×120 thumbnails with a 75 quality setting. I googled for a while and discovered that ImageMagick’s “convert” program has an -thumbnail option.
I tested it and it produced 3-4 kB images, whereas my web application produced 30-40 kB images from the very same file.
Then I found out that -thumbnail was setting an internal flag, -strip for producing thumbnails. This was the answer.
I modified my local copy of flex_image, and add the following line in “data” method of model.rb:
And this solved the big sized thumbnails problem. A quick hack, but may help others experiencing same problem.
June 28th, 2007 at 11:05 PM
And that can really reduce the final filesize by 90%? Does it look as good? Does it work for large images as well? If so, I will definitely stick that into the trunk.
I guess I should investigate this.
June 28th, 2007 at 11:05 PM
I did add this into the plugin. Now
strip!is called at the final stage of rendering the image. At the very least it doesn;t seem to hurt anything.June 28th, 2007 at 11:05 PM
JPEG files, like other image files have the ability to carry meta information about the image, such as, camera make and model that captured the image, date and time that the image was captured at, etc. These meta data can be large compared to the image file size, especially if the image is small.
Take a look at the following. First one is the original unstripped version. It is about 41 kB in size. Latter one is the stripped version, which is visually same as the first one, but only 13 kB in size. You can view metadata with most of the image software, the most available one is Windows Explorer (right click -> Properties)
http://www.tugayoglu.com/images/unstripped.jpg http://www.tugayoglu.com/images/stripped.jpg
Without
strip!ImageMagick (and thus RMagick) produces resized images which carry the same meta data as the original one. This is not a problem for big file sizes, but if your page contains many tiny images (such as thumbnails) this may be a problem.Regards, Ferit
June 28th, 2007 at 11:05 PM
I learn new things every day! Thanks for the tip. As long as it looks the same it’s definitely not worth that extra bandwidth.
June 28th, 2007 at 11:05 PM
Hi Alex, I’m just starting out in the world of RubyRails and am having an issue with syntax. Basically I am getting the following error message:
undefined method `data' for class `Stockimagestbl' #{RAILS_ROOT}/vendor/plugins/flex_image/lib/flex_image/model.rb:71:in `alias_method' #{RAILS_ROOT}/vendor/plugins/flex_image/lib/flex_image/model.rb:71:in `binary_column' #{RAILS_ROOT}/app/models/stockimagestbl.rb:4 #{RAILS_ROOT}/app/controllers/unregistered_controller.rb:21:in `artist'My code is as follows:
Controller: View:Map: class Stockimagestbl < FlexImage::Model set_primary_key "item_code" belongs_to :stocktbl, :foreign_key => "stock_id" binary_column :item_photo end<%= image_tag url_for(:controller => 'unregistered', :action => 'artist', :id => @artistImage) %>My postgreSQL (8.2) table (Stockimagestbl) structure is comprised of the following columns:
What am I overlooking here?
— Regards
Andrew
June 28th, 2007 at 11:05 PM
Hi, I seem to be getting somewhere! In my Model I have commented out:
binary_column :item_photo
My controller reads as:
@artistImage = Stockimagestbl.find("2221bc21-0ce2-11db-abe1-000c6e65312d")My view reads as:
<%= image_tag url_for(:controller => 'unregistered', :action => 'artist', :id => @artistImage) %>What is being rendered in the browser is:
That’s right! Because I cannot specify the binary column in my model, it is now rendering the primary key value!!!
To be honest I am also still not sure about:
#app/views/admin/image.flexi @artistImage.resize! :size => '65x65'What is .flexi view?! Where does it live, how do I create one? I tried to specify a :size in the image_tag url_for tag, but the image size remained the same.
Also, does ActiveRecord cache these image dB calls? If not, how do I go about ensuring that it does?
— Regards
Andrew
June 28th, 2007 at 11:05 PM
Hi Alex, I am still having an issue with:
binary_column :myColumn_name
Even though I have added a ‘data’ column of type bytea (postgreSQL 8.2) to my table stockimagestbl, I am still getting the following error message:
“undefined method ‘data’ for class ‘Stockimagestbl’ “
What is the issue here?
— Regards
Andrew
June 28th, 2007 at 11:05 PM
Hi Alex, the situation as it currently stand is this:
1. I have deleted the extra data column from my database table and renamed the existing binary column to ‘data’.
2. I have completely removed binary_column from my code.
A .png image is now being rendered to the browser but it is not the binary image, instead it is the actual primary key used to search for the required image which is itself being rendered as an image!!
Why is the binary information not being read from the table?
— Regards
Andrew
June 28th, 2007 at 11:05 PM
Hi, still no joy! In my routes.rb I have specified the following:
In my controller I have specified the following:
In my model I have specified the following:
class Stockimagestbl < FlexImage::Model set_primary_key “item_code” belongs_to :stocktbl, :foreign_key => “stock_id”
end
And in my view I specified:
<%= image_tag url_for(:controller => ‘unregistered’, :action => ‘artist’, :id => @artistImage, :size => ‘65×65’ ) %>
I now get the following rendered in the browser:
But still the binary information already held in the ‘data’ column is not being rendered to the browser. HELP!!!
— Regards
Andrew
June 28th, 2007 at 11:05 PM
It sounds like everything should be hooked up ok. Remember that you don’t render the image data directly inside an HTML page. You render an image tag, and the browser then makes another request for the image. Go to the URL in your image tag and you should see some sort of error if something went wrong, and you should see the image if it works.
So what happens when you go the image url?
June 28th, 2007 at 11:05 PM
As for
.flexiviews, it’s simple. Let’s say you have an action calledshow_image. Normally, rails would rendershow_image.rhtml, but if you have ashow_image.flexiinstead it will render that. In this view file process your image. Do your resizes or whatever else you like. The result will be rendered out as image data.June 28th, 2007 at 11:05 PM
Is it possible to save a thumbnail in the database so it doesnt have to convert it everytime?
June 28th, 2007 at 11:05 PM
I would love to use your plug-in, but the model requires the deprecated form_tag in Rails 1.2, which will break in Rails 2.0.
(from Mongrel log file) “DEPRECATION WARNING: end_form_tag is deprecated and will be removed from Rails 2.0”
(from rubyonrails.org/deprecation) “start_form_tag and end_form_tag Use form_tag with a block.”
I am having trouble getting your model.rb file to recognize the multipart declaration in my form block.
Any suggestions?<% form_for(:photo, :url => {:action => 'upload'}, :html => {:multipart=>true}) do |photo| %> <b>Add a new Photo:</b> <%= photo.file_field("newphoto") %> <%= submit_tag 'Upload' %> <% end %>June 28th, 2007 at 11:05 PM
Saving the thumbnail is the DB is probably not the best option. Simply use
page_cachingon your thumbnail action and have it written to the disk. See the Rails docs for more on page caching.Ryan: You don’t need to use those old form tags. What you have written there should work fine. Just be sure that
params[:photo][:newphoto]is what your are sending the model for its data.July 8th, 2007 at 12:18 PM
Thanks for the multi-class fix. Works great.
A rotate method, or a rotate option in the resize method, would be a nice addition. Nothing too fancy, just a 90 degree left-right rotate method … would make it easy to do an action for users to rotate uploaded photos.
July 13th, 2007 at 09:36 PM
A rotate method would be handy, I agree. I would gladly accept a patch to add one :)
September 10th, 2007 at 12:46 AM
Hi
this is a wonderful plugin, thanks so much!
I just have one question. How do you resize the image such that it only one dimension is fixed?
for example, I want all my images to have 80px width but if i set :size => ‘80’ if the height > width, the height will be 80px and the width smaller.
September 10th, 2007 at 10:03 AM
@Jarrold:
There is no real way to fo that in the API right now. But you can use a workaround which is supply a very high vertical size that will never be reached.
@photo.resize! :size => '80x10000'This will only make the image less than 80 pizels wide of the height of the image is greater than 10,000 which would be highly unlikely.
September 10th, 2007 at 11:10 PM
Thanks for the fast reply!! why didn’t I think of that.
I’m now having another problem:
The crop seems not to be working.
September 11th, 2007 at 12:21 AM
my bad, i think my Rmagick version is outdated.
April 24th, 2008 at 07:20 AM
I’ve followed the walk-through on the [url=http://github.com/Squeegy/fleximage]fleximage github[/url] and it’s worked well except for one thing: The path to the image in show.rhtml.erb is not correct so the image does not display.
Below are all the relevant snippets.
models/post.rb: [code=] validates_presence_of :title acts_as_fleximage do image_directory ‘public/images/uploaded’ image_storage_format :png invalid_image_message ‘Image was not readable. Please try again.’ output_image_jpg_quality 85 end[/code] controllers/admin/posts_controller.rb: [code=] def show @post = Post.find(params[:id]) respond_to do |format| format.html # show.html.erb format.xml { render :xml => @post } end end[/code] views/admin/posts/show.html.erb: <%= image_tag formatted_post_path(@post, :png) %> %>[/code] views/admin/posts/show.jpg.flexi: do |image| image.resize 100 end[/code] routes.rb: [code=] map.root :controller => “posts”, :action => “index” # See how all your routes lay out with “rake routes” map.resources :posts, :has_many => :comments map.namespace :admin do |admin| admin.root :controller => “posts”, :action => “index” admin.resources :posts end[/code] I’m storing the files in the file system and the paths fleximage generates are like this: /images/uploaded/2008/4/24/12.pngThe directory is set with ‘image_directory’ as seen in the model below, but in show.html.erb the resulting image tag is, for example, ’/posts/12.png’
This obviously will not show the image. How do I get the image source correct for the image_tag? Do I do it in routes? What do I do with show.flexi.png? I read that rails simply will call show.flexi.png from the controller action show. So do I need to do something like:
controllers/admin/posts_controller.rb: show @post = Post.find(:all) respond_to do |format| format.flexi # I really have no idea what to do with this .flexi thing format.html # show.html.erb format.xml { render :xml => @post } end[/code]
April 24th, 2008 at 07:22 AM
I’ve followed the walk-through on the [url=http://github.com/Squeegy/fleximage]fleximage github[/url] and it’s worked well except for one thing: The path to the image in show.rhtml.erb is not correct so the image does not display.
Below are all the relevant snippets.
models/post.rb: [code=] validates_presence_of :title acts_as_fleximage do image_directory ‘public/images/uploaded’ image_storage_format :png invalid_image_message ‘Image was not readable. Please try again.’ output_image_jpg_quality 85 end[/code] controllers/admin/posts_controller.rb: [code=] def show @post = Post.find(params[:id]) respond_to do |format| format.html # show.html.erb format.xml { render :xml => @post } end end[/code] views/admin/posts/show.html.erb: <%= image_tag formatted_post_path(@post, :png) %> %>[/code] views/admin/posts/show.jpg.flexi: do |image| image.resize 100 end[/code]April 24th, 2008 at 11:39 PM
@Patrick:
This url /images/uploaded/2008/4/24/12.png is where your master uploaded image is stored. This is not the image your public sees. This is the base image that the plugin starts with, then renders the image as declared in your .flexi template, and makes that available at the URL /posts/12.png
The problem is that you have the template setup, as well as a respond_to block. respond_to overrides the rails automatic template format handling. So you either need to get rid of the respond_to block completely (letting your view template naming conventions sort out what to display via the name.requestformat.templatelanguage format), or add a line to respond to you respond_to block that allows the JPG (or PNG or GIF if you prefer) format to perform its default.
So this won’t work, because your template will be ignored:
But this will work, since rails will just look for the right template instead:
Or if you need the respond_to, this will work as well