[Zope] Photo: somes issues and thoughts

J M Cerqueira Esteves jmce@artenumerica.com
Fri, 4 Jan 2002 13:06:08 +0000


* marc lindahl <marc@bowery.com> [2002-01-04 03:17 +0000]:
> 
> 
> > From: J M Cerqueira Esteves <jmce@artenumerica.com>
> > 
> > The main difference is that Photo defines new dimensions with integer
> > truncation, while Image Magick rounds each to the nearest integer
> > (when results of both calculations are different, the aspect ratio is
> > closer to the original with Image Magick).
> 
> But then you can go 1 pixel outside your 'bounding box' - is that more
> desirable?

It never goes outside the hM×wM 'bounding box'... unless you request 
hM == 0 or wM == 0.

The algorithm is

    scale = min (float (wM) / w0, float (hM) / h0)
    width = max (int (scale * w0 + 0.5), 1)
    height = max (int (scale * h0 + 0.5), 1)

Suppose  hM >= 1,  wM >= 1, and float (wM) / w0  <= float (hM) / h0.
Then:  
     scale == float (wM) / w0
     width == max (int (float (wM) / w0 * w0 +0.5), 1)

Unless  the result of float (wM) / w0 * w0  falls outside of the interval
 
                ] wM-0.5, wM+0.5 [

(can you think of a case where arithmetic would cause such an error?)
we then have

       width == max (wM, 1) == wM
and
       height == max (int (float(wM) / w0 * h0 + 0.5), 1).

Since we are assuming   float (wM) / w0  <= float (hM) / h0,  then

       height <= max (int (float(hM) / h0 * h0 + 0.5), 1)

and unless arithmetic errors make    float (hM) / h0 * h0   >= hM+0.5
we can conclude that

       height <= max (hM, 1),

i.e., in our case,

        height <= hM.

In the case  float (wM) / w0  >= float (hM) / h0  one can show in the same way
that

        width <= wM,  height == hM .


If one is still worried about the possibility of errors above 0.5 when
calculating   float (wM) / w0 * w0 or  float (hM) / h0 * h0,  one can
simply change the algorithm above into

    sw = float (wM) / w0
    sh = float (hM) / h0
    if sw <= sh:
      width = wM
      height = int (sw * h0 + 0.5)
    else:
      width = int (sh * w0 + 0.5)
      height = hM

(now respecting zero values for wM and hM).