www.pudn.com > TImageProcess.rar > IP.cpp
#include "stdafx.h" #include#include "dibapi.h" // Definitions required for convolution image filtering #define KERNELCOLS 3 #define KERNELROWS 3 #define KERNELELEMENTS (KERNELCOLS * KERNELROWS) // struct for convolute kernel typedef struct { int Element[KERNELELEMENTS]; int Divisor; } KERNEL; // The following kernel definitions are for convolution filtering. // Kernel entries are specified with a divisor to get around the // requirement for floating point numbers in the low pass filters. KERNEL HP1 = { // HP filter #1 {-1, -1, -1, -1, 9, -1, -1, -1, -1}, 1 // Divisor = 1 }; KERNEL HP2 = { // HP filter #2 { 0, -1, 0, -1, 5, -1, 0, -1, 0}, 1 // Divisor = 1 }; KERNEL HP3 = { // HP filter #3 { 1, -2, 1, -2, 5, -2, 1, -2, 1}, 1 // Divisor = 1 }; KERNEL LP1 = { // LP filter #1 { 1, 1, 1, 1, 1, 1, 1, 1, 1}, 9 // Divisor = 9 }; KERNEL LP2 = { // LP filter #2 { 1, 1, 1, 1, 2, 1, 1, 1, 1}, 10 // Divisor = 10 }; KERNEL LP3 = { // LP filter #3 { 1, 2, 1, 2, 4, 2, 1, 2, 1}, 16 // Divisor = 16 }; KERNEL VertEdge = { // Vertical edge { 0, 0, 0, -1, 1, 0, 0, 0, 0}, 1 // Divisor = 1 }; KERNEL HorzEdge = { // Horizontal edge { 0, -1, 0, 0, 1, 0, 0, 0, 0}, 1 // Divisor = 1 }; KERNEL VertHorzEdge = { // Vertical Horizontal edge { -1, 0, 0, 0, 1, 0, 0, 0, 0}, 1 // Divisor = 1 }; KERNEL EdgeNorth = { // North gradient { 1, 1, 1, 1, -2, 1, -1, -1, -1}, 1 // Divisor = 1 }; KERNEL EdgeNorthEast = { // North East gradient { 1, 1, 1, -1, -2, 1, -1, -1, 1}, 1 // Divisor = 1 }; KERNEL EdgeEast = { // East gradient {-1, 1, 1, -1, -2, 1, -1, 1, 1}, 1 // Divisor = 1 }; KERNEL EdgeSouthEast = { // South East gradient {-1, -1, 1, -1, -2, 1, 1, 1, 1}, 1 // Divisor = 1 }; KERNEL EdgeSouth = { // South gadient {-1, -1, -1, 1, -2, 1, 1, 1, 1}, 1 // Divisor = 1 }; KERNEL EdgeSouthWest = { // South West gradient { 1, -1, -1, 1, -2, -1, 1, 1, 1}, 1 // Divisor = 1 }; KERNEL EdgeWest = { // West gradient { 1, 1, -1, 1, -2, -1, 1, 1, -1}, 1 // Divisor = 1 }; KERNEL EdgeNorthWest = { // North West gradient { 1, 1, 1, 1, -2, -1, 1, -1, -1}, 1 // Divisor = 1 }; KERNEL Lap1 = { // Laplace filter 1 { 0, 1, 0, 1, -4, 1, 0, 1, 0}, 1 // Divisor = 1 }; KERNEL Lap2 = { // Laplace filter 2 { -1, -1, -1, -1, 8, -1, -1, -1, -1}, 1 // Divisor = 1 }; KERNEL Lap3 = { // Laplace filter 3 { -1, -1, -1, -1, 9, -1, -1, -1, -1}, 1 // Divisor = 1 }; KERNEL Lap4 = { // Laplace filter 4 { 1, -2, 1, -2, 4, -2, 1, -2, 1}, 1 // Divisor = 1 }; KERNEL Sobel[4] = { { // Sobel1 {-1, 0, 1, -2, 0, 2, -1, 0, 1}, 1 // Divisor = 1 }, { // Sobel2 {-1, -2, -1, 0, 0, 0, 1, 2, 1}, 1 // Divisor = 1 }, { // Sobel3 {-2, -1, 0, -1, 0, 1, 0, 1, 2}, 1 // Divisor = 1 }, { // Sobel4 {0, -1, -2, 1, 0, -1, 2, 1, 0}, 1 // Divisor = 1 } }; KERNEL Hough[4] = { { // Hough1 {-1, 0, 1, -1, 0, 1, -1, 0, 1}, 1 // Divisor = 1 }, { // Hough2 {-1, -1, 0, -1, 0, 1, 0, 1, 1}, 1 // Divisor = 1 }, { // Hough3 {-1, -1, -1, 0, 0, 0, 1, 1, 1}, 1 // Divisor = 1 }, { // Hough4 {0, -1, -1, 1, 0, -1, 1, 1, 0}, 1 // Divisor = 1 } }; // local use macro #define PIXEL_OFFSET(i, j, nWidthBytes) \ (LONG)((LONG)(i)*(LONG)(nWidthBytes) + (LONG)(j)*3) // local function prototype int compare(const void *e1, const void *e2); void DoMedianFilterDIB(int *red, int *green, int *blue, int i, int j, WORD wBytesPerLine, LPBYTE lpDIBits); void DoConvoluteDIB(int *red, int *green, int *blue, int i, int j, WORD wBytesPerLine, LPBYTE lpDIBits, KERNEL *lpKernel); BOOL ConvoluteDIB(HDIB hDib, KERNEL *lpKernel, int Strength, int nKernelNum=1); // function body /************************************************************************* * * HighPassDIB() * * Parameters: * * HDIB hDib - objective DIB handle * int nAlgorithm - specify the filter to use * int Strength - operation strength set to the convolute * * Return Value: * * BOOL - True is success, else False * * Description: * * High pass filtering to sharp DIB * ************************************************************************/ BOOL HighPassDIB(HDIB hDib, int Strength, int nAlgorithm) { switch (nAlgorithm) { case FILTER1: return ConvoluteDIB(hDib, &HP1, Strength); case FILTER2: return ConvoluteDIB(hDib, &HP2, Strength); case FILTER3: return ConvoluteDIB(hDib, &HP3, Strength); } return FALSE; } /************************************************************************* * * LowPassDIB() * * Parameters: * * HDIB hDib - objective DIB handle * int nAlgorithm - specify the filter to use * int Strength - operation strength set to the convolute * * Return Value: * * BOOL - True is success, else False * * Description: * * Low pass filtering to blur DIB * ************************************************************************/ BOOL LowPassDIB(HDIB hDib, int Strength, int nAlgorithm) { switch (nAlgorithm) { case FILTER1: return ConvoluteDIB(hDib, &LP1, Strength); case FILTER2: return ConvoluteDIB(hDib, &LP2, Strength); case FILTER3: return ConvoluteDIB(hDib, &LP3, Strength); } return FALSE; } /************************************************************************* * * EdgeEnhanceDIB() * * Parameters: * * HDIB hDib - objective DIB handle * int nAlgorithm - specify the filter to use * int Strength - operation strength set to the convolute * * Return Value: * * BOOL - True is success, else False * * Description: * * Edge enhance DIB * ************************************************************************/ BOOL EdgeEnhanceDIB(HDIB hDib, int Strength, int nAlgorithm) { switch (nAlgorithm) { case VERT: return ConvoluteDIB(hDib, &VertEdge, Strength); case HORZ: return ConvoluteDIB(hDib, &HorzEdge, Strength); case VERTHORZ: return ConvoluteDIB(hDib, &VertHorzEdge, Strength); case NORTH: return ConvoluteDIB(hDib, &EdgeNorth, Strength); case NORTHEAST: return ConvoluteDIB(hDib, &EdgeNorthEast, Strength); case EAST: return ConvoluteDIB(hDib, &EdgeEast, Strength); case SOUTH: return ConvoluteDIB(hDib, &EdgeSouth, Strength); case SOUTHEAST: return ConvoluteDIB(hDib, &EdgeSouthEast, Strength); case SOUTHWEST: return ConvoluteDIB(hDib, &EdgeSouthWest, Strength); case WEST: return ConvoluteDIB(hDib, &EdgeWest, Strength); case NORTHWEST: return ConvoluteDIB(hDib, &EdgeNorthWest, Strength); case LAP1: return ConvoluteDIB(hDib, &Lap1, Strength); case LAP2: return ConvoluteDIB(hDib, &Lap2, Strength); case LAP3: return ConvoluteDIB(hDib, &Lap3, Strength); case LAP4: return ConvoluteDIB(hDib, &Lap4, Strength); case SOBEL: return ConvoluteDIB(hDib, Sobel, Strength, 4); case HOUGH: return ConvoluteDIB(hDib, Hough, Strength, 4); } return FALSE; } /************************************************************************* * * MedianFilterDIB() * * Parameters: * * HDIB hDib - objective DIB handle * * Return Value: * * BOOL - True is success, else False * * Description: * * This is the media filtering function to DIB * ************************************************************************/ BOOL MedianFilterDIB(HDIB hDib) { WaitCursorBegin(); HDIB hNewDib = NULL; // we only convolute 24bpp DIB, so first convert DIB to 24bpp WORD wBitCount = DIBBitCount(hDib); if (wBitCount != 24) hNewDib = ConvertDIBFormat(hDib, 24, NULL); else hNewDib = CopyHandle(hDib); if (! hNewDib) { WaitCursorEnd(); return FALSE; } // new DIB attributes WORD wDIBWidth = (WORD)DIBWidth(hNewDib); WORD wDIBHeight = (WORD)DIBHeight(hNewDib); WORD wBytesPerLine = (WORD)BytesPerLine(hNewDib); DWORD dwImageSize = wBytesPerLine * wDIBHeight; // Allocate and lock memory for filtered image data HGLOBAL hFilteredBits = GlobalAlloc(GHND, dwImageSize); if (!hFilteredBits) { WaitCursorEnd(); return FALSE; } LPBYTE lpDestImage = (LPBYTE)GlobalLock(hFilteredBits); // get bits address in DIB LPBYTE lpDIB = (LPBYTE)GlobalLock(hNewDib); LPBYTE lpDIBits = FindDIBBits(lpDIB); // convolute... for (int i=1; i red) red = r; if (g > green) green = g; if (b > blue) blue = b; //red += r; green += g; blue += b; } // original RGB value in center pixel (j, i) LONG lOffset= PIXEL_OFFSET(i,j, wBytesPerLine); BYTE OldB = *(lpDIBits + lOffset++); BYTE OldG = *(lpDIBits + lOffset++); BYTE OldR = *(lpDIBits + lOffset); // When we get here, red, green and blue have the new RGB value. if (Strength != 10) { // Interpolate pixel data red = OldR + (((red - OldR) * Strength) / 10); green = OldG + (((green - OldG) * Strength) / 10); blue = OldB + (((blue - OldB) * Strength) / 10); } lOffset= PIXEL_OFFSET(i,j, wBytesPerLine); *(lpDestImage + lOffset++) = BOUND(blue, 0, 255); *(lpDestImage + lOffset++) = BOUND(green, 0, 255); *(lpDestImage + lOffset) = BOUND(red, 0, 255); } // a filtered image is available in lpDestImage // copy it to DIB bits memcpy(lpDIBits, lpDestImage, dwImageSize); // cleanup temp buffers GlobalUnlock(hFilteredBits); GlobalFree(hFilteredBits); GlobalUnlock(hNewDib); // rebuild hDib HDIB hTmp = NULL; if (wBitCount != 24) hTmp = ConvertDIBFormat(hNewDib, wBitCount, NULL); else hTmp = CopyHandle(hNewDib); GlobalFree(hNewDib); DWORD dwSize = GlobalSize(hTmp); memcpy((LPBYTE)GlobalLock(hDib), (LPBYTE)GlobalLock(hTmp), dwSize); GlobalUnlock(hTmp); GlobalFree(hTmp); GlobalUnlock(hDib); WaitCursorEnd(); return TRUE; } // local function: perform convolution to DIB with a kernel void DoConvoluteDIB(int *red, int *green, int *blue, int i, int j, WORD wBytesPerLine, LPBYTE lpDIBits, KERNEL *lpKernel) { BYTE b[9], g[9], r[9]; LONG lOffset; lOffset= PIXEL_OFFSET(i-1,j-1, wBytesPerLine); b[0] = *(lpDIBits + lOffset++); g[0] = *(lpDIBits + lOffset++); r[0] = *(lpDIBits + lOffset); lOffset= PIXEL_OFFSET(i-1,j, wBytesPerLine); b[1] = *(lpDIBits + lOffset++); g[1] = *(lpDIBits + lOffset++); r[1] = *(lpDIBits + lOffset); lOffset= PIXEL_OFFSET(i-1,j+1, wBytesPerLine); b[2] = *(lpDIBits + lOffset++); g[2] = *(lpDIBits + lOffset++); r[2] = *(lpDIBits + lOffset); lOffset= PIXEL_OFFSET(i,j-1, wBytesPerLine); b[3] = *(lpDIBits + lOffset++); g[3] = *(lpDIBits + lOffset++); r[3] = *(lpDIBits + lOffset); lOffset= PIXEL_OFFSET(i,j, wBytesPerLine); b[4] = *(lpDIBits + lOffset++); g[4] = *(lpDIBits + lOffset++); r[4] = *(lpDIBits + lOffset); lOffset= PIXEL_OFFSET(i,j+1, wBytesPerLine); b[5] = *(lpDIBits + lOffset++); g[5] = *(lpDIBits + lOffset++); r[5] = *(lpDIBits + lOffset); lOffset= PIXEL_OFFSET(i+1,j-1, wBytesPerLine); b[6] = *(lpDIBits + lOffset++); g[6] = *(lpDIBits + lOffset++); r[6] = *(lpDIBits + lOffset); lOffset= PIXEL_OFFSET(i+1,j, wBytesPerLine); b[7] = *(lpDIBits + lOffset++); g[7] = *(lpDIBits + lOffset++); r[7] = *(lpDIBits + lOffset); lOffset= PIXEL_OFFSET(i+1,j+1, wBytesPerLine); b[8] = *(lpDIBits + lOffset++); g[8] = *(lpDIBits + lOffset++); r[8] = *(lpDIBits + lOffset); *red = *green = *blue = 0; for (int k=0; k<8; ++k) { *red += lpKernel->Element[k]*r[k]; *green += lpKernel->Element[k]*g[k]; *blue += lpKernel->Element[k]*b[k]; } if (lpKernel->Divisor != 1) { *red /= lpKernel->Divisor; *green /= lpKernel->Divisor; *blue /= lpKernel->Divisor; } // getoff opposite *red = abs(*red); *green = abs(*green); *blue = abs(*blue); } // local function: perform median filter to DIB void DoMedianFilterDIB(int *red, int *green, int *blue, int i, int j, WORD wBytesPerLine, LPBYTE lpDIBits) { BYTE b[9], g[9], r[9]; LONG lOffset; lOffset= PIXEL_OFFSET(i-1,j-1, wBytesPerLine); b[0] = *(lpDIBits + lOffset++); g[0] = *(lpDIBits + lOffset++); r[0] = *(lpDIBits + lOffset); lOffset= PIXEL_OFFSET(i-1,j, wBytesPerLine); b[1] = *(lpDIBits + lOffset++); g[1] = *(lpDIBits + lOffset++); r[1] = *(lpDIBits + lOffset); lOffset= PIXEL_OFFSET(i-1,j+1, wBytesPerLine); b[2] = *(lpDIBits + lOffset++); g[2] = *(lpDIBits + lOffset++); r[2] = *(lpDIBits + lOffset); lOffset= PIXEL_OFFSET(i,j-1, wBytesPerLine); b[3] = *(lpDIBits + lOffset++); g[3] = *(lpDIBits + lOffset++); r[3] = *(lpDIBits + lOffset); lOffset= PIXEL_OFFSET(i,j, wBytesPerLine); b[4] = *(lpDIBits + lOffset++); g[4] = *(lpDIBits + lOffset++); r[4] = *(lpDIBits + lOffset); lOffset= PIXEL_OFFSET(i,j+1, wBytesPerLine); b[5] = *(lpDIBits + lOffset++); g[5] = *(lpDIBits + lOffset++); r[5] = *(lpDIBits + lOffset); lOffset= PIXEL_OFFSET(i+1,j-1, wBytesPerLine); b[6] = *(lpDIBits + lOffset++); g[6] = *(lpDIBits + lOffset++); r[6] = *(lpDIBits + lOffset); lOffset= PIXEL_OFFSET(i+1,j, wBytesPerLine); b[7] = *(lpDIBits + lOffset++); g[7] = *(lpDIBits + lOffset++); r[7] = *(lpDIBits + lOffset); lOffset= PIXEL_OFFSET(i+1,j+1, wBytesPerLine); b[8] = *(lpDIBits + lOffset++); g[8] = *(lpDIBits + lOffset++); r[8] = *(lpDIBits + lOffset); qsort(r, 9, 1, compare); qsort(g, 9, 1, compare); qsort(b, 9, 1, compare); *red = r[0]; *green = g[0]; *blue = b[0]; } // function used to sort in the call of qsort int compare(const void *e1, const void *e2) { if (*(BYTE *)e1 < *(BYTE *)e2) return -1; if (*(BYTE *)e1 > *(BYTE *)e2) return 1; return 0; } /************************************************************************* * * ReverseDIB() * * Parameters: * * HDIB hDib - objective DIB handle * * Return Value: * * BOOL - True is success, else False * * Description: * * This function reverse DIB * ************************************************************************/ BOOL ReverseDIB(HDIB hDib) { WaitCursorBegin(); HDIB hNewDib = NULL; // only support 256 grayscale image WORD wBitCount = DIBBitCount(hDib); if (wBitCount != 8) { WaitCursorEnd(); return FALSE; } // the maxium pixel value int nMaxValue = 256; // source pixel data LPBITMAPINFO lpSrcDIB = (LPBITMAPINFO)GlobalLock(hDib); if (! lpSrcDIB) { WaitCursorBegin(); return FALSE; } // new DIB attributes LPSTR lpPtr; LONG lHeight = DIBHeight(lpSrcDIB); LONG lWidth = DIBWidth(lpSrcDIB); DWORD dwBufferSize = GlobalSize(lpSrcDIB); int nLineBytes = BytesPerLine(lpSrcDIB); // convolute... for (long i=0; i num0) num0 = num; } *lpTempPtr=(unsigned char)num0; /* num=(unsigned char)*lpPtr; if (num==0) { *lpTempPtr=(unsigned char)0; for(i=0;i<3;i++) { num=(unsigned char)*(lpPtr+i-1); if(num==255) { *lpTempPtr=(unsigned char)255; break; } } } else *lpTempPtr=(unsigned char)255; */ lpPtr++; lpTempPtr++; } } } else // Vertical { for (y=1; y num0) num0 = num; } *lpTempPtr=(unsigned char)num0; /* num=(unsigned char)*lpPtr; if (num==0) { *lpTempPtr=(unsigned char)0; for(i=0;i<3;i++) { num=(unsigned char)*(lpPtr+(i-1)*nLineBytes); if(num==255) { *lpTempPtr=(unsigned char)255; break; } } } else *lpTempPtr=(unsigned char)255; */ lpPtr++; lpTempPtr++; } } } // cleanup GlobalUnlock(hDib); GlobalUnlock(hNewDIB); GlobalFree(hNewDIB); WaitCursorEnd(); return TRUE; } /************************************************************************* * * DilationDIB() * * Parameters: * * HDIB hDib - objective DIB handle * BOOL bHori - dilation direction * * Return Value: * * BOOL - True is success, else False * * Description: * * This function do dilation with the specified direction * ************************************************************************/ BOOL DilationDIB(HDIB hDib, BOOL bHori) { // start wait cursor WaitCursorBegin(); // Old DIB buffer if (hDib == NULL) { WaitCursorEnd(); return FALSE; } // only support 256 color image WORD wBitCount = DIBBitCount(hDib); if (wBitCount != 8) { WaitCursorEnd(); return FALSE; } // new DIB HDIB hNewDIB = CopyHandle(hDib); if (! hNewDIB) { WaitCursorEnd(); return FALSE; } // source dib buffer LPBITMAPINFO lpSrcDIB = (LPBITMAPINFO)GlobalLock(hDib); if (! lpSrcDIB) { WaitCursorBegin(); return FALSE; } // New DIB buffer LPBITMAPINFO lpbmi = (LPBITMAPINFO)GlobalLock(hNewDIB); if (! lpbmi) { WaitCursorBegin(); return FALSE; } // start erosion... LPSTR lpPtr; LPSTR lpTempPtr; LONG x,y; BYTE num, num0; int i; LONG lHeight = DIBHeight(lpSrcDIB); LONG lWidth = DIBWidth(lpSrcDIB); DWORD dwBufferSize = GlobalSize(lpSrcDIB); int nLineBytes = BytesPerLine(lpSrcDIB); if(bHori) { for(y=0;y num0) num0 = num; } *lpTempPtr=(unsigned char)num0; /* num=(unsigned char)*lpPtr; if (num==0) { *lpTempPtr=(unsigned char)0; for(i=0;i<3;i++) { num=(unsigned char)*(lpPtr+i-1); if(num==255) { *lpTempPtr=(unsigned char)255; break; } } } else *lpTempPtr=(unsigned char)255; */ lpPtr++; lpTempPtr++; } } } else // Vertical { for (y=1; y num0) num0 = num; } *lpTempPtr=(unsigned char)num0; /* num=(unsigned char)*lpPtr; if (num==0) { *lpTempPtr=(unsigned char)0; for(i=0;i<3;i++) { num=(unsigned char)*(lpPtr+(i-1)*nLineBytes); if(num==255) { *lpTempPtr=(unsigned char)255; break; } } } else *lpTempPtr=(unsigned char)255; */ lpPtr++; lpTempPtr++; } } } // Step 2: original image minues dilation image if(bHori) { for(y=0;y 255) m=255; Point((x 255) a=255; Point(x,nHeight-y-1)=(BYTE)(a); } } delete f; delete W; PutPoints(nWidth,nHeight,lpOutput,lpPoints); delete lpPoints; // recover DWORD dwSize = GlobalSize(hDib); memcpy(lpSrcDIB, lpDIB, dwSize); GlobalUnlock(hDib); GlobalUnlock(hNewDib); if (wBitCount != 24) { hNewDib = ConvertDIBFormat(hDib, wBitCount, NULL); lpSrcDIB = (LPBYTE)GlobalLock(hDIB); lpDIB = (LPBYTE)GlobalLock(hNewDib); dwSize = GlobalSize(hNewDib); memcpy(lpSrcDIB, lpDIB, dwSize); GlobalUnlock(hDIB); GlobalUnlock(hNewDib); } else { lpSrcDIB = (LPBYTE)GlobalLock(hDIB); lpDIB = (LPBYTE)GlobalLock(hDib); dwSize = GlobalSize(hDib); memcpy(lpSrcDIB, lpDIB, dwSize); GlobalUnlock(hDIB); GlobalUnlock(hDib); } // cleanup GlobalFree(hDib); GlobalFree(hNewDib); // return WaitCursorEnd(); return TRUE; } /**************************************************** WALhDIB() 参数: hDIB为输入的DIB句柄 返回值: 成功为TRUE;失败为FALSE 说明: 本函数实现DIB位图的快速沃尔什-哈达玛变换 ****************************************************/ BOOL WALhDIB(HDIB hDIB) { if (hDIB == NULL) return FALSE; // start wait cursor WaitCursorBegin(); HDIB hDib = NULL; HDIB hNewDib = NULL; // we only convolute 24bpp DIB, so first convert DIB to 24bpp WORD wBitCount = DIBBitCount(hDIB); if (wBitCount != 24) { hNewDib = ConvertDIBFormat(hDIB, 24, NULL); hDib = CopyHandle(hNewDib); } else { hNewDib = CopyHandle(hDIB); hDib = CopyHandle(hDIB); } if (hNewDib == NULL && hDib == NULL) { WaitCursorEnd(); return FALSE; } // process! LPBYTE lpSrcDIB = (LPBYTE)GlobalLock(hDib); LPBYTE lpDIB = (LPBYTE)GlobalLock(hNewDib); LPBYTE lpInput = FindDIBBits(lpSrcDIB); LPBYTE lpOutput = FindDIBBits(lpDIB); int nWidth = DIBWidth(lpSrcDIB); int nHeight = DIBHeight(lpSrcDIB); int w=1,h=1,wp=0,hp=0; while(w*2<=nWidth) { w*=2; wp++; } while(h*2<=nHeight) { h*=2; hp++; } int x,y; BYTE *lpPoints=new BYTE[nWidth*nHeight]; GetPoints(nWidth,nHeight,lpInput,lpPoints); double *f=new double[w*h]; double *W=new double[w*h]; for(y=0;y 255) a=255; Point(x,nHeight-y-1)=(BYTE)a; } } delete f; delete W; PutPoints(nWidth,nHeight,lpOutput,lpPoints); delete lpPoints; // recover DWORD dwSize = GlobalSize(hDib); memcpy(lpSrcDIB, lpDIB, dwSize); GlobalUnlock(hDib); GlobalUnlock(hNewDib); if (wBitCount != 24) { hNewDib = ConvertDIBFormat(hDib, wBitCount, NULL); lpSrcDIB = (LPBYTE)GlobalLock(hDIB); lpDIB = (LPBYTE)GlobalLock(hNewDib); dwSize = GlobalSize(hNewDib); memcpy(lpSrcDIB, lpDIB, dwSize); GlobalUnlock(hDIB); GlobalUnlock(hNewDib); } else { lpSrcDIB = (LPBYTE)GlobalLock(hDIB); lpDIB = (LPBYTE)GlobalLock(hDib); dwSize = GlobalSize(hDib); memcpy(lpSrcDIB, lpDIB, dwSize); GlobalUnlock(hDIB); GlobalUnlock(hDib); } // cleanup GlobalFree(hDib); GlobalFree(hNewDib); // return WaitCursorEnd(); return TRUE; }