[SFML 3.0.2] Kopiowanie sf::Image wraz z kanałem alfa do schowka
Ostatnio zmodyfikowano 2025-11-07 21:05
tBane Temat założony przez niniejszego użytkownika |
[SFML 3.0.2] Kopiowanie sf::Image wraz z kanałem alfa do schowka » 2025-11-07 12:29:17 Witam. Jak skopiować sf::Image wraz z kanałem alfa (przezroczystością) do schowka systemowego? Mam kod ale nie obsługuje kanału alfa :-/ Kopioweanie bez kanału alfabool copyImageToClipboard( sf::Image & image, sf::IntRect rect ) { if( image.getSize().x == 0 || image.getSize().y == 0 ) { return false; } int x0 = std::clamp( rect.position.x, 0, int( image.getSize().x ) ); int y0 = std::clamp( rect.position.y, 0, int( image.getSize().y ) ); int x1 = std::clamp( rect.position.x + rect.size.x, 0, int( image.getSize().x ) ); int y1 = std::clamp( rect.position.y + rect.size.y, 0, int( image.getSize().y ) ); std::wcout << x0 << "\n"; std::wcout << y0 << "\n"; std::wcout << x1 << "\n"; std::wcout << y1 << "\n"; const unsigned int w =( x1 > x0 ) ? unsigned( x1 - x0 ) : 0u; const unsigned int h =( y1 > y0 ) ? unsigned( y1 - y0 ) : 0u; sf::IntRect r( { 0, 0 }, { int( image.getSize().x ), int( image.getSize().y ) } ); if( !rect.findIntersection( r ).has_value() || w == 0 || h == 0 ) { if( w == 0 ) std::cout << " w is 0\n"; if( h == 0 ) std::cout << " h is 0\n"; return false; } const uint8_t * pixels = image.getPixelsPtr(); BITMAPINFOHEADER bi { }; bi.biSize = sizeof( BITMAPINFOHEADER ); bi.biWidth = LONG( w ); bi.biHeight = - LONG( h ); bi.biPlanes = 1; bi.biBitCount = 32; bi.biCompression = BI_RGB; const SIZE_T pixelBytes = SIZE_T( w ) * SIZE_T( h ) * 4; HGLOBAL hMem = GlobalAlloc( GHND, sizeof( BITMAPINFOHEADER ) + pixelBytes ); if( !hMem ) return false; void * pMem = GlobalLock( hMem ); auto * pHeader = static_cast < BYTE * >( pMem ); auto * dstPixels = pHeader + sizeof( BITMAPINFOHEADER ); std::memcpy( pHeader, & bi, sizeof( BITMAPINFOHEADER ) ); for( unsigned int y = 0; y < h; ++y ) { const uint8_t * srcRow = pixels +(( y0 + y ) * image.getSize().x + x0 ) * 4; uint8_t * dstRow = dstPixels +( y * w ) * 4; for( unsigned int x = 0; x < w; ++x ) { const uint8_t r = srcRow[ 4 * x + 0 ]; const uint8_t g = srcRow[ 4 * x + 1 ]; const uint8_t b = srcRow[ 4 * x + 2 ]; const uint8_t a = srcRow[ 4 * x + 3 ]; dstRow[ 4 * x + 0 ] = b; dstRow[ 4 * x + 1 ] = g; dstRow[ 4 * x + 2 ] = r; dstRow[ 4 * x + 3 ] = a; } } GlobalUnlock( hMem ); if( !OpenClipboard( nullptr ) ) { GlobalFree( hMem ); return false; } EmptyClipboard(); if( !SetClipboardData( CF_DIB, hMem ) ) { CloseClipboard(); GlobalFree( hMem ); return false; } CloseClipboard(); return true; }
|
|
tBane Temat założony przez niniejszego użytkownika |
» 2025-11-07 21:05:02 bool copyImageToClipboard( sf::Image & image, sf::IntRect rect ) { const auto imgW = static_cast < int >( image.getSize().x ); const auto imgH = static_cast < int >( image.getSize().y ); if( imgW == 0 || imgH == 0 ) return false; const sf::IntRect imgRect( { 0, 0 }, { imgW, imgH } ); std::optional < sf::IntRect > interOpt = rect.findIntersection( imgRect ); if( !interOpt.has_value() ) { std::cout << "Brak przeciecia z obrazem.\n"; return false; } const sf::IntRect inter = * interOpt; const int x0 = inter.position.x; const int y0 = inter.position.y; const unsigned w = static_cast < unsigned >( inter.size.x > 0 ? inter.size.x: 0 ); const unsigned h = static_cast < unsigned >( inter.size.y > 0 ? inter.size.y: 0 ); if( w == 0 || h == 0 ) { if( w == 0 ) std::cout << "w == 0\n"; if( h == 0 ) std::cout << "h == 0\n"; return false; } std::wcout << x0 << L"\n" << y0 << L"\n" <<( x0 + static_cast < int >( w ) ) << L"\n" <<( y0 + static_cast < int >( h ) ) << L"\n"; const uint8_t * src = image.getPixelsPtr(); BITMAPINFOHEADER bi { }; bi.biSize = sizeof( BITMAPINFOHEADER ); bi.biWidth = static_cast < LONG >( w ); bi.biHeight = - static_cast < LONG >( h ); bi.biPlanes = 1; bi.biBitCount = 32; bi.biCompression = BI_RGB; bi.biSizeImage = w * h * 4; const SIZE_T headerSize = sizeof( BITMAPINFOHEADER ); const SIZE_T pixelBytes = static_cast < SIZE_T >( w ) * static_cast < SIZE_T >( h ) * 4; HGLOBAL hMem = GlobalAlloc( GMEM_MOVEABLE | GMEM_ZEROINIT, headerSize + pixelBytes ); if( !hMem ) return false; void * pMem = GlobalLock( hMem ); if( !pMem ) { GlobalFree( hMem ); return false; } auto * pHeader = static_cast < uint8_t * >( pMem ); auto * dstPixels = pHeader + headerSize; std::memcpy( pHeader, & bi, headerSize ); const unsigned srcStride = static_cast < unsigned >( image.getSize().x ) * 4; const unsigned dstStride = w * 4; for( unsigned y = 0; y < h; ++y ) { const uint8_t * srcRow = src +( static_cast < unsigned >( y0 ) + y ) * srcStride + static_cast < unsigned >( x0 ) * 4; uint8_t * dstRow = dstPixels + y * dstStride; for( unsigned x = 0; x < w; ++x ) { const uint8_t r = srcRow[ 4 * x + 0 ]; const uint8_t g = srcRow[ 4 * x + 1 ]; const uint8_t b = srcRow[ 4 * x + 2 ]; const uint8_t a = srcRow[ 4 * x + 3 ]; dstRow[ 4 * x + 0 ] = b; dstRow[ 4 * x + 1 ] = g; dstRow[ 4 * x + 2 ] = r; dstRow[ 4 * x + 3 ] = a; } } GlobalUnlock( hMem ); if( !OpenClipboard( nullptr ) ) { GlobalFree( hMem ); return false; } EmptyClipboard(); if( !SetClipboardData( CF_DIB, hMem ) ) { CloseClipboard(); GlobalFree( hMem ); return false; } CloseClipboard(); return true; }
|
|
| « 1 » |