Alastair M. Robinson wrote:
> Hi
>
> Sven Neumann wrote:
>
>
>> As already explained in my previous mail, the decimation routines are
>> only used for the pre-scaling steps. As soon as the image is close
>> enough to the final size, the chosen interpolation routine is used. This
>> gives continuous results for all scale factors as there is no longer any
>> special casing for scaling down by 50%.
>>
>
> What I don't understand is why there's a need to interpolate at all in
> the case of scaling an image down. When scaling up, interpolation is
> used to estimate missing information, but when scaling down there is no
> missing information to be estimated - the problem is instead finding the
> best strategy for *discarding* information.
>
> What I do in PhotoPrint is just use a simple sub-pixel-capable box
> filter - which is what your current approach
> (scale-by-nearest-power-of-two, then interpolate) is approximating.
>
> The routine looks like this:
>
> // We accumulate pixel values from a potentially
> // large number of pixels and process all the samples
> // in a pixel at one time.
> double tmp[IS_MAX_SAMPLESPERPIXEL];
> for(int i=0;i<samplesperpixel;++i)
> tmp[i]=0;
>
> ISDataType *srcdata=source->GetRow(row);
>
> // We use a Bresenham-esque method of calculating the
> // pixel boundaries for scaling - add the smaller value
> // to an accumulator until it exceeds the larger value,
> // then subtract the larger value, leaving the remainder
> // in place for the next round.
> int a=0;
> int src=0;
> int dst=0;
> while(dst<width)
> {
> // Add the smaller value (destination width)
> a+=width;
>
> // As long as the counter is less than the larger value
> // (source width), we take full pixels.
> while(a<source->width)
> {
> if(src>=source->width)
> src=source->width-1;
> for(int i=0;i<samplesperpixel;++i)
> tmp[i]+=srcdata[samplesperpixel*src+i];
> ++src;
> a+=width;
> }
>
> double p=source->width-(a-width);
> p/=width;
> // p now contains the proportion of the next pixel
> // to be counted towards the output pixel.
>
> a-=source->width;
> // And a now contains the remainder,
> // ready for the next round.
>
> // So we add p * the new source pixel
> // to the current output pixel...
> if(src>=source->width)
> src=source->width-1;
> for(int i=0;i<samplesperpixel;++i)
> tmp[i]+=p*srcdata[samplesperpixel*src+i];
>
> // Store it...
> for(int i=0;i<samplesperpixel;++i)
> {
> rowbuffer[samplesperpixel*dst+i] =
> 0.5+(tmp[i]*width)/source->width;
> }
> ++dst;
>
> // And start off the next output pixel with
> // (1-p) * the source pixel.
> for(int i=0;i<samplesperpixel;++i)
> tmp[i]=(1.0-p)*srcdata[samplesperpixel*src+i];
> ++src;
> }
>
>
>> The main problem with the code in trunk is though that I think that the
>> results of the new code are too blurry. Please have a look at the tests
>> that I published at http://svenfoo.org/scalepatch/. And please try the
>> patch and do your own tests.
>>
>
> The slight blurriness comes, I think, from performing the scaling in two
> distinct stages. Just for kicks, since I had a rare spare hour to play
> with such things, here are versions of the 3% and 23% test from your
> page, for comparison, scaled using the downsample filter whose core is
> posted above:
>
> http://www.blackfiveservices.co.uk/3Percent.png
> http://www.blackfiveservices.co.uk/23Percent.png
>
> Hope this is some help
>
> All the best,
> --
> Alastair M. Robinson
>
> _______________________________________________
> Gimp-developer mailing list
> [email protected]
> https://lists.XCF.Berkeley.EDU/mailman/listinfo/gimp-developer
>
>
>
The code is not interpolating rather resampling (supersampling in case
of lanczos and bicubic) in the case of scaling down.
The different filters lanczos,bicubic, box are just what you describe :
the problem is instead finding the best strategy for *discarding* information.
_______________________________________________
Gimp-developer mailing list
[email protected]
https://lists.XCF.Berkeley.EDU/mailman/listinfo/gimp-developer