65.9K
CodeProject is changing. Read more.
Home

Two Pass Scaling using Filters

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.94/5 (21 votes)

Dec 12, 1999

viewsIcon

576521

downloadIcon

2762

A smart way of scaling bitmaps

  • Download source files - 4 Kb

    Sample Image - 2_pass_scaling.jpg

    Unlike traditional scaling of images, where every n'th pixel is sampled and copied to the result image, this template provides much more accurate image scaling features.

    It takes a buffer of RGB values (as COLORREFs) and creates another buffer with new dimensions. The input / output buffers are sequential pixels (not compressed) compatible with the format used in 24-bit DIBs.

    The template is instantiated with a specific filter. The filter determines the quality of the output image. Different basic filters are supplied with this template and additional filters can be easily added.

    Major features:

    • Provides professional quality image scaling.
    • Code is optimized for image quality, not speed.
    • Supports various image filters:
      • Box filter.
      • Bilinear filter.
      • Gaussian filter.
      • Hamming filter.
      • Blackman filter.
      • ...New filters can be easily added.
    • Supports both magnification and minification.
    • Does not force aspect ratio limitations. e.g. an image can be magnified horizontally and minified vertically.
    • Supports 24-bit images. With little change can support other image formats / depths.
    • Template based - no need for libraries, DLLs etc. No linkage problems.

    How to use the scaling template:

    Assuming you have a non-compressed true-color 24-bit DIB in memory (the bits array is pointed by m_pBits), where the original bitmap width is m_dwWidth and height is m_dwHeight.

    Your code should look something like this:

    #include <2PassScale.h>
    ...
    
    void CMyDIB::ScaleTo (DWORD dwNewWidth, DWORD dwNewHeight)
    {
    	C2PassScale <CBilinearFilter> ScaleEngine;
    	COLORREF *pOldBitmap = m_pBits;
    	m_pBits = ScaleEngine.AllocAndScale(m_pBits,
    	                                    m_dwWidth,
    	                                    m_dwHeight,
    	                                    dwNewWidth,
    	                                    dwNewHeight
    	                                    );
    	if (NULL == m_pBits)
    	{
    		//
    		// Handle errors here
    		//
    	}
    	m_dwWidth = dwNewWidth;
    	m_dwHeight = dwNewHeight;
    	delete pOldBitmap;
    }
    
    // Alternatively, if you already have a pre-allocated destination buffer
    // in the new size you can call ScaleEngine.Scale (...) and give it that buffer