Blur Blending Method

Environment: C++

This sample shows a way to code the blur blending method on a RGB bitmap. Use it for a smooth effect or to remove noise.

/////////////////////////////////////////////////////////////////////
//
// Filter Procedure
//
// Blend a RGB color bitmap. Do not work with RGB(555).
//
// Process a blur average blending on the source bitmap. It takes 
// all the environnent pixels that are attached to the source pixel.
// 
//      1 1 1
//      1 S 1
//      1 1 1
//
// Then it computes the average of the color region.
// If (Pixel.Value - Average) is upper to the LevelDelta then the 
// color S is the Average; otherwise, it does not change.
// Set levelDelta to zero to apply Blur Method to each pixels of
// the bitmap.
//
// A blending matrix is use to set the weight of each pixel
// in the average computation
// Change matrix to change the transformation
// 
//      1 2 1
//      2 4 2
//      1 2 1
//
// SumColor is the sum of each element. (Sum = 16 in this example)
//
//  Average computation is made as follow : 
//
//  For( i = 0 ; i < MatrixElement ; i ++ )
//  Average += ( PixelColor[i] * BlendingMatrix[i] )
//  Average = Average / SumColor
//
//
// The following matrix is the Blur Blending Method :
//      1 2 1
//      2 4 2
//      1 2 1
//
// The following matrix is the Blur More Blending Method :
//      1 1 1
//      1 1 1
//      1 1 1
//
//
// NOTE : The format of the source bitmap is not changed.
// NOTE : The code is not optimized for execution but for a good
//        read comprehension
// NOTE : This procedure do not assum error managment. It is not the
//        subject of this example.
//
/////////////////////////////////////////////////////////////////////
//
// Input  :  Source DC
//           Source Bitmap
//           Color Delta
//
// Output :  None
// return :  None 
//
/////////////////////////////////////////////////////////////////////
//
// History : 05/2002 Jean-Rémi PINNA (jrpinna@noos.fr) Wrote it. 
//
/////////////////////////////////////////////////////////////////////


