Shrinking Images

I have a huge memory bitmap that I am rendering an OpenGl image to. I save this bitmap to a file then I recall it up. After I have it back into a Device Context I then want to be able to shrink it down and save it.

I don't want to use StretchBlt(). It doesn't produce the quality I need. What I'm trying to simulate is what powerpoint does with it's zoom feature. I can open the image in powerpoint then scale it down using the zoom feature to say 33% and it actually improves in quality.

Does anyone know how I can simulate this effect?
Who is Participating?
lif081199Connect With a Mentor Commented:
Here is the bilinear reduction.
Not really clean, but it's just a good skeleton...
RGBBufferSource is a 24 bpp picture.
You can of course optimize this with pointers incrementations, and not those slow macros !!!
Good luck,

#define GetPixelRed(x,y)     RGBBufferSource[ (y*XSize+x)*3 ]  
#define GetPixelGreen(x,y)   RGBBufferSource[ (y*XSize+x)*3+1 ]  
#define GetPixelBlue(x,y)    RGBBufferSource[ (y*XSize+x)*3+2 ]  

void ReducePicture(char *RGBBufferSource, int XSize, int YSize, int XWantedSize, int YWantedSize)

    // For each destination pixel...
    for (y=0;y<YWantedSize;y++)
        for (x=0;x<XWantedSize;x++)
            // Compute the coord of (x,y) into the source pict.
            float xs,ys;
            xs = (float)x * (float)XWantedSize / (float)XSize ;
            ys = (float)y * (float)YWantedSize / (float)YSize ;

            // Basical influence
            float Left,Right,Top,Bottom;
            Left = 1 - ((float)xs - (float)((int)xs));
            Right = 1 - ( (float)((int)xs + 1) - (float)xs);
            Top = 1 - ((float)ys - (float)((int)ys));
            Bottom = 1 - ( (float)((int)ys + 1) - (float)ys);
            // note that Left+Right = 1, and Top+Bottom = 1.
            // Combine the influences
            float BottomLeft = Bottom * Left;
            float BottomRight = Bottom * Right;
            float TopRight = Top * Right;
            float TopLeft = top * Left;

            // Find the color of the new pixel (bilinear filtering)
            float r,g,b;
            r = TopLeft * GetPixelRed((int)xs,(int)ys) +
                TopRight * GetPixelRed((int)xs+1 ,(int)ys) +
                BottomLeft * GetPixelRed((int)xs ,(int)ys+1) +
                BottomRight * GetPixelRed((int)xs+1 ,(int)ys +1));
            g = TopLeft * GetPixelGreen((int)xs,(int)ys) +
                TopRight * GetPixelGreen((int)xs+1 ,(int)ys) +
                BottomLeft * GetPixelGreen((int)xs ,(int)ys+1) +
                BottomRight * GetPixelGreen((int)xs+1 ,(int)ys +1));
            b = TopLeft * GetPixelBlue((int)xs,(int)ys) +
                TopRight * GetPixelBlue((int)xs+1 ,(int)ys) +
                BottomLeft * GetPixelBlue((int)xs ,(int)ys+1) +
                BottomRight * GetPixelBlue((int)xs+1 ,(int)ys +1));

            // And write here the new (r,g,b) pixel into your dest !!!

all i can do for you is point you to a site, there u have to download a library to deal with image proccessing, it very easy to use try it:

by the way its free

The process we use to shrink/stretch an image is through the SetWindowExt and SetViewportExt functions.  Then a standard PaintBlt function will shrink the bitmap to your size.

But, if you are wanting a shrunken image that is actually clearer than the original.  Then a typical smoothing algorithm to the original image before you shrink it is in order.  But you will need multiple bitmaps in order to achieve this.
Upgrade your Question Security!

Your question, your audience. Choose who sees your identity—and your question—with question security.

jvitaleAuthor Commented:
psdavis: where can I find the algorithms for smoothing a bitmap image. That is really what I am after. I don't want huge libraries, just the means to smooth the image and make it clearer.
Linear interpolation between each adjacent pixels R,G & B values may prove worthwhile:

eg. [0][10][20][5] scales up to [0][5][10][15][20][13][5]
    and do the same in the vertical direction as well!

This may be a bit slow. An alternative is to use convolution templates - see a good book on image processing for low-pass filtering algorithms such as convolution.

If you're feeling brave you may want to pass the bitmap through a fast fourier transform, do a low-pass cut off on the resultant power spectrum and transform back thru' the inverse FFT. That would be much quicker if the bitmap is particularly large, but the maths is *scary* (I don't understand complex math at all)
Smoothing algorithm is not to bad.

A standard process is denoted

    1 1 1
    1 1 1
    1 1 1

Basically, you take two identically sized bitmaps.  One source and one destination.  Now for every pixel, take the value of itself, and the eight surrounding pixels and take the sum of them.  Then divide by 9.

Now store your result in the destination bitmap.

I can't think of any imaging libraries that don't have this type of feature.


Simply use glPixelZoom to shrink images.
to save a 'small' version of the image, you can sample it, (for example, skip 2 pixels, save one every 3 pixels.)

jvitaleAuthor Commented:
I guess I wasn't to clear about the OpenGl part. I'm not using straight OpenGl to program I'm using a set of libraries that encapsulates opengl. So I don't have direct access to the gl code.

However I am able to render the image to a huge memory bitmap and what I'm trying to concentrate on is shrinking the image back to a normal screen size while performing all the anti-alias and raster smoothing operations

if you use visual c++ and Windows NT(or Windows 98), you can definitely access gl functions.
NOTE: OpenGL functions do what you want to do. it's useless
What is your current question at this time jvitale?
jvitaleAuthor Commented:
My Question at this time is how do I take this huge memory bitmap and shrink it down to say a normal screen size with the best possible quality.

An example of the quality I'm looking for can be demonstrated using a large bitmap, inserting it into a powerpoint document then zooming out to like 50%.

I thank you for the examples of how to take the bits and transfer them to another bitmap, but I'm on clear on the code to do this. Before I venture down that path I want to make sure that by doing all that work it will produce the quality I need.

If it's too hard to do via code then please point me in the direction of a good library that does this. Shay pointed me in that direction, but when I got to the site it looked like there was tons of files to download and I'm not looking to add alot of files to my project; just a few.


Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.