Screenshot in Tiff speichern



  • Hallo Leute,

    ich nutze die WinApi um einen Screenshot zu erstellen und möchte diesen dann mit Hilfe der LibTiff in einem Tiff Bild speichern.
    Soweit klappt das auch, allerdings ist das Bild dann 4 mal fehlerhaft nebeneinander im Tiff gespeichert und sieht so aus:
    http://imgur.com/a/CT5jw

    Der Beispiel-Code dazu sieht folgendermaßen aus:

    void CreateTiffImage2( )
    {
    
        HDC hScreen = CreateDC( "DISPLAY", NULL, NULL, NULL );
        int width = GetDeviceCaps( hScreen, HORZRES );
        int height = GetDeviceCaps( hScreen, VERTRES );
        HDC     hDC     = CreateCompatibleDC( hScreen );
        HBITMAP hBitmap = CreateCompatibleBitmap( hScreen, width, height );
    
        HGDIOBJ old_obj = SelectObject( hDC, hBitmap );
        BOOL    bRet    = BitBlt( hDC, 0, 0, width, height, hScreen, 0, 0, SRCCOPY );
    
        // get bitmap infos
        BITMAPINFO info ={ 0, };
        info.bmiHeader.biSize = sizeof( BITMAPINFOHEADER );
        auto res = GetDIBits( hDC, hBitmap, 0, height, NULL, &info, DIB_RGB_COLORS );
    
        // prepare buffer and get pixels
        std::vector<RGBQUAD> rgbq( width * height );
        ::GetDIBits( hDC, hBitmap, 0, height, &rgbq[0], &info, DIB_RGB_COLORS );
    
        TIFF* tiff = TIFFOpen( "c:\\test2.tif", "w" );
        if ( tiff )
        {
            TIFFCreateDirectory( tiff );
            TIFFSetField( tiff, TIFFTAG_IMAGEWIDTH, info.bmiHeader.biWidth );
            TIFFSetField( tiff, TIFFTAG_IMAGELENGTH, std::abs( info.bmiHeader.biHeight ) );
            TIFFSetField( tiff, TIFFTAG_BITSPERSAMPLE, info.bmiHeader.biBitCount );
            TIFFSetField( tiff, TIFFTAG_SAMPLESPERPIXEL, 3 );
            TIFFSetField( tiff, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG );
            TIFFSetField( tiff, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT );
            TIFFSetField( tiff, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB );
            TIFFSetField( tiff, TIFFTAG_COMPRESSION, COMPRESSION_LZW );
    
            std::vector<BYTE> vec;
            for ( auto item : rgbq )
            {
                vec.push_back( item.rgbRed );
                vec.push_back( item.rgbGreen );
                vec.push_back( item.rgbBlue );
            }
            vec.push_back( 0 );
            vec.push_back( 0 );
            vec.push_back( 0 );
    
            for ( int y = 0; y < std::abs( info.bmiHeader.biHeight ); y++ )
            {
                res = TIFFWriteScanline( tiff, &vec[y * info.bmiHeader.biWidth * 3], y );
                if ( res != 1 )
                    throw std::exception( "Error adding bitmap to tiff. " + res );
            }
            TIFFFlush( tiff );
        }
    }
    

    Hat jemand eine Idee was ich falsch mache?



  • hmmm ich frage mich immer wieder, warum manche setzen in ihre projeckte irgend-welche fremde dll's ein....in netz gibts DLL/Soft OpenSource als Komplettes Projeckt zum saugen ...saug dir so ein ding runter, dann bist für den rest deines leben glücklich.



  • saug dir irgend-welche DLL/Soft Projeckte alter!



  • Wenn du schon eine externe Bibliothek nutzen möchtest, nimm doch gleich GDIPlus. Die Bitmap-Klasse kann direkt mit HBITMAPs umgehen und auch tiffs speichern (pngs dürften aber bei typischen Screenshots kleiner sein).

    Deinen Code habe ich mir jetzt nicht genauer angeschaut, vermutlich machst du beim wiederholten Umkopieren und beim Zugriff auf die jeweilige Zeile Fehler (siehe top-down vs. bottom-up-Bitmaps, Länge einer Rasterzeile etc.).


Anmelden zum Antworten