More thoughts on automated image optimization for Plone

Last June, I wrote up some initial thoughts about how Plone could to more to help folks with limited experience preparing images for the web.    It got quite a bit of favorable response, but then I went off on sabbatical and haven’t followed up, until now.  I’m more convinced than ever that this is a good idea, and I really want to build some energy and resources around it.

Here’s some updated thinking on what I think could be done, both in core Plone and in a new add-on product, along with a simple wireframe and some implementation notes.

Making core Plone smarter

Plone 4 includes a frequently-requested feature that makes images much smarter: through-the-web configurable image scales.  Previously, these were hard-coded into ATContentTypes.  Now, we have a new “Image Scales” control panel, and site admins can add, edit and remove image scales.  This makes it much easier to provide the image scales site users need, and to eliminate the ones they don’t.  Nice work!

There’s one more change that I think should happen here:

Let’s make the amount of JPEG compression that PIL applies be easily configurable.  Right now, it’s hardcoded into our zope.conf, and it’s really, really high.  When we prep images for the web here at Groundwire, we typically use a compression quality of 60.  I think that it would make a lot of sense to expose this variable through-the-web in the Image Scales control panel configlet.

Rough Spec for an “Image Optimizer” Add-on Product

Ok, now here’s where the cool stuff starts.  Here are my updated thoughts on an add-on product that I think would really make life easier for sites that have lots of poorly-optimized images.

