[cairo] nearest neighborhood or bilinear interpolation
Bill Spitzak
spitzak at d2.com
Mon Oct 30 10:22:48 PST 2006
Jeff Muizelaar wrote:
> On Fri, Oct 27, 2006 at 08:45:13PM -0200, Carlos Eduardo Rodrigues Diógenes wrote:
>> Hi,
>>
>> It's possible to select what cairo will use when making scale
>> transformations in imagens (nearest neighborhood or bilinear
>> interpolation)?
>
> Yes.
>
> Have a look at the poorly documented cairo_pattern_set_filter().
>
> http://www.cairographics.org/manual/cairo-Patterns.html#cairo-pattern-set-filter
I'm curious about exactly the reason this is wanted. Often people who
request this actually want a specific subset, and it would be much
better to implement this specific subset.
1. Actual impulse filtering (often called "nearest neighbor") results in
very poor image quality if the scale is anything other than an integer
or if any rotation is done. I kind of doubt this is wanted by anybody,
unless the desperately need to emulate the output of some other software.
2. However the result of impulse filtering when scaling by an integer is
often what the programmer wants and expects, which is that each pixel
turns into an n*n square of pixels identical to the original. At
non-integers above a certain size many people prefer impulse filtering,
this size depends on the viewer and the image, and is the point at which
the difference in widths of the pixel columns and rows becomes
unobjectionable, this can vary from 2 to 10 or so.
3. A much less common reason is that no scaling or rotation is being
done, but the picture is being translated by a non-integer. What is
really wanted is that the translation be rounded to the nearest integer.
I very much suspect that #2 is the real request, and that the original
poster either does not care about, or actually does not want, the
results when the picture is scaled by less than 2 or rotated.
Because of this I think the proper solution is to fix #2 and leave
filtering working for other transformations, and even make this the
default behavior of Cairo. One way is to do something I have only seen
OS/X do, which is to ignore sampling theory and scale images up by using
a box filter that gets smaller than 1. An equivalent would be to
impulse-filter scale the picture up to the next larger integer and then
filter that down to the result. Another way to look at it is that the
image really is fully antialiased squares the size of each pixel. This
has the advantage that not only integer scales work, but that
non-integer scales greater than 1 blend smoothly into them. The big
disadvantage is that no hardware renderer works this way.
#3 is a totally seperate problem. It may make sense to do that if
antialiasing (which otherwise does not effect images) is turned off.
Since drawing a rectangle with antialiasing off shifts the rectangle to
the nearest integer, it may make sense to shift the translation of the
image to the nearest integer so it remains matching. Then again this may
be a bad idea if antialiasing is being used to seam together several
texture-mapped rectangles.
More information about the cairo
mailing list