[cairo] Downing scaling images

Bill Spitzak spitzak at gmail.com
Tue Dec 14 12:15:18 PST 2010


There still seems to be some confusion here and some basic 
misunderstanding of how images are sampled.

Changing some fixed filter that is used to sample the source is not 
going to fix it! Blurring the resulting samples with more filtering is 
not going to fix it either! Calling the sampling function more than once 
per output pixel will work but is actually a really slow way to achieve 
the correct result (unless the sample filter is nearest-pixel in which 
case you have just replicated the algorithm I describe below).

Here are the facts:

The sampling filter *depends on the resulting scale*. As the scale gets 
smaller the filter gets bigger (as the scale gets bigger the filter may 
stop getting smaller at 1:1, this will give you normal blurry zoom, or 
it gets smaller to get antialiased pixel squares like OSX).

After this filter is applied you will get *exactly* the resulting pixel 
value. If you ever think you need to do a second step or somehow merge 
more than one sample call, it means you are not doing it right.

No algorithm that passes only an x,y to the code that retrives values 
from the source image is ever going to work, because the sampling code 
cannot figure out what filter to use!

A fully accurate one for affine transforms must take 6 numbers to 
describe the parallelogram that the edges of the output pixel 
back-transforms to, and for perspective transforms it must take 8 
numbers to describe an arbitrary quad (Note that a quad always describes 
the transform, no matter what "shape" you think a pixel has. This shape 
is used to get the filter from the quad.)

However this is overkill. The quad should be reduced to a simpler shape 
that the filtering can support. For two 1xn and 1xm linear filters, I 
recommend just sending x,y center and a dx,dy derivative to the sampling 
code (describing an axis-aligned rectangle that is as close as possible 
to the quad). The filter coefficients depends not only on dx and dy but 
also on the fractional parts of x,y!

This is what we are using in professional special effects software so it 
is probably good enough. A possible improvement is to pass integer skew 
values (this will reduce the blurring on 45 degree rotations while still 
allowing two linear filters to be used).

Ross Alexander wrote:
> The best down scaler I have come across gdk-pixbuf with GDK_INTERP_HYPER.  Both the cairo scaler and gegl only do bilinear scaling.
> 
>   gdk_pixbuf_scale(px, spx, 0, 0, width_new, height_new, 0.0, 0.0, scale, scale, GDK_INTERP_HYPER);
> 
> I have a test C program comparing the three methods.
> 
> Ross
> --
> cairo mailing list
> cairo at cairographics.org
> http://lists.cairographics.org/mailman/listinfo/cairo


More information about the cairo mailing list