Image scaling and rotating in C/C++

Solution 1:

There are many ways to scale and rotate images. The simplest way to scale is:

dest[dx,dy] = src[dx*src_width/dest_width,dy*src_height/dest_height]

but this produces blocky effects when increasing the size and loss of detail when reducing the size. There are ways to produce better looking results, for example, bilinear filtering.

For rotating, the src pixel location can be calculated using a rotation matrix:

sx,sy = M(dx,dy)

where M is a matrix that maps destination pixels to the source image. Again, you'll need to do interpolation to produce non-blocky results.

But there are plenty of libraries available if you don't want to get into the mathematics of image processing.

Solution 2:

What you're doing is mapping a set of input points to a set of output points. The first part of the problem is to determine the mapping for your resizing or rotation; the second part is to handle points that don't lie exactly on a pixel boundary.

Mapping for a resize is easy:

x' = x * (width' / width)
y' = y * (height' / height)

Mapping for rotation is only a little bit harder.

x' = x * cos(a) + y * sin(a)
y' = y * cos(a) - x * sin(a)

The technique for determining the value of pixels that lie off the grid is called interpolation. There are many such algorithms, ranging widely in speed and final image quality. A few of them in increasing order of quality/time are nearest neighbor, bilinear, bicubic, and Sinc filter.