HBITMAP nach DIB konvertieren
-
Wie konvertiere ich nen Bitmap in ne DIB-Section ???
-
Guck mal hier in dem Dreh... ich erinnere mich nur dunkel.
-
soo, hab das Ganze jetzt so gebaut :
BITMAPINFO DIB24toDIB8(HBITMAP hOldBmp24, int cx, int cy) { BITMAPINFO bmInfo8; memset(&bmInfo8,0,sizeof(BITMAPINFO)); bmInfo8.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); bmInfo8.bmiHeader.biWidth = cx; bmInfo8.bmiHeader.biHeight = cy; bmInfo8.bmiHeader.biPlanes = 1; bmInfo8.bmiHeader.biBitCount = 8; bmInfo8.bmiHeader.biCompression = BI_RGB; // erzeuge eine 8 bit DIB BYTE *pBits8=NULL; HBITMAP hBitmap8 = CreateDIBSection(NULL,&bmInfo8,DIB_RGB_COLORS,(void**)&pBits8,NULL,0); // selectiere die 8 bit DIB in einen DC HDC hDC8 = CreateCompatibleDC(NULL); HGDIOBJ hOldBmp8 = SelectObject(hDC8,hBitmap8); // selectiere die 24 bit DIB in nen DC HDC hDC24 = CreateCompatibleDC(hDC8); hOldBmp24 = (HBITMAP) SelectObject(hDC24,hOldBmp24); // blite die DIB24 in die DIB8 // windows macht die frabraum konvertierung für dich StretchBlt(hDC8,0,0,150,150,hDC24,0,0,150,150,SRCCOPY); // Aufräumen SelectObject(hDC24,hOldBmp24); SelectObject(hDC8,hOldBmp8); GetDIBits (hDC8, (HBITMAP) hOldBmp8, 0, cx, &bmInfo8.bmiColors, &bmInfo8, DIB_RGB_COLORS); DeleteDC(hDC24); DeleteDC(hDC8); return bmInfo8; }leider bekomme ich hierdurch einen ziemlich leeren Bereich..
-
Das hier hatte aber noch funktioniert, oder?! Was genau meinst du mit dem "ziemlich leeren Bereich". Wie sieht dein weiterer Code aus?
-
Also die oben genannte Funktion wird von dieser hier aufgerufen :
__declspec ( dllexport ) int CALLBACK SaveClipboard(HWND hWnd, char *filename) { HBITMAP B; BITMAPINFO bmi; // BITMAPINFO *bmi; DEVMODE Dev; /* ClipBoard laden */ EnumDisplaySettings (NULL, ENUM_CURRENT_SETTINGS, &Dev); OpenClipboard(hWnd); B = (HBITMAP ) GetClipboardData(CF_BITMAP); CloseClipboard(); bmi = DIB24toDIB8(B, Dev.dmPelsWidth, Dev.dmPelsHeight); // SaveBitmap (hBitmap, Dev.dmPelsWidth, Dev.dmPelsHeight, filename); write2gif(&bmi, filename, true); DeleteObject(B); // ReleaseDC(hDC); // ReleaseDC(hDCa); return 0; }write2gif ist eine Funktion, die ich im netz gefunden habe und ursrünglich aus Farbdaten, die in einem Array of Char bestanden wegsichert. Die Funktion habe ich ein klein wenig umgebaut. Die Kompressionsalgorithmen zu posten würde glaub ich den Rahmen hier sprengen, aber write2gif sieht so aus :
ulong write2gif(BITMAPINFO *bmi, const char *filename, bool interlaced) /* Opens a binary file of the specified name, writes the complete GIF file format and closes it. In case of success, returns the file size in bytes. Writes an interlaced GIF file if 'interlaced' is true. Parameters and the image are taken from the member variables and methods of class gifwriter. Adapt this function to your own programming environment. Remove all dependencies on class gifwriter, and on Windows unless you're using Visual C++. The following items need to be changed - or not: */ { ulong i; ulong kk,clrused,datadepth; if(!filename) return 0; FILE *f=fopen(filename,"wb"); if(!f) { MessageBox(NULL, "Unable to open file:\n\r", "Error",MB_OK); return 0; } ulong imagesize=bmi->bmiHeader.biSizeImage; /* GIF signature */ fputc('G',f); fputc('I',f); fputc('F',f); fputc('8',f); fputc('7',f); fputc('a',f); /* Screen Descriptor */ kk= bmi->bmiHeader.biWidth; // Screen Width fputc(0xff & kk , f); fputc((0xff00 & kk) / 0x100 , f); kk= bmi->bmiHeader.biHeight; // Screen Height fputc(0xff & kk , f); fputc((0xff00 & kk) / 0x100 , f); clrused=256; // is a power of two between 2 and 256 // compute its exponent 'datadepth' datadepth=0; // (between 1 and 8) for(i=1;i<clrused;i*=2) datadepth++; fputc(0xf0 | (0x7&(datadepth-1)) , f); // write datadepth-1 to the three // least significant bits of byte 5 of // the Screen Descriptor fputc(0x00 , f); // Background color = colortable index 0 fputc(0x00 , f); // Byte 7 must be 0x00 /* Global Color Table */ RGBQUAD rgbq; for(i=0; i<clrused; i++) // write 'clrused' 3-byte entries each { // consisting of the intensity values of red, rgbq=bmi->bmiColors[i]; // green, blue in this order. (The colors are fputc(rgbq.rgbRed , f); // taken and converted from a Windows defined fputc(rgbq.rgbGreen , f); // structure of type "RGBQUAD") fputc(rgbq.rgbBlue , f); } /* Image Descriptor */ fputc(0x2c,f); // Image separator character = ',' fputc(0x00,f); // "Image Left" fputc(0x00,f); fputc(0x00,f); // "Image Top" fputc(0x00,f); kk=bmi->bmiHeader.biWidth; // Image Width fputc(0xff & kk , f); // (low byte first) fputc((0xff00 & kk) / 0x100 , f); kk=bmi->bmiHeader.biHeight; // Image Height fputc(0xff & kk , f); fputc((0xff00 & kk) / 0x100 , f); kk=interlaced ? 0x40 : 0x00; // Byte 10 contains the interlaced flag and fputc(kk|(0x7 & (datadepth-1)),f); // information on the local color table. // There is no local color table if its // most significant bit is reset. ulong filesize=6 + 7 + 3*256 + 10; /* "Raster Data" */ gifcompressor *gc=new gifcompressor; if(gc) filesize += gc->writedatablocks( f , (unsigned char *)bmi->bmiColors , imagesize,bmi->bmiHeader.biWidth , datadepth, interlaced ); delete gc; /* GIF terminator */ fputc(0x3b,f); // tells the decoder software to return // to its calling environment fclose(f); return filesize+1; } // write2gifIch möchte hiermit einen Screenshot als GIF wegsichern. (hab um die GDI+ gebeten, die wird aber in der Firma bis auf weiteres verboten, da sie der Grund für den JPEG-Virus war) Das Ergebnis ist aber immer ein weißes GIF mit 1280 * 1024 Pixeln (wobei die Auflösung korrekt ist, aber mein Bildschirm ist nicht weiß..)
Edit: hab die Funktion hier gefunden.