//--------------------------------------------------------------------- // // Function: DIBPaint // // Purpose: Painting routine for a DIB. Calls StretchDIBits() or // SetDIBitsToDevice() to paint the DIB. The DIB is // output to the specified DC, at the coordinates given // in lpDCRect. The area of the DIB to be output is // given by lpDIBRect. The specified palette is used. // // Parms: hDC == DC to do output to. // lpDCRect == Rectangle on DC to do output to. // hDIB == Handle to global memory with a DIB spec // in it (either a BITMAPINFO or BITMAPCOREINFO // followed by the DIB bits). // lpDIBRect == Rect of DIB to output into lpDCRect. // hPal == Palette to be used. // // History: Date Reason // 6/01/91 Created // //--------------------------------------------------------------------- static void DIBPaint (HDC hDC,LPRECT lpDCRect,HANDLE hDIB) { LPSTR lpDIBHdr, lpDIBBits; if (!hDIB) return; // Lock down the DIB, and get a pointer to the beginning of the bit // buffer. lpDIBHdr = GlobalLock (hDIB); lpDIBBits = FindDIBBits (lpDIBHdr); // Make sure to use the stretching mode best for color pictures. SetStretchBltMode (hDC, COLORONCOLOR); SetDIBitsToDevice (hDC, // hDC lpDCRect->left, // DestX lpDCRect->top, // DestY RECTWIDTH (lpDCRect), // nDestWidth RECTHEIGHT (lpDCRect), // nDestHeight 0, // SrcX 0, // (int) DIBHeight (lpDIBHdr), // SrcY 0, // nStartScan (WORD) DIBHeight (lpDIBHdr), // nNumScans lpDIBBits, // lpBits (LPBITMAPINFO) lpDIBHdr, // lpBitsInfo DIB_RGB_COLORS); // wUsage GlobalUnlock (hDIB); }
/************************************************************************* * * 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<lHeight; i++) for (long j=0; j<lWidth; j++) { lpPtr=(char *)lpSrcDIB+(dwBufferSize-nLineBytes-i*nLineBytes)+j; *lpPtr = nMaxValue - *lpPtr; } // cleanup GlobalUnlock(hDib); WaitCursorEnd(); return TRUE; }
BOOL WINAPI PaintDIB(HDC hDC, LPRECT lpDCRect, HDIB hDIB, LPRECT lpDIBRect, CPalette* pPal) { LPSTR lpDIBHdr; // Pointer to BITMAPINFOHEADER LPSTR lpDIBBits; // Pointer to DIB bits BOOL bSuccess=FALSE; // Success/fail flag HPALETTE hPal=NULL; // Our DIB's palette HPALETTE hOldPal=NULL; // Previous palette /* Check for valid DIB handle */ if (hDIB == NULL) return FALSE; /* Lock down the DIB, and get a pointer to the beginning of the bit * buffer */ lpDIBHdr = (LPSTR) ::GlobalLock((HGLOBAL) hDIB); lpDIBBits = ::FindDIBBits(lpDIBHdr); // Get the DIB's palette, then select it into DC if (pPal != NULL) { hPal = (HPALETTE) pPal->m_hObject; // Select as background since we have // already realized in forground if needed hOldPal = ::SelectPalette(hDC, hPal, TRUE); } /* Make sure to use the stretching mode best for color pictures */ ::SetStretchBltMode(hDC, COLORONCOLOR); /* Determine whether to call StretchDIBits() or SetDIBitsToDevice() */ if ((RECTWIDTH(lpDCRect) == RECTWIDTH(lpDIBRect)) && (RECTHEIGHT(lpDCRect) == RECTHEIGHT(lpDIBRect))) bSuccess = ::SetDIBitsToDevice(hDC, // hDC lpDCRect->left, // DestX lpDCRect->top, // DestY RECTWIDTH(lpDCRect), // nDestWidth RECTHEIGHT(lpDCRect), // nDestHeight lpDIBRect->left, // SrcX (int)DIBHeight(lpDIBHdr) - lpDIBRect->top - RECTHEIGHT(lpDIBRect), // SrcY 0, // nStartScan (WORD)DIBHeight(lpDIBHdr), // nNumScans lpDIBBits, // lpBits (LPBITMAPINFO)lpDIBHdr, // lpBitsInfo DIB_RGB_COLORS); // wUsage else bSuccess = ::StretchDIBits(hDC, // hDC lpDCRect->left, // DestX lpDCRect->top, // DestY RECTWIDTH(lpDCRect), // nDestWidth RECTHEIGHT(lpDCRect), // nDestHeight lpDIBRect->left, // SrcX lpDIBRect->top, // SrcY RECTWIDTH(lpDIBRect), // wSrcWidth RECTHEIGHT(lpDIBRect), // wSrcHeight lpDIBBits, // lpBits (LPBITMAPINFO)lpDIBHdr, // lpBitsInfo DIB_RGB_COLORS, // wUsage SRCCOPY); // dwROP ::GlobalUnlock((HGLOBAL) hDIB); /* Reselect old palette */ if (hOldPal != NULL) { ::SelectPalette(hDC, hOldPal, TRUE); } return bSuccess; }
BOOL FAR PaintDIB(HDC hDC, LPRECT lpDCRect, HDIB hDIB, LPRECT lpDIBRect, HPALETTE hPal) { LPSTR lpDIBHdr; // Pointer to BITMAPINFOHEADER LPSTR lpDIBBits; // Pointer to DIB bits BOOL bSuccess=FALSE; // Success/fail flag HPALETTE hOldPal=NULL; // Previous palette /* Check for valid DIB handle */ if (!hDIB) return FALSE; /* Lock down the DIB, and get a pointer to the beginning of the bit * buffer */ lpDIBHdr = GlobalLock(hDIB); lpDIBBits = FindDIBBits(lpDIBHdr); /* Select and realize our palette as background */ if (hPal) { hOldPal = SelectPalette(hDC, hPal, TRUE); RealizePalette(hDC); } /* Make sure to use the stretching mode best for color pictures */ SetStretchBltMode(hDC, COLORONCOLOR); /* Determine whether to call StretchDIBits() or SetDIBitsToDevice() */ if ((RECTWIDTH(lpDCRect) == RECTWIDTH(lpDIBRect)) && (RECTHEIGHT(lpDCRect) == RECTHEIGHT(lpDIBRect))) bSuccess = SetDIBitsToDevice(hDC, // hDC lpDCRect->left, // DestX lpDCRect->top, // DestY RECTWIDTH(lpDCRect), // nDestWidth RECTHEIGHT(lpDCRect), // nDestHeight lpDIBRect->left, // SrcX (int)DIBHeight(lpDIBHdr) - lpDIBRect->top - RECTHEIGHT(lpDIBRect), // SrcY 0, // nStartScan (WORD)DIBHeight(lpDIBHdr), // nNumScans lpDIBBits, // lpBits (LPBITMAPINFO)lpDIBHdr, // lpBitsInfo DIB_RGB_COLORS); // wUsage else bSuccess = StretchDIBits(hDC, // hDC lpDCRect->left, // DestX lpDCRect->top, // DestY RECTWIDTH(lpDCRect), // nDestWidth RECTHEIGHT(lpDCRect), // nDestHeight lpDIBRect->left, // SrcX lpDIBRect->top, // SrcY RECTWIDTH(lpDIBRect), // wSrcWidth RECTHEIGHT(lpDIBRect), // wSrcHeight lpDIBBits, // lpBits (LPBITMAPINFO)lpDIBHdr, // lpBitsInfo DIB_RGB_COLORS, // wUsage SRCCOPY); // dwROP /* Unlock the memory block */ GlobalUnlock(hDIB); /* Reselect old palette */ if (hOldPal) SelectPalette(hDC, hOldPal, FALSE); /* Return with success/fail flag */ return bSuccess; }
/************************************************************************* * * 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<lHeight;y++) { lpPtr=(char *)lpbmi+(dwBufferSize-nLineBytes-y*nLineBytes)+1; lpTempPtr=(char *)lpSrcDIB+(dwBufferSize-nLineBytes-y*nLineBytes)+1; for(x=1;x<lWidth-1;x++) { num0 = num = 255; for(i=0;i<3;i++) { num=(unsigned char)*(lpPtr+i-1); if(num < num0) num0 = num; } *lpTempPtr=(unsigned char)num0; /* num=(unsigned char)*lpPtr; if (num==255) { *lpTempPtr=(unsigned char)255; for(i=0;i<3;i++) { num=(unsigned char)*(lpPtr+i-1); if(num==0) { *lpTempPtr=(unsigned char)0; break; } } } else *lpTempPtr=(unsigned char)0; */ lpPtr++; lpTempPtr++; } } } else { for(y=1;y<lHeight-1;y++) { lpPtr=(char *)lpbmi+(dwBufferSize-nLineBytes-y*nLineBytes); lpTempPtr=(char *)lpSrcDIB+(dwBufferSize-nLineBytes-y*nLineBytes); for(x=0;x<lWidth;x++) { num0 = num = 255; for(i=0;i<3;i++) { num=(unsigned char)*(lpPtr+i-1); if(num < num0) num0 = num; } *lpTempPtr=(unsigned char)num0; /* num=(unsigned char)*lpPtr; if (num==255) { *lpTempPtr=(unsigned char)255; for(i=0;i<3;i++) { num=(unsigned char)*(lpPtr+(i-1)*nLineBytes); if(num==0) { *lpTempPtr=(unsigned char)0; break; } } } else *lpTempPtr=(unsigned char)0; */ lpPtr++; lpTempPtr++; } } } // cleanup GlobalUnlock(hDib); GlobalUnlock(hNewDIB); GlobalFree(hNewDIB); WaitCursorEnd(); return TRUE; }
/************************************************************************* * * 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<wDIBHeight-1; i++) for (int j=1; j<wDIBWidth-1; j++) { int red=0, green=0, blue=0; DoMedianFilterDIB(&red, &green, &blue, i, j, wBytesPerLine, lpDIBits); LONG 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; }
/************************************************************************* * * ConvoluteDIB() * * Parameters: * * HDIB hDib - objective DIB handle * KERNEL *lpKernel - pointer of kernel used to convolute with DIB * int Strength - operation strength set to the convolute * int nKernelNum - kernel number used to convolute * * Return Value: * * BOOL - True is success, else False * * Description: * * This is the generic convolute function to DIB * ************************************************************************/ BOOL ConvoluteDIB(HDIB hDib, KERNEL *lpKernel, int Strength, int nKernelNum) { 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<wDIBHeight-1; i++) for (int j=1; j<wDIBWidth-1; j++) { int red=0, green=0, blue=0; for (int k=0; k<nKernelNum; ++k) { int r=0, g=0, b=0; DoConvoluteDIB(&r, &g, &b, i, j, wBytesPerLine, lpDIBits, lpKernel+k); if (r > 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; }
/**************************************************** 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<h;y++) { for(x=0;x<w;x++) { f[x+y*w]=Point(x,y); } } for(y=0;y<h;y++) { WALh(f+w*y,W+w*y,wp); } for(y=0;y<h;y++) { for(x=0;x<w;x++) { f[x*h+y]=W[x+w*y]; } } for(x=0;x<w;x++) { WALh(f+x*h,W+x*h,hp); } double a; memset(lpPoints,0,nWidth*nHeight); for(y=0;y<h;y++) { for(x=0;x<w;x++) { a=fabs(W[x*h+y]*1000); if (a>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; }
/**************************************************** FFTDIB() 参数: hDIB为输入的DIB句柄 返回值: 成功为TRUE;失败为FALSE 说明: 本函数实现DIB位图的快速傅立叶变换 ****************************************************/ BOOL FFTDIB(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); COMPLEX *TD=new COMPLEX[w*h]; COMPLEX *FD=new COMPLEX[w*h]; for(y=0;y<h;y++) { for(x=0;x<w;x++) { TD[x+w*y].re=Point(x,y); TD[x+w*y].im=0; } } for(y=0;y<h;y++) { FFT(&TD[w*y],&FD[w*y],wp); } for(y=0;y<h;y++) { for(x=0;x<w;x++) { TD[y+h*x]=FD[x+w*y]; // TD[x+w*y]=FD[x*h+y]; } } for(x=0;x<w;x++) { FFT(&TD[x*h],&FD[x*h],hp); } memset(lpPoints,0,nWidth*nHeight); double m; for(y=0;y<h;y++) { for(x=0;x<w;x++) { m=sqrt(FD[x*h+y].re*FD[x*h+y].re+FD[x*h+y].im*FD[x*h+y].im)/100; if (m>255) m=255; Point((x<w/2?x+w/2:x-w/2),nHeight-1-(y<h/2?y+h/2:y-h/2))=(BYTE)(m); } } delete TD; delete FD; 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; }
/************************************************************************* * * ThinningDIB() * * Parameters: * * HDIB hDib - objective DIB handle * * Return Value: * * BOOL - True is success, else False * * Description: * * This function thins a DIB * ************************************************************************/ BOOL ThinningDIB(HDIB hDib) { static int erasetable[256]= { 0,0,1,1,0,0,1,1, 1,1,0,1,1,1,0,1, 1,1,0,0,1,1,1,1, 0,0,0,0,0,0,0,1, 0,0,1,1,0,0,1,1, 1,1,0,1,1,1,0,1, 1,1,0,0,1,1,1,1, 0,0,0,0,0,0,0,1, 1,1,0,0,1,1,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 1,1,0,0,1,1,0,0, 1,1,0,1,1,1,0,1, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,1,1,0,0,1,1, 1,1,0,1,1,1,0,1, 1,1,0,0,1,1,1,1, 0,0,0,0,0,0,0,1, 0,0,1,1,0,0,1,1, 1,1,0,1,1,1,0,1, 1,1,0,0,1,1,1,1, 0,0,0,0,0,0,0,0, 1,1,0,0,1,1,0,0, 0,0,0,0,0,0,0,0, 1,1,0,0,1,1,1,1, 0,0,0,0,0,0,0,0, 1,1,0,0,1,1,0,0, 1,1,0,1,1,1,0,0, 1,1,0,0,1,1,1,0, 1,1,0,0,1,0,0,0 }; // 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; LONG lHeight = DIBHeight(lpSrcDIB); LONG lWidth = DIBWidth(lpSrcDIB); DWORD dwBufferSize = GlobalSize(lpSrcDIB); int nLineBytes = BytesPerLine(lpSrcDIB); int nw,n,ne,w,e,sw,s,se; BOOL Finished=FALSE; while(!Finished) { Finished=TRUE; for (y=1;y<lHeight-1;y++) { lpPtr=(char *)lpbmi+(dwBufferSize-nLineBytes-y*nLineBytes); lpTempPtr=(char *)lpSrcDIB+(dwBufferSize-nLineBytes-y*nLineBytes); x=1; while(x<lWidth-1) { if(*(lpPtr+x)==0) { w=(unsigned char)*(lpPtr+x-1); e=(unsigned char)*(lpPtr+x+1); if( (w==255)|| (e==255)) { nw=(unsigned char)*(lpPtr+x+nLineBytes-1); n=(unsigned char)*(lpPtr+x+nLineBytes); ne=(unsigned char)*(lpPtr+x+nLineBytes+1); sw=(unsigned char)*(lpPtr+x-nLineBytes-1); s=(unsigned char)*(lpPtr+x-nLineBytes); se=(unsigned char)*(lpPtr+x-nLineBytes+1); num=nw/255+n/255*2+ne/255*4+w/255*8+e/255*16+sw/255*32+s/255*64+se/255*128; if(erasetable[num]==1) { *(lpPtr+x)=(BYTE)255; *(lpTempPtr+x)=(BYTE)255; Finished=FALSE; x++; } } } x++; } } for (x=1;x<lWidth-1;x++) { y=1; while(y<lHeight-1) { lpPtr=(char *)lpbmi+(dwBufferSize-nLineBytes-y*nLineBytes); lpTempPtr=(char *)lpSrcDIB+(dwBufferSize-nLineBytes-y*nLineBytes); if(*(lpPtr+x)==0) { n=(unsigned char)*(lpPtr+x+nLineBytes); s=(unsigned char)*(lpPtr+x-nLineBytes); if( (n==255)|| (s==255)) { nw=(unsigned char)*(lpPtr+x+nLineBytes-1); ne=(unsigned char)*(lpPtr+x+nLineBytes+1); w=(unsigned char)*(lpPtr+x-1); e=(unsigned char)*(lpPtr+x+1); sw=(unsigned char)*(lpPtr+x-nLineBytes-1); se=(unsigned char)*(lpPtr+x-nLineBytes+1); num=nw/255+n/255*2+ne/255*4+w/255*8+e/255*16+sw/255*32+s/255*64+se/255*128; if(erasetable[num]==1) { *(lpPtr+x)=(BYTE)255; *(lpTempPtr+x)=(BYTE)255; Finished=FALSE; y++; } } } y++; } } } // cleanup GlobalUnlock(hDib); GlobalUnlock(hNewDIB); GlobalFree(hNewDIB); return TRUE; }
DWORD PrintABand (HDC hDC, LPRECT lpRectOut, LPRECT lpRectClip, BOOL fDoText, BOOL fDoGraphics, LPSTR lpDIBHdr, LPSTR lpDIBBits) { int nxLogPix, nyLogPix; RECT rect; double dblXScaling, dblYScaling; DWORD dwError = ERR_PRN_NONE; if (fDoGraphics) { nxLogPix = GetDeviceCaps (hDC, LOGPIXELSX); nyLogPix = GetDeviceCaps (hDC, LOGPIXELSY); dblXScaling = ((double) lpRectOut->right - lpRectOut->left) / DIBWidth (lpDIBHdr); dblYScaling = ((double) lpRectOut->bottom - lpRectOut->top) / DIBHeight (lpDIBHdr); // Now we set up a temporary rectangle -- this rectangle // holds the coordinates on the paper where our bitmap // WILL be output. We can intersect this rectangle with // the lpClipRect to see what we NEED to output to this // band. Then, we determine the coordinates in the DIB // to which this rectangle corresponds (using dbl?Scaling). IntersectRect (&rect, lpRectOut, lpRectClip); if (!IsRectEmpty (&rect)) { RECT rectIn; int nPct; rectIn.left = (int) ((rect.left - lpRectOut->left) / dblXScaling + 0.5); rectIn.top = (int) ((rect.top - lpRectOut->top) / dblYScaling + 0.5); rectIn.right = (int) (rectIn.left + (rect.right - rect.left) / dblXScaling + 0.5); rectIn.bottom = (int) (rectIn.top + (rect.bottom - rect.top) / dblYScaling + 0.5); // Could just always call StretchDIBits() below, but // we want to give SetDIBitsToDevice() a work out, too! if ((rect.right - rect.left == rectIn.right - rectIn.left) && (rect.bottom - rect.top == rectIn.bottom - rectIn.top)) { if (!SetDIBitsToDevice (hDC, // DestDC rect.left, // DestX rect.top, // DestY rect.right - rect.left, // DestWidth rect.bottom - rect.top, // DestHeight rectIn.left, // SrcX (int) DIBHeight (lpDIBHdr)-// SrcY rectIn.top - (rectIn.bottom - rectIn.top), 0, // nStartScan (int) DIBHeight (lpDIBHdr),// nNumScans lpDIBBits, // lpBits (LPBITMAPINFO) lpDIBHdr, // lpBitInfo DIB_RGB_COLORS)) // wUsage dwError |= ERR_PRN_SETDIBITSTODEV; } else { if (!StretchDIBits (hDC, // DestDC rect.left, // DestX rect.top, // DestY rect.right - rect.left, // DestWidth rect.bottom - rect.top, // DestHeight rectIn.left, // SrcX (int) DIBHeight (lpDIBHdr) - // SrcY rectIn.top - (rectIn.bottom - rectIn.top), rectIn.right - rectIn.left, // SrcWidth rectIn.bottom - rectIn.top, // SrcHeight lpDIBBits, // lpBits (LPBITMAPINFO) lpDIBHdr, // lpBitInfo DIB_RGB_COLORS, // wUsage SRCCOPY)) // dwROP dwError |= ERR_PRN_STRETCHDIBITS; } // Change percentage of print shown in abort dialog. nPct = MulDiv (rect.bottom, 100, lpRectOut->bottom); ChangePrintPercent (nPct); } } I_UNUSED(nyLogPix); I_UNUSED(nxLogPix); I_UNUSED(fDoText); return dwError; }
DWORD DIBPrint (HDC hPrnDC, HANDLE hDIB, LPRECT lpPrintRect, WORD wUnits, DWORD dwROP, BOOL fBanding, BOOL fUse31APIs) { RECT rect; LPSTR lpDIBHdr, lpBits; // Do some setup (like getting pointers to the DIB and its header, // and a printer DC). Also, set the global gbUseEscapes to force // using printer escapes or the 3.1 printing API. if (!hDIB) return 0; gbUseEscapes = !fUse31APIs; lpDIBHdr = (LPSTR)GlobalLock (hDIB); lpBits = FindDIBBits (lpDIBHdr); if (hPrnDC) { SetStretchBltMode (hPrnDC, COLORONCOLOR); TranslatePrintRect (hPrnDC, lpPrintRect, wUnits, (WORD) DIBWidth (lpDIBHdr), (WORD) DIBHeight (lpDIBHdr)); // Initialize the abort procedure. Then STARTDOC. bAbort = FALSE; if (fBanding) BandDIBToPrinter (hPrnDC, lpDIBHdr, lpBits, lpPrintRect); else { // When not doing banding, call PrintABand() to dump the // entire page to the printer in one shot (i.e. give it // a band that covers the entire printing rectangle, // and tell it to print graphics and text). rect = *lpPrintRect; PrintABand (hPrnDC, lpPrintRect, &rect, TRUE, TRUE, lpDIBHdr, lpBits); // Non-banding devices need the NEWFRAME or EndPage() call. } } // All done, clean up. GlobalUnlock (hDIB); I_UNUSED(dwROP); return 1; }