void CTimeEv::OnTeTakePict() { // CWnd* pWnd = CWnd::GetDesktopWindow(); CWindowDC dc(this); CDC memDC; CRect rect; CBitmap bitmap; CClientDC pDC(this); // pWnd->GetWindowRect(rect); GetWindowRect(rect); memDC.CreateCompatibleDC(&dc); // bitmap.CreateCompatibleBitmap(&dc,rect.right,rect.bottom); bitmap.CreateCompatibleBitmap(&dc,rect.Width(),rect.Height()); CBitmap *oldBM = memDC.SelectObject(&bitmap); // memDC.BitBlt(rect.left, rect.top, rect.Width(), rect.Height(), &dc, 0, 0, SRCCOPY); memDC.BitBlt(0, 0, rect.Width(), rect.Height(), &dc, 0, 0, SRCCOPY); BITMAP bm; bitmap.GetObject(sizeof(bm),&bm); // pDC.BitBlt(0, 0, rect.right, rect.bottom, &memDC, 0, 0, SRCCOPY); pDC.BitBlt(0, 0, rect.Width(), rect.Height(), &memDC, 0, 0, SRCCOPY); CFile file; file.Open("a.pcx",CFile::modeWrite | CFile::modeCreate); CreatePCXHeader(&file,rect.Width(),rect.Height()); short *bmBit; RGBQUAD *rgbQuad; bmBit = (short*) malloc (bm.bmHeight * bm.bmWidthBytes * 2); int n = bitmap.GetBitmapBits(bm.bmHeight * bm.bmWidthBytes, bmBit); rgbQuad = (RGBQUAD*) malloc (bm.bmHeight * bm.bmWidthBytes * sizeof(RGBQUAD)); for (int y=0; y< rect.Height();y++) { for (char hl=0; hl<3; hl++) { for (int x=0; x < rect.Width();x++) { char byte; RGBQUAD rgb; rgb = QuadFromWord( bmBit[y*rect.Width() + x]); if (hl == 0) byte = rgb.rgbRed; if (hl == 1) byte = rgb.rgbGreen; if (hl == 2) byte = rgb.rgbBlue; char toWr; toWr = (char) 0xC1; file.Write(&toWr,1); file.Write(&byte,1); } } } free(bmBit); free(rgbQuad); file.Close(); char txt[300]; sprintf(txt,"type:%d, width:%d, height:%d, widthbytes:%d, planes:%d, BitsPixel:%d,", bm.bmType, bm.bmWidth, bm.bmHeight, bm.bmWidthBytes, bm.bmPlanes, bm.bmBitsPixel); // sprintf(txt,"%d %d", rect.left,rect.right); pDC.TextOut(10,10,txt); memDC.SelectObject(oldBM); MessageBeep(0); }
//////////////////////////////////////////////////////////////// //This function fills a jsmpArray with the RGB values //for the CBitmap. // //It has been improved to handle all legal bitmap formats. // //A jsmpArray is a big array of RGB values, 3 bytes per value. // //Note that rows of pixels are processed bottom to top: //The data in the jsamp array must be arranged top to bottom. //////////////////////////////////////////////////////////////// bool DibToSamps (LPBITMAPINFOHEADER pbBmHdr, int nSampsPerRow, struct jpeg_compress_struct cinfo, JSAMPARRAY jsmpPixels) { // Sanity... ASSERT (pbBmHdr != NULL); ASSERT (nSampsPerRow > 0); int r = 0; int p = 0; int q = 0; int b = 0; int n = 0; int nUnused = 0; int nBytesWide = 0; int nUsed = 0; int nLastBits = 0; int nLastNibs = 0; int nCTEntries = 0; int nRow = 0; int nByte = 0; int nPixel = 0; BYTE bytCTEnt = 0; // The bit count tells you the format of the bitmap: // Decide how many entries will be in the color table (if any) switch (pbBmHdr->biBitCount) { case 1: nCTEntries = 2; // Monochrome break; case 4: nCTEntries = 16; // 16-color break; case 8: nCTEntries = 256; // 256-color break; case 16: case 24: case 32: nCTEntries = 0; // No color table needed break; default: return false; // unsupported format } // Point to the color table and pixels DWORD dwCTab = (DWORD) pbBmHdr + pbBmHdr->biSize; LPRGBQUAD pCTab = (LPRGBQUAD) (dwCTab); LPSTR lpBits = (LPSTR) pbBmHdr + (WORD) pbBmHdr->biSize + (WORD) (nCTEntries * sizeof (RGBQUAD)); // Different formats for the image bits LPBYTE lpPixels = (LPBYTE) lpBits; RGBQUAD* pRgbQs = (RGBQUAD*) lpBits; WORD* wPixels = (WORD*) lpBits; // Set up the jsamps according to the bitmap's format. // Note that rows are processed bottom to top, because // that's how bitmaps are created. switch (pbBmHdr->biBitCount) { case 1: nUsed = (pbBmHdr->biWidth + 7) / 8; nUnused = (((nUsed + 3) / 4) * 4) - nUsed; nBytesWide = nUsed + nUnused; nLastBits = 8 - ((nUsed * 8) - pbBmHdr->biWidth); for (r = 0; r < pbBmHdr->biHeight; r++) { for (p = 0, q = 0; p < nUsed; p++) { nRow = (pbBmHdr->biHeight - r - 1) * nBytesWide; nByte = nRow + p; int nBUsed = (p < (nUsed - 1)) ? 8 : nLastBits; for (b = 0;b < nBUsed; b++) { bytCTEnt = lpPixels[nByte] << b; bytCTEnt = bytCTEnt >> 7; jsmpPixels[r][q + 0] = pCTab[bytCTEnt].rgbRed; jsmpPixels[r][q + 1] = pCTab[bytCTEnt].rgbGreen; jsmpPixels[r][q + 2] = pCTab[bytCTEnt].rgbBlue; q += 3; } } } break; case 4: nUsed = (pbBmHdr->biWidth + 1) / 2; nUnused = (((nUsed + 3) / 4) * 4) - nUsed; nBytesWide = nUsed + nUnused; nLastNibs = 2 - ((nUsed * 2) - pbBmHdr->biWidth); for (r = 0; r < pbBmHdr->biHeight; r++) { for (p = 0, q = 0; p < nUsed; p++) { nRow = (pbBmHdr->biHeight - r - 1) * nBytesWide; nByte = nRow + p; int nNibbles = (p < nUsed - 1) ? 2 : nLastNibs; for(n = 0; n < nNibbles; n++) { bytCTEnt = lpPixels[nByte] << (n * 4); bytCTEnt = bytCTEnt >> (4 - (n * 4)); jsmpPixels[r][q + 0] = pCTab[bytCTEnt].rgbRed; jsmpPixels[r][q + 1] = pCTab[bytCTEnt].rgbGreen; jsmpPixels[r][q + 2] = pCTab[bytCTEnt].rgbBlue; q += 3; } } } break; default: // !!!!??? case 8: // Each byte is a pointer to a pixel color nUnused = (((pbBmHdr->biWidth + 3) / 4) * 4) - pbBmHdr->biWidth; for (r = 0;r < pbBmHdr->biHeight; r++) { for (p = 0,q = 0; p < pbBmHdr->biWidth; p++, q += 3) { nRow = (pbBmHdr->biHeight-r-1) * (pbBmHdr->biWidth + nUnused); nPixel = nRow + p; jsmpPixels[r][q + 0] = pCTab[lpPixels[nPixel]].rgbRed; jsmpPixels[r][q + 1] = pCTab[lpPixels[nPixel]].rgbGreen; jsmpPixels[r][q + 2] = pCTab[lpPixels[nPixel]].rgbBlue; } } break; case 16: // Hi-color (16 bits per pixel) nBytesWide = (pbBmHdr->biWidth); nUnused = (((nBytesWide + 1) / 2) * 2) - nBytesWide; nBytesWide += nUnused; for (r = 0;r < pbBmHdr->biHeight; r++) { for (p = 0, q = 0; p < (nBytesWide-nUnused); p++, q += 3) { nRow = (pbBmHdr->biHeight-r-1) * nBytesWide; nPixel = nRow + p; RGBQUAD quad = QuadFromWord (wPixels[nPixel]); jsmpPixels[r][q + 0] = quad.rgbRed; jsmpPixels[r][q + 1] = quad.rgbGreen; jsmpPixels[r][q + 2] = quad.rgbBlue; } } break; case 24: nBytesWide = (pbBmHdr->biWidth * 3); nUnused = (((nBytesWide + 3) / 4) * 4) - nBytesWide; nBytesWide += nUnused; for (r = 0;r < pbBmHdr->biHeight; r++) { for (p = 0, q = 0; p < (nBytesWide-nUnused); p += 3, q += 3) { nRow = (pbBmHdr->biHeight-r-1) * nBytesWide; nPixel = nRow + p; jsmpPixels[r][q + 0] = lpPixels[nPixel + 2]; // Red jsmpPixels[r][q + 1] = lpPixels[nPixel + 1]; // Green jsmpPixels[r][q + 2] = lpPixels[nPixel + 0]; // Blue } } break; case 32: for (r = 0; r < pbBmHdr->biHeight; r++) { for (p = 0, q = 0; p < pbBmHdr->biWidth; p++, q += 3) { nRow = (pbBmHdr->biHeight - r - 1) * pbBmHdr->biWidth; nPixel = nRow + p; jsmpPixels[r][q + 0] = pRgbQs[nPixel].rgbRed; jsmpPixels[r][q + 1] = pRgbQs[nPixel].rgbGreen; jsmpPixels[r][q + 2] = pRgbQs[nPixel].rgbBlue; } } break; } return true; }
BOOL CJpegFile::DibToSamps(HANDLE hDib, int nSampsPerRow, struct jpeg_compress_struct cinfo, JSAMPARRAY jsmpPixels, char* pcsMsg) { //Sanity... if (hDib == NULL || nSampsPerRow <= 0 || pcsMsg == NULL) { if (pcsMsg !=NULL) pcsMsg="Invalid input data"; return FALSE; } int r=0, p=0, q=0, b=0, n=0, nUnused=0, nBytesWide=0, nUsed=0, nLastBits=0, nLastNibs=0, nCTEntries=0, nRow=0, nByte=0, nPixel=0; BYTE bytCTEnt=0; LPBITMAPINFOHEADER pbBmHdr = (LPBITMAPINFOHEADER)GlobalLock(hDib); switch (pbBmHdr->biBitCount) { case 1: nCTEntries = 2; //Monochrome break; case 4: nCTEntries = 16; //16-color break; case 8: nCTEntries = 256; //256-color break; case 16: case 24: case 32: nCTEntries = 0; //No color table needed break; default: pcsMsg = "Invalid bitmap bit count"; GlobalUnlock(hDib); return FALSE; //Unsupported format } //Point to the color table and pixels DWORD dwCTab = (DWORD)pbBmHdr + pbBmHdr->biSize; LPRGBQUAD pCTab = (LPRGBQUAD)(dwCTab); LPSTR lpBits = (LPSTR)pbBmHdr + (WORD)pbBmHdr->biSize + (WORD)(nCTEntries * sizeof(RGBQUAD)); //Different formats for the image bits LPBYTE lpPixels = (LPBYTE) lpBits; RGBQUAD* pRgbQs = (RGBQUAD*)lpBits; WORD* wPixels = (WORD*) lpBits; //Set up the jsamps according to the bitmap's format. //Note that rows are processed bottom to top, because //that's how bitmaps are created. switch (pbBmHdr->biBitCount) { case 1: nUsed = (pbBmHdr->biWidth + 7) / 8; nUnused = (((nUsed + 3) / 4) * 4) - nUsed; nBytesWide = nUsed + nUnused; nLastBits = 8 - ((nUsed * 8) - pbBmHdr->biWidth); for (r=0; r < pbBmHdr->biHeight; r++) { for (p=0,q=0; p < nUsed; p++) { nRow=(pbBmHdr->biHeight-r-1) * nBytesWide; nByte = nRow + p; int nBUsed = (p <(nUsed-1)) ? 8 : nLastBits; for(b=0; b < nBUsed;b++) { bytCTEnt = lpPixels[nByte] << b; bytCTEnt = bytCTEnt >> 7; jsmpPixels[r][q+0] = pCTab[bytCTEnt].rgbRed; jsmpPixels[r][q+1] = pCTab[bytCTEnt].rgbGreen; jsmpPixels[r][q+2] = pCTab[bytCTEnt].rgbBlue; q += 3; } } } break; case 4: nUsed = (pbBmHdr->biWidth + 1) / 2; nUnused = (((nUsed + 3) / 4) * 4) - nUsed; nBytesWide = nUsed + nUnused; nLastNibs = 2 - ((nUsed * 2) - pbBmHdr->biWidth); for (r=0; r < pbBmHdr->biHeight;r++) { for (p=0,q=0; p < nUsed;p++) { nRow=(pbBmHdr->biHeight-r-1) * nBytesWide; nByte = nRow + p; int nNibbles = (p < nUsed - 1) ? 2 : nLastNibs; for(n=0;n < nNibbles;n++) { bytCTEnt = lpPixels[nByte] << (n*4); bytCTEnt = bytCTEnt >> (4-(n*4)); jsmpPixels[r][q+0] = pCTab[bytCTEnt].rgbRed; jsmpPixels[r][q+1] = pCTab[bytCTEnt].rgbGreen; jsmpPixels[r][q+2] = pCTab[bytCTEnt].rgbBlue; q += 3; } } } break; default: case 8: //Each byte is a pointer to a pixel color nUnused = (((pbBmHdr->biWidth + 3) / 4) * 4) - pbBmHdr->biWidth; for (r=0;r < pbBmHdr->biHeight; r++) { for (p=0,q=0; p < pbBmHdr->biWidth; p++,q+=3) { nRow = (pbBmHdr->biHeight-r-1) * (pbBmHdr->biWidth + nUnused); nPixel = nRow + p; jsmpPixels[r][q+0] = pCTab[lpPixels[nPixel]].rgbRed; jsmpPixels[r][q+1] = pCTab[lpPixels[nPixel]].rgbGreen; jsmpPixels[r][q+2] = pCTab[lpPixels[nPixel]].rgbBlue; } } break; case 16: //Hi-color (16 bits per pixel) for (r=0;r < pbBmHdr->biHeight; r++) { for (p=0,q=0; p < pbBmHdr->biWidth; p++,q+=3) { nRow = (pbBmHdr->biHeight-r-1) * pbBmHdr->biWidth; nPixel = nRow + p; RGBQUAD quad = QuadFromWord(wPixels[nPixel]); jsmpPixels[r][q+0] = quad.rgbRed; jsmpPixels[r][q+1] = quad.rgbGreen; jsmpPixels[r][q+2] = quad.rgbBlue; } } break; case 24: nBytesWide = (pbBmHdr->biWidth*3); nUnused = (((nBytesWide + 3) / 4) * 4) - nBytesWide; nBytesWide += nUnused; for (r=0;r < pbBmHdr->biHeight;r++) { for (p=0,q=0;p < (nBytesWide-nUnused); p+=3,q+=3) { nRow = (pbBmHdr->biHeight-r-1) * nBytesWide; nPixel = nRow + p; jsmpPixels[r][q+0] = lpPixels[nPixel+2]; //Red jsmpPixels[r][q+1] = lpPixels[nPixel+1]; //Green jsmpPixels[r][q+2] = lpPixels[nPixel+0]; //Blue } } break; case 32: for (r=0; r < pbBmHdr->biHeight; r++) { for (p=0,q=0; p < pbBmHdr->biWidth; p++,q+=3) { nRow = (pbBmHdr->biHeight-r-1) * pbBmHdr->biWidth; nPixel = nRow + p; jsmpPixels[r][q+0] = pRgbQs[nPixel].rgbRed; jsmpPixels[r][q+1] = pRgbQs[nPixel].rgbGreen; jsmpPixels[r][q+2] = pRgbQs[nPixel].rgbBlue; } } break; } //end switch GlobalUnlock(hDib); return TRUE; }