You ever make something, and then look back a few years later and say “What the hell was I thinking”? This happened to me recently. Fleximage has been quite a useful plugin for me, but under the hood it was a mess; the API was cumbersome, and mixing in all the image transformations as direct model methods was code smell.

This release represents the 3rd complete rewrite of this code base. The first effort was SuperImage. It worked, but it happened almost entirely in the controller and made more interesting effects harder. The first Fleximage was next introducing more tranformations and .flexi views and a good effort to making it more MVC friendly.

Get Fleximage v2 here

So I now present, Fleximage v2. The output is very similar, but the API and internals are completely different. Here’s some highlights.

  • Creation date based master image storage to prevent OS imposed directory limits. i.e. /path/to/images/2008/02/06/999.jpg
  • Rails 2 formatted resource route friendly
  • Magic columns to capture filename and image size
  • Image transformation methods are not injected into your model or controller at all.
  • Image operations now happen via Operator class that refactor each transformation into their own encapsulated class.
  • Easily output JPG, PNG, or GIF based on request format.
  • Simple acts_as_* style model activation rather than using a cumbersome inheritance method
  • Side by side file upload or URL fields for easy uploading.
  • Uploading will only ever replace you image file if the uploaded file actually has content, removing the need for “if file.size > 0” nonsense in your controller.
  • Rake tasks to convert from master image directory styles, as well as master image formats (jpg => png for instance)

And it’s all hosted on GitHib. It’s new, it’s awesome, and has extensive documentation in the attached Wiki.

Lastly, if you are using Fleximage in an existing production site, please add it on the WhoUsesFleximage page. I know you’re out there.