void _FILTER_BlurMethodBlending( HDC hSrcDc, 
                                 HBITMAP hSrcBmp, 
                                 BYTE bDeltaMax )
{
BITMAPINFO  sBmpInfo;
BYTE *      pBmpBytes;

  ::memset( &sBmpInfo, 0, sizeof(BITMAPINFO) );

  BITMAP SrcBmp;
  ::GetObject(hSrcBmp, sizeof(BITMAP), &SrcBmp);

  if( (SrcBmp.bmBitsPixel != 24) && (SrcBmp.bmBitsPixel != 32) )
    return;

  sBmpInfo.bmiHeader.biSize         = sizeof(BITMAPINFOHEADER);
  sBmpInfo.bmiHeader.biWidth        = SrcBmp.bmWidth;
  sBmpInfo.bmiHeader.biHeight       = SrcBmp.bmHeight;
  sBmpInfo.bmiHeader.biBitCount     = SrcBmp.bmBitsPixel;
  sBmpInfo.bmiHeader.biPlanes       = 1;
  sBmpInfo.bmiHeader.biCompression  = BI_RGB;
  sBmpInfo.bmiHeader.biSizeImage    =
        SrcBmp.bmBitsPixel*SrcBmp.bmWidth*SrcBmp.bmHeight/8;

  pBmpBytes = new BYTE[sBmpInfo.bmiHeader.biSizeImage];

  // Fill the buffer with a copy of the bitmap's bits

  ::GetDIBits(  hSrcDc,
      hSrcBmp, 
      0, 
      sBmpInfo.bmiHeader.biHeight, 
      pBmpBytes, 
      &sBmpInfo, 
      DIB_RGB_COLORS );


  DWORD dwLineWidth, dwByteCount, dwBytesPixel, dwImageSize;

  dwLineWidth   = SrcBmp.bmBitsPixel*SrcBmp.bmWidth/8;
  dwBytesPixel  = SrcBmp.bmBitsPixel/8;
  dwImageSize   = sBmpInfo.bmiHeader.biSizeImage;
  dwByteCount   = dwBytesPixel;	
  // Start to second pixel to avoid bug on first pixel
  // (Previous bottom point coordinate is 1276)

  // Blending Matrix ---- This matrix correspond to the Blur More
  //                         blending method 
  //                      The middle pixel value is the average
  //                        of all environnent pixels
  //                      Change value of an element modify his
  //                        weight in the computation of the average
  //
  // BYTE bBlurMoreBlendingMatrix[9] = { 1, 1, 1, 
  //          1, 1, 1,
  //          1, 1, 1 };
  //
  // BYTE bHalfBlendingMatrix[9] = { 0, 1, 0, 
  //          1, 1, 1,
  //          0, 1, 0 };


  // Blending Matrix ---- This matrix correspond to the Blur
  //                         blending method 
  //                      The sum of the elements of the array
  //                         must not exceed 256
  //

  BYTE bBlurBlendingMatrix[9] = { 1, 2, 1, 
          2, 4, 2,
          1, 2, 1 };

  // This matrix contains the values needed to point on 
  // corresponding bit
  //

  long nPosRange[9] = { - (long)(dwLineWidth-dwBytesPixel) ,
                        - (long)(dwLineWidth) ,
                        - (long)(dwLineWidth+dwBytesPixel),
                        - (long)(dwBytesPixel) , 
                        0 , 
                        +dwBytesPixel,
                        + (dwLineWidth-dwBytesPixel) , 
                        + (dwLineWidth) , 
                        + (dwLineWidth+dwBytesPixel) };


  // Sum Blending Matrix Elements
  //

  BYTE bMatrixSum = 0;

  for( int iSum = 0 ; iSum<9 ; iSum++ )
    bMatrixSum += bBlurBlendingMatrix[iSum];

  while( dwByteCount < dwImageSize )
  {
    DWORD bDelta, dwAverage;

    // Create array of pixel's positions
    //
    long nPosNewRange[9]= { (long)(dwByteCount+nPosRange[0]),
          (long)(dwByteCount+nPosRange[1]), 
          (long)(dwByteCount+nPosRange[2]),
          (long)(dwByteCount+nPosRange[3]), 
          (long)(dwByteCount+nPosRange[4]), 
          (long)(dwByteCount+nPosRange[5]),
          (long)(dwByteCount+nPosRange[6]), 
          (long)(dwByteCount+nPosRange[7]), 
          (long)(dwByteCount+nPosRange[8]) };

    // Check point validity : ensure points are in the bit array
    //
    for( int iPos = 0 ; iPos < 9 ; iPos++ )
    {
      nPosNewRange[iPos] = nPosNewRange[iPos] < 0 ? 0 : 
              nPosNewRange[iPos] > 
              (long)dwImageSize ? dwByteCount : nPosNewRange[iPos];
    }

    // Compute method on each RGB color of the pixel
    //
    for( int iColor = 0 ; iColor < 3 ; iColor++ )
    {
      dwAverage = 0;

      // Compute Color average
      //
      BYTE bColorValue[9] = { pBmpBytes[nPosNewRange[0]+iColor],
                              pBmpBytes[nPosNewRange[1]+iColor],
                              pBmpBytes[nPosNewRange[2]+iColor],
                              pBmpBytes[nPosNewRange[3]+iColor],
                              pBmpBytes[nPosNewRange[4]+iColor],
                              pBmpBytes[nPosNewRange[5]+iColor],
                              pBmpBytes[nPosNewRange[6]+iColor],
                              pBmpBytes[nPosNewRange[7]+iColor],
                              pBmpBytes[nPosNewRange[8]+iColor] };

      // Apply Blendind Matrix to compute color average
      //
      for( iPos = 0 ; iPos < 9 ; iPos++ )
        dwAverage += bColorValue[iPos]*bBlurBlendingMatrix[iPos];

      BYTE bAverage = (BYTE)(dwAverage/bMatrixSum);

      bDelta = abs( pBmpBytes[dwByteCount]-bAverage );
      pBmpBytes[dwByteCount+iColor] = 
           bDelta > bDeltaMax ? bAverage : 
                                  pBmpBytes[dwByteCount+iColor];
    }

    // Move to next pixel
    //
    dwByteCount+=dwBytesPixel;
  }


  ::SetDIBits( 	hSrcDc,
      hSrcBmp, 
      0, 
      sBmpInfo.bmiHeader.biHeight, 
      pBmpBytes, 
      &sBmpInfo, 
      DIB_RGB_COLORS );


  delete pBmpBytes;
}

Downloads

Download source - 7 Kb


Comments

  • A missing link!?!?

    Posted by Legacy on 06/06/2002 12:00am

    Originally posted by: Bo Krohn

    The link points to NIL... :)

    Reply
  • Source File

    Posted by Legacy on 06/05/2002 12:00am

    Originally posted by: Roger McElfresh

    Source file, what source file?

    Reply
Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • Are you truly leading your team or simply managing them? Organizations need leaders and your team needs someone to follow. With some ongoing development, you could become that leader. Learn the top leadership qualities that inspire others to want to follow you and the direction of your company.

  • On-demand Event Event Date: March 19, 2015 The 2015 Enterprise Mobile Application Survey asked 250 mobility professionals what their biggest mobile challenges are, how many employees they are equipping with mobile apps, and their methods for driving value with mobility. Join Dan Woods, Editor and CTO of CITO Research, and Alan Murray, SVP of Products at Apperian, as they break down the results of this survey and discuss how enterprises are using mobile application management and private app stores to …

Most Popular Programming Stories

More for Developers

RSS Feeds

Thanks for your registration, follow us on our social networks to keep up-to-date