I imagine an “Image Optimization” control panel configlet that will present a UI that allows the user to:

  1. Walk the site catalog, looking for all objects that are Image-ish (i.e. have an image field) and contain images that are in JPEG, PNG or GIF format.
  2. Look at the pixel dimensions and the filesize of each image.
  3. Find images where the “bytes per pixel” (filesize/*(height*width)) is higher than a certain “reasonable” value.  (0.5 bytes per pixel seems about right to me, based on the idea that a 150X150 pixel JPEG image shouldn’t weigh much more than 10kb.  (Obviously, these settings should be user-editable.)
  4. Present the user with a list of “suspiciously large” images, along with their pixel dimensions, filesize, bytes per pixel and a preview.
  5. For images with dimensions that are larger than user-specified value, offer to resize them.
  6. For images that are too “heavy per pixel,” offer to apply more compression (for JPEGs) or convert to JPEG (for GIFs/PNGs)
  7. Apply changes via a separate process (via with AJAX updates so that Zope doesn’t bog down.
  8. Afterwards, offer to rebuild Plone’s auto-resized images afterwards from this new original.  Purge caches as necessary.

Here’s a wireframe of what I’ve got in mind:

A few more implementation notes/questions:

  • Alec Mitchell recommended using ImageMagick, because it offers much better quality than PIL.   I think this also seems sensible, because it would offer an easy way to spawn the intensive image manipulation work off into a separate process.  An outside-of-Zope processing approach such as is probably worth looking at as a model.
  • Resize, then convert, then compress.
  • JPEGs should be compressed via ImageMagick.
  • PNGs could potentially be compressed by running through OptiPNG.
  • GIF’s can’t be compressed
  • Use AJAX to refresh the screen on scan and as optimization proceeds.  Show optimization results by crossing out weight/dimension/density and replacing with new values.  (Hide unselected images when you hit Optimize.)  Total up savings at the bottom when optimization is complete.
  • Can Plone’s image scale rebuild be run in the background via so we don’t tie up a Zope process?
  • Plone 4 support is required; Plone 3 support would be very nice and would probably greatly increase the value of this product.
  • For extra bonus points, warn the user of unoptimized images right after upload, and offer to fix it “on the spot.”

Somewhat randomly, I also wanted to take note of Kurt Bendl’s useful recipes for limiting the max KB and pixel dimensions of uploaded AT Images and Files.  This might be useful and/or worth exposing in a TTW setting.

Next steps

Doing a mediocre job on this would probably be pretty easy, but it will take some focused effort to really nail the details that will make this sing.  I think this is a project worth raising a little bit of money around, and hiring someone good to really own it.

If your clients would benefit from a tool like this, I encourage you to think about whether you can raise some cash from them for a bounty fund.  I don’t have a hard total in mind just yet, but I’m thinking that $3000-$5000 might be a reasonable range.

I’ve got a couple of people in mind that I’d like to approach as possible developers on this, but if this description strikes a chord with you and you’ve got both the passion and skills, let me know!

This also might make a great Google Summer of Code project, in which case I’d love to supplement that by paying an experienced Plonista to be a strong, hands-on mentor and ensure that the project gets done and done right.  (This worked really well with Martin Aspeli and Timo Stollenwerk on!)

I’m willing to PM this and be “the customer” and Groundwire can very likely help seed the bounty fund as well.  Let’s make this happen!

12 thoughts on “More thoughts on automated image optimization for Plone”

  1. I really like this specs. I have a suggestion on how to handle the “long running” processes like rescaling: this seems to be the optimal job for something like zc.queue or any equivalent queue-of-atomic-actions implementation (PDFPeek seems to have its own queue implementation).

    What I see as a nice-to-have feature for the queue system is the ability to skip “ticks” (and not perform any action) if certain conditions are not met (load too high, for example).

    Also, I suggest to maybe split the specification into a “quick to implement core functionality” and the full package, making it easier to implement.

  2. Your proposal is cool, I like it, for content managers and admins who already know geek about digital images and/or who need to retroactively manipulate stuff already on the site and so on.

    I want something that cuts all this off at the pass, or at least as much of it as possible.

    What most of my client content managers need is something “for dummies” that works more like the “mail this picture” option in digiKam, iPhoto, etc., and happens right when they add an image object.

    This is how I think adding an image object ought to work – core plone functionality – not arguing with your proposal, more like complementing it (and maybe reducing some of the need for it?):

    When a user adds an image, there is a very simple means (option selections, slider, whatever – configurable by admins) to specify what the max size (width in px) for an image they are adding to the site needs to be, and maybe…only maybe!…a couple of quality level choices (also configurable by admins). Clicking the save button just makes it so – resizes and saves the given image file at the selected quality level.

    There could be an option for “original size” – which could be disabled by admins – for those cases where there’s a real need to add massive image files.

  3. Jon,
    A great idea. We have an AT field/widget here at Netsight called SuperImageField that does a number of things that we keep meaning to get around to releasing. This could be a good catalyst for this, and would be good to roll the functionality into the project you describe as I think they would fit nicely. It allows variable image compression, cropping to set sizes, watermarking, etc. Basically an accumulation of a number of features clients have wanted from us over the years. It ain’t pretty, but I’m sure we could sort it out 😉

    As for using ImageMagick as opposed to PIL… does it really give better quality? Alec, you are using PIL.Image.ANTIALIAS for resizes right? We already have PIL in Plone, and I’d be a shame to have to imclude yet another dependancy unless really worth it.


  4. Hi

    Great idea, something that I think Plone could have done with a long while back !

    My only thought , is that with png’s with transparency, you will not want them to be changed to jpeg’s necessarily as you’ll lose the transparency. It may be worth doing a check in the app, to see if your png or gif files has transparency and make a small flag of this in the results, so that the user doesn’t automatically just select ‘change to jpg’ for each png file.

  5. @JohnS — I agree wholeheartedly, and in fact I mentioned it as afterthought: “Somewhat randomly, I also wanted to take note of Kurt Bendl’s useful recipes for limiting the max KB and pixel dimensions of uploaded AT Images and Files. This might be useful and/or worth exposing in a TTW setting.” IOW, Plone already has this capability, it’s just buried very, very deeply.

  6. @Julian – Great point! I’ll update the article. Thank you!

    @Matt – PIL vs. ImageMagick – no strong personal opinion, but I trust Alec here. I agree that avoiding dependencies is good. RE: SuperImageField — I was hoping someone would have something like this — it would be amazing if you had time to release it in some fashion!

  7. Jon,
    Sounds great. I have several sites that need this badly.
    You can put designKiln down for 10% of the project cost up to $500.

  8. As the manager of a large website with lots of content contributors and lots of images (we do radiology, folks, images is what we are about) I’d be 100% behind any effort to work on this, especially if we can put some focus on allowing content creators to manage the images they upload when they upload them. I can even see if there might be some funds I can shake loose. This would be a great boon to us and we should pony up to support it if possible.


  9. @Lee, @Cris — awesome! I will think a bit more about how to fold the ideas Matt mentions for the “SuperImageField” into this. I was thinking more from a site admin point of few, not at the individual content creator level, but it would be really great to think at that level as well — thanks!

  10. Yes! This functionality would be very useful, — but the configuation seems a tad technical for control panels.
    There is little reason to vary these settings from site to site. I’d be happy to see this happening automatically in the background instead of adding more buttons to tweak.

  11. Matt,

    Yes, I use ANTIALIAS in PIL transformations, but I’ve had clients for whom the result was not acceptable. ImageMagick is pretty close to state of the art as far as scaling goes and the techniques it uses go far beyond anti-aliasing (See: There are comparisons to Photoshop and some anti-aliased scaling output here:

    It also supports an almost magical “liquid scaling” feature that can change an aspect ratio without significantly distorting the image content.

    I wouldn’t suggest making it a dependency for Plone though, because it’s a pain to install. For an add-on that wants to offer quality image transformations, it should be seriously considered, IMHO. Also, if you want to offer flipping/rotation of JPEG images, using libjpeg/jpegtran/jhead allows for extremely fast lossless transforms (whereas both PIL and ImageMagick degrade JPEGs on each transform). See:

  12. We recently had a user upload two bmp files that were 28MB each. I think it would be wise to include bmp file type in your list of image types that can be converted to jpegs. Unfortunately there are users out there who are quite ignorant about image formats, dimensions and compression.

    I know it’s slightly out of scope but a similar tool to pick up large File objects would be useful for administrators. We’d really like to know if a user has uploaded a 100MB powerpoint.

Comments are closed.