24 Responses to “Fleximage v2, now with more awesome”

  1. Mike Says:

    So, you decided to totally dump the DB stored images? Or, hopefully, the support will be added later? Any particular reason why it was removed?

    I use FlexImage on over 30+ sites I have built (sorry, , and all of them used DB storage for images, because this way I have easier workflow (I can move just DB from our development machine, where all the site information is actually entered before going public, and don’t worry about any images I have forgot). Also, I believe this approach is also less prone to data corruption.

    Not having DB storage supported is, honestly, a pretty big blow for me.. Hopefully it will be re-added.

    Anyways, congratulations on the release and keep up the good work!

  2. Alex Wayne Says:

    Perhaps as a sister plugin, but for most people it’s probably not the right choice.

    I have mixed feelings about it. And DB support is one thing that made the last version’s code so messy. I’m sure there is a solution here, but it hasn’t been tackled yet.

    Accepting patches :) Or if you have a github account, you can just fork me and work on your own version of the repo. Need an invite?

  3. Alex Wayne Says:

    By the way, I would love to know some of the sites you have that use Fleximage. Care to post them?

  4. Lucas Says:

    What columns are needed on DB? Can you post an example migrate at wiki?

  5. Alex Wayne Says:

    I had an idea about this that was surprisingly easy to implement. Just include a image_file_data binary field and the plugin will automatically shove image data in there. More info here:

    http://github.com/Squeegy/fleximage/wikis/databaseorfilesystemstorage

    I just didn’t really want to be supporting the issues that come with this, like getting people to constrain their common SQL from querying binary columns and other headaches. So I added the support, with the clause that I recommend file system based approaches.

    @Lucas: If you are using file system storage, no database columns are needed at all. Currently there is no rake tasks to migrate between DB and filesystem stores, but I think I can make that happen. Stay tuned.

  6. Marco Says:

    Hi, nice to hear about an update. I’am using DB-storage too. For my next project I’ll try the new version (with DB-storage). Very nice plugin, thanks a lot!

  7. Mike Says:

    Thanks for the update!

    As for sites I use FlexImI mostly use FlexImage for simple image manipulation and image storage, so they definitely don’t look anything close to the featured WineSpies :)

    But anyways, here’s the list of some sites :) Everything except for the first one are in Japanese (working at a Japan-based company currently, so.. oh well.. :)

    http://rightviewpro.com/ http://gakuenblog.com/ http://www.kyosyoen.com/ http://www.sudo-saketen.com/ http://www.maidsalon-hermes.com/ http://www.sakelife-tomu.com/ http://www.kimonokurachi.com/ http://www.kyo-roman.com/ http://www.sake-no-tamagoya.com/

    Nothing visually spectacular though. Feel free to include or not include these to your list :)

  8. Alex Wayne Says:

    Thanks Mike! Your comment got spam filtered, sorry for the delay.

    I have added them to the list Who uses Fleximage list.

  9. Ben Johnson Says:

    I couldnt find where to submit bugs, but its a pretty simple bug. I am using the flex image edge. When you do:

    some_obj.image_file = File.open(“path_to_jpg”)

    A file object does not have a method “original_filename”. So when trying to set the magic attributes you get an undefined method error. It’s on line 377.

    Thought this would help.

  10. Alex Wayne Says:

    Thanks Ben, nice find. Rails (and the CGI library) has like 3 classes it uses to upload files, and then there is there is an instance of File. It’s all a bit cumbersome to support all the APIs.

    I just committed a fix here

    It will ask for original_filename or basename which should work with File instances.

  11. oa Says:

    Hey Alex,

    Thanks for the plugin – it looks great.

    I am currently using AttachmentFu for its S3 capabilities, which I need for my current project. Is there an established way to store to S3 using Fleximage? If not, I would be happy to work on it and contribute back to the community. In this case, I was wondering if you could give me a few initial pointers to get started faster.

    Thanks, OA

  12. Alex Wayne Says:

    I have not used S3 just yet, so I am unfamiliar with the API. Although I am sure support would not be hard to add.

    Here some methods you will want to look at from Fleximage::Model

    • has_image?
    • has_saved_image?
    • load_image
    • delete_image_file
    • post_save

    Monkeying with those methods should be all you need to make Fleximage work with S3.

    Probably about time I hopped on that bandwagon, eh?

  13. atticus Says:

    Hi Alex,

    Thanks for the plugin. I’m guessing Fleximage V2 will not work on rails 1.2.3 because Mime::Type.register_alias in the init.rb file only works in Rails 2.0.

    If I comment off that line, would the plugin still work as normal?

    Thanks!

  14. Mark Says:

    I love the plugin! I would second the appreciation of S3 support.

  15. neelesh Says:

    atticus, This may be too late, but I could get Fleximage2 to work with Rails 1.2.3 by commenting the register_alias line in init.rb and changing from Mime::Type.lookup_by_extension to Mime::Type.lookup in legacy_view.rb and helper.rb. I haven’t tested the entire flow yet, though Hope this helps.

  16. Idonas Says:

    thanx for a wonderful plugin Alex

  17. Alex Wayne Says:

    You’re welcome!

  18. Brian Says:

    I am having trouble with fleximage and mod_rails (passenger). It works fine using conservative spawning, but freezes using smart spawning. The trouble spot seems to be GC.start I’d really like to get this working with smart spawning, but I’m stuck on where to look next to fix the problem. Any help would be greatly appreciated. Thanks.

  19. Nick Says:

    Alex, you’ve written an excellent plug-in and thank you.

    Just wondering if there is a good way to introduce height, width, and perhaps a desired aspect ratio or cropping. Just looking for a way to extending the routing to reduce templating code for different sizes. The code for the routing didn’t jump out at me, so any suggestions or pointers would be appepreciated.

    Example: Take: http://mysite.com/photos/123.jpg

    With additional params in the route. http://mysite.com/photos/200/100/3×1/123.jpg Where 200 is height, 100 is width, and 3×1 is aspect ratio. These params could be changed dynamically for whatever size image I want rather than hard coding them in a flexi template.

    Also will there be any updates for Amazon S3 support?

  20. Alex Wayne Says:

    Brian: Have not used mod_rails just yet, so I don’t know how that works. GC.start tells the garbage collector to do its thing to prevent memory leaks in RMagick. Maybe that’s not needed in mod_rails, I dont really know.

    Nick: What you ask isn’t hard. Set up a route like:

    map.photo ‘photos/:width/:height/:ratio/:id.:format’, :controller => ‘photos’, :action => ‘show’

    Then in your template, use what logic you need to based on those params:

    
    @photo.operate! do |image|
      width = (logic to figure out width based on aspect ratio)
      height = (logic to figure out height based on aspect ratio)
    
      image.resize [params[:width], params[:height]], :crop => true
    end
    

    You can setup the image_width and image_height magic columns on your model to capture them and compare them however you like, then figure out the numbers you need form there.

    I dont use S3 much, but I would happily accept a patch that extends support to it :)

  21. tommie jones Says:
    I’ve just tried fleximage and am stuck. I used your tutorial in the README.rdoc. In my show for the controller I do the following:
    <p>
      <%= image_tag formatted_image_path (@image, :jpg) %>
      <%= formatted_image_path (@image, :jpg) %>
    </p>
    
    but the path from formatted_image_path looks like: /images/1.jpg

    but it stores the image in dated directories so this does not work. any suggestions. maybe I am missing something in routes.

  22. Alex Wayne Says:

    tommie: Fleximage content is always served through a controller (and perhaps cached) but you never link directly to the master images.

    Your formatted_image route should have a controller and an action, in your case I bet it’s the images controller and the show action. Have your show action find the image object just like any other show action, and then create a show.jpg.flexi view to render the actual image out to the browser.

    The dated directories are used for the master images only. Fleximage reads the master images, transforms them based on your .flexi templates and sends them out as the response to a request. You don’t even need to store your master images in the public directory since its only ever read by your rails app.

  23. Duke Says:

    Uploading images on Flexiamge works fine. But how about updating image? All database records was updated, but the image which was located under “pulic/images” was not. When I destroyed it the database records and the image both were deleted. How cat I update the image?

  24. Dennis Says:

    On my development machine fleximage works perfectly – including working with image and page caching.

    When I post to my ISP server a very strange thing happens. The upload form completely ignores the create action and ends up back at the “successful” create redirect route – no error messages – nothing.

    Checked the dev log (server running in dev mode) and there is no hint that the create action was even invoked – intentional validation errors input into the form are not seen.

    Core problem is the image is not uploaded as a result of the above.

    If I remove the caching and expire code on the server then all works fine (but slow (:>)). Since there is absolutely no err msgs I’m stumped. Been two days of trying figure this out.

    I tried to determine if there are fleximage version dependencies (other than RAILs > 2) but can’t seem to find that info on git – maybe it’s me not looking all the well – but I don’t see anything.

    Can you tell me are there Imagemagick/Rmagick dependencies that must be met for the current version of fleximage.

    On my dev machine I have Rmagick 2.90 and Imagemagick ImageMagick 6.4.8-Q8

    On the ISP server it’s Rmagick 1.15.17 and Imagemagick 6.0.7.

    I’m using RAILS 2.3.2 on the dev and on the server.

    Sorry for posting here but I’m down to this being a database issue (ISP only tracks slow queries msgs – big help they are) or a fleximage version issue.

    Should mention same set of four plugins are on the server and the dev machine so I don’t see this being a plugin conflict issue.

    Thanks,

    Dennis

    PS: the web site provided for this form is pswd protected while under dev.

Leave a Reply