[Zope] Photo: somes issues and thoughts

J M Cerqueira Esteves jmce@artenumerica.com
Thu, 3 Jan 2002 19:40:12 +0000


Greetings

I am developing a site where people editing content will not directly
access the Zope interface but will use several simplified forms
adequate for their work.  Since they will occasionally need to add
some images, I am using the Photo product as the basis for the image
management tool they will be using (images will be Photo objects in a
hierarchy of Photo Folders, and most people will not be writing DTML
but referring to original images or derived displays explicitly writing
their URLs in plain HTML).  While preparing this, I noticed a few
minor issues.


On-the-fly resizing could be interesting:

Ron Bickers seems to be considering adding support for on-the-fly
image resizing, that is, arbitrary image resizing with no need for
predefining named display sizes.  This could be convenient for
situations like my current one.  There will be a few cases where the
"photo album" metaphor will be used (like in the Photo Folder sample
views), but the majority of the other pictures will be added one by
one to be used in separate contexts, each in one or two sizes without
any foreseeable "size standards".  For many pictures, display sizes
will have to be defined individually, therefore with less interest
in having to "invent" or reuse a name for each new size or even to
have to visit an administration interface just for resizing; maybe the
nicest solution from the point of view of a content editor (when not
working with the "tag" method but only writing pure HTML) would be simply
to write

  <img src="http:/somesite/img/.../picture.jpg?width=300" ...  />

when one needs to show picture.jpg in a new size with width of 300 pixels
or  .../picture.jpg?width=480&height=480   to limite the larger size to 480 
pixels.
This would end up producing "unnamed" cached displays for each
picture.  Of course HTML authors would still have to take care of
checking the final dimensions in order to write 'height' and 'width'
attributes...  or those could be supplied by a size testing interface
on the site (possibly listing already cached sizes).  It could also be
nice to allow rescaling (relatively to the original size) with
something like

     .../picture.jpg?scale=1.56 

(or a "scale" cookie perhaps of use for automagically resizing all
images (big and small) by the same factor on a set of pages via a
"scale" cookie).  One could then wish for several other image
transformations like those available with \includegraphics in LaTeX
package graphicx: cropping with "bounding boxes", rotation, ... :-)


About the cookie name:

It could also be useful to allow customization of the cookie name (now
hardcoded as 'display') to solve possible cases of "collision" with
other cookies or even to allow separate display customization for
different image sets in the same site.  Likewise for any other cookies which
may someday be used by the Photo product.


The `tag' method:

The `tag' method sets the display cookie only when the supplied
display name corresponds to an existing one for the current image.  An
interesting exception would be to set the display cookie ALSO when
display=='', thus activating "natural size" viewing (unless one has
defined a display size with id=='', which is currently possible...).

Ideally, the `tag' method should respect alt=='' (since sometimes one
really wants that):

  if alt is None:
    alt = getattr(self, 'title', None)
    if alt is None:
      alt = self.getId()


Image size calculation:

In my "view" method (replacing the sample "view") I was going to show
the dimensions the current pic would have at each defined display size, near
to the link to the corresponding page.  It would be interesting to
have public methods providing that information (height() and width()
only provide it for the original image; displayMap() only provides
dimensions for displays which have already been generated, and I chose
not to pregenerate them all).  I simply reproduced the calculations of
_getAspectRatioSize, but then noticed that some results were wrong.

For instance, with an original image of 272×281 pixels, the result of
rezising to a maximum of 480×480 is not an image with 464×480 as
expected, but 464×479.  This happens because I opted for using
ImageMagick and:

- _getAspectRatioSize, using integer division, rounds down 
  464.626334... (the "ideal" new width) to 464;
- _resize calls ImageMagick's `convert' with option -geometry 464x480;
- called like this, `convert' also tries to mantain the aspect ratio
  of the input image and uses the -geometry parameters as limits:
  constrained to 464×480, the best solution it finds to maintain the 
  aspect ratio is creating an image of 464×479.

It would be better in this case to call `convert' with option
-geometry 480x480 and let it calculate the ideal new size.  When I do
that manually, I get a 465×480 image.  Unfortunately, I had no time to
determine the precise equation used by ImageMagick to calculate new
sizes maintaining aspect ratio.  Having it, you could use that instead
of the calculation at _getAspectRatioSize when resizing with PIL
(since PIL's `resize', unlike ImageMagick's `convert', doesn't try to
maintain aspect ratio and needs to be given precise final sizes).


Image quality with PIL:

I noticed that in the version of PIL I have here, 1.1.2, the resize
method has an optional filter argument which can be "NEAREST,
BILINEAR, or BICUBIC. If omitted, it defaults to NEAREST."  I have no
time for careful testing now (and Image Magick is working very well),
but noticed that `resize' is being without specifying the
filter, thus using NEAREST and not taking full advantage of PIL
capabilities.


Best regards
                         J Esteves