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;
    } // write2gif
    

    Ich 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.


Anmelden zum Antworten