This averages the appropriate pixels.
w_ratio = src.w / dest.w
h_ratio = src.h / dest.h
dest[x,y] =
AVG( src[x * w_ratio + xi, y * h_ratio + yi] )
where
xi in range (0, w_ratio - 1), inc by 1
yi in range (0, h_ratio - 1), inc by 1
For boundary conditions do a separate loop (no if's in loop).
Here's a more C like code:
src and dest are bitmaps that:
* property src[x,y] for pixel
* property src.w for width
* property src.h for height
pixel has been defined so that
adding
p1 = p1 + p2
is same as
p1.r = p1.r + p2.r
p1.g = p1.g + p2.g
...
division
p1 = p1 / c
p1.r = p1.r / c
p1.g = p1.g / c
evaluation with a constant 0
p1 = 0
p1.r = 0
p1.g = 0
...
for simplicity sake I won't consider the problem when pixel component integer overflows...
float w_ratio = src.w / dest.w;
float h_ratio = src.h / dest.h;
int w_ratio_i = floor(w_ratio);
int h_ratio_i = floor(h_ratio);
wxh = w_ratio*h_ratio;
for (y = 0; y < dest.w; y++)
for (x = 0; x < dest.h; x++){
pixel temp = 0;
int srcx, srcy;
// we have to use here the floating point value w_ratio, h_ratio
// otherwise towards the end it can get a little wrong
// this multiplication can be optimized similarly to Bresenham's line
srcx = floor(x * w_ratio);
srcy = floor(y * h_ratio);
// here we use floored value otherwise it might overflow src bitmap
for(yi = 0; yi < h_ratio_i; yi++)
for(xi = 0; xi < w_ratio_i; xi++)
temp += src[srcx + xi, srcy + yi];
dest[x,y] = temp / wxh;
}
Bresenham's line optimization