[Zope] Photo: somes issues and thoughts

J M Cerqueira Esteves jmce@artenumerica.com
Fri, 4 Jan 2002 15:07:14 +0000


* Jose' Sebrosa <sebrosa@artenumerica.com> [2002-01-04 13:29 +0000]:
> Sometimes, truncation (floor) gives better aspect ratio than round.  I would
> even not be surprised if, statistically, none of the methods were better.
> 
> Two examples:
> 
> 1-
> Initial size: 51x49
> Scale: 1/10
> Final size (method=round): 5x5
> Final size (method=floor): 5x4
> Best method: round
> 
> 2-
> Initial size: 54x56
> Scale: 1/10
> Final size (method=round): 5x6
> Final size (method=floor): 5x5
> Best method: floor

Those methods are not used by Photo and ImageMagick. 

With Photo and IM you start by choosing new maximum integer
dimensions, not the scale, and one of the sides of the resulting
rectangle gets one of those exact integer lengths.  THEN you calculate
the scale factor and apply it to the other side; it is here that 
IM rounds and Photo truncates.

But it is interesting to use these examples and see what we get for a
few very small maximum width (wM) and maximum height (hM) values:

1 - h0×w0 = 51×49
                                  width × height
                     wM  hM     Photo  ImageMagick
                      6   6      6×5       6×6
                      6   5      5×5       5×5
                      5   6      5×4       5×5
                      5   5      5×4       5×5
                      1   1      1×0       1×1

2 - h0×w0 = 54×56
                                  width × height
                     wM  hM     Photo  ImageMagick
                      6   6      5×6       6×6
                      6   5      4×5       5×5
                      5   6      5×5       5×5
                      5   5      4×5       5×5
                      1   1      0×1       1×1

You may test all of this by calling functions below 
with arguments (w0,h0,wM,hM):

def scaleP (w0, h0, w, h):
  if h > h0 * w / w0:
    h = h0 * w / w0
  else:
    w =  w0 * h / h0
  return (w, h)
  
def scaleIM (w0, h0, w, h):
  scale = min (float (w) / w0, float (h) / h0)
  w = int (scale * w0 + 0.5)
  h = int (scale * h0 + 0.5)
  return (w, h)