[cairo] Downing scaling images
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.
> cairo mailing list
> cairo at cairographics.org
More information about the cairo