bool WICImageLoader::processImage(IWICBitmapDecoder* pDecoder) { HRESULT hr = E_FAIL; IWICBitmapFrameDecode* pFrame = NULL; if(NULL != pDecoder) { hr = pDecoder->GetFrame(0, &pFrame); } if(SUCCEEDED(hr)) { hr = pFrame->GetPixelFormat(&_format); } IWICFormatConverter* pConv = NULL; if(SUCCEEDED(hr)) { hr = convertFormatIfRequired(pFrame, &pConv); } if(SUCCEEDED(hr)) { _bpp = getBitsPerPixel(_format); if(NULL != pConv) { hr = pConv->GetSize((UINT*)&_width, (UINT*)&_height); } else { hr = pFrame->GetSize((UINT*)&_width, (UINT*)&_height); } } assert(_bpp > 0); assert(_width > 0 && _height > 0); if(SUCCEEDED(hr)) { size_t rowPitch = (_width * _bpp + 7) / 8; _dataLen = rowPitch * _height; _data = new (std::nothrow) BYTE[_dataLen]; if(NULL != pConv) { hr = pConv->CopyPixels(NULL, static_cast<UINT>(rowPitch), static_cast<UINT>(_dataLen), _data); } else { hr = pFrame->CopyPixels(NULL, static_cast<UINT>(rowPitch), static_cast<UINT>(_dataLen), _data); } } SafeRelease(&pFrame); SafeRelease(&pConv); return SUCCEEDED(hr); }
void GL::Image::load(const unsigned char *buf, size_t bufSize) { if (CoInitializeEx(NULL, COINIT_MULTITHREADED) != S_OK) { // bad! return; } IStream *stream = SHCreateMemStream((const BYTE*)buf, (UINT)bufSize); if (stream != NULL) { IWICImagingFactory *pFactory; if (CoCreateInstance(CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, IID_IWICImagingFactory, (LPVOID*)&pFactory) == S_OK) { IWICBitmapDecoder *pDecoder; if (pFactory->CreateDecoderFromStream(stream, &CLSID_WICPngDecoder, WICDecodeMetadataCacheOnDemand, &pDecoder) == S_OK) { IWICBitmapFrameDecode *frame; if (pDecoder->GetFrame(0, &frame) == S_OK) { UINT w, h; if (frame->GetSize(&w, &h) == S_OK) { width_ = w; height_ = h; } IWICFormatConverter *formatConverter; if (pFactory->CreateFormatConverter(&formatConverter) == S_OK) { if (formatConverter->Initialize(frame, GUID_WICPixelFormat32bppPBGRA, WICBitmapDitherTypeNone, nullptr, 0.0, WICBitmapPaletteTypeCustom) == S_OK) { unsigned char *pixels = new unsigned char[w * h * 4]; if (formatConverter->CopyPixels(0, w * 4, w * h * 4, pixels) == S_OK) { loadTextureData_(pixels); } delete[] pixels; } formatConverter->Release(); } } pDecoder->Release(); } pFactory->Release(); } stream->Release(); } CoUninitialize(); }
// 解码照片的基础位图文件的. HRESULT VideoEncoder::DecodeFrame(Photo* pPhoto, BYTE** ppOutputBitmap, int* pBitmapSize) { HRESULT hr = S_OK; IWICBitmapDecoder *pDecoder = nullptr; IWICBitmapFrameDecode *pFrame = nullptr; IWICBitmap* pSourceBitmap = nullptr; IWICBitmapLock* pLock = nullptr; BYTE* pSourceBuffer = nullptr; BYTE* pDestinationBuffer = nullptr; UINT pixelWidth; UINT pixelHeight; WICRect lockRect; *ppOutputBitmap = nullptr; hr = m_pIWICFactory->CreateDecoderFromFilename( pPhoto->GetFile().c_str(), nullptr, GENERIC_READ, WICDecodeMetadataCacheOnDemand, &pDecoder ); CheckHR(hr); this->m_logFileStream << "WIC解码器创建成功." << endl; GUID containerFormat; CheckHR(pDecoder->GetContainerFormat(&containerFormat)); // 我们仅支持jpg 文件. if (containerFormat != GUID_ContainerFormatJpeg) { this->m_logFileStream << "仅支持jpeg文件." << endl; return E_NOTSUPPORTEDFORMAT; } // 我们仅支持jpg 文件. 因此只有一桢. CheckHR(pDecoder->GetFrame(0, &pFrame)); // TODO: 目前我们需要所有照片有相同的大小. // 如果需求在将来发生变化,修改代码. pFrame->GetSize(&pixelWidth, &pixelHeight); if (pixelWidth != this->m_frameWidth || pixelHeight != this->m_frameHeight) { this->m_logFileStream << "所有的照片必须使用固定的大小." << endl; return E_IMAGESIZEINCORRECT; } // 创建源位图对象. CheckHR(this->m_pIWICFactory->CreateBitmapFromSource(pFrame, WICBitmapCacheOnLoad, &pSourceBitmap)); this->m_logFileStream << "位图资源创建成功." << endl; lockRect.X = 0; lockRect.Y = 0; lockRect.Width = pixelWidth; lockRect.Height = pixelHeight; CheckHR(pSourceBitmap->Lock(&lockRect, WICBitmapLockWrite, &pLock)); UINT sourceBufferSize; CheckHR(pLock->GetDataPointer(&sourceBufferSize, &pSourceBuffer)); // Jpg BGR 位图转换 RGBA 格式. UINT destinationBufferSize = sourceBufferSize / 3 * 4; pDestinationBuffer = new BYTE[destinationBufferSize]; for (UINT i = 0, j = 0; i < sourceBufferSize; i+=3, j+=4) { pDestinationBuffer[j] = pSourceBuffer[i]; // R pDestinationBuffer[j + 1] = pSourceBuffer[i + 1]; // G pDestinationBuffer[j + 2] = pSourceBuffer[i + 2]; // B pDestinationBuffer[j + 3] = 255; // A } *ppOutputBitmap = pDestinationBuffer; *pBitmapSize = destinationBufferSize; cleanup: if (!SUCCEEDED(hr)) { DWORD error = GetLastError(); this->m_logFileStream << "意外错误: " << error << endl; this->m_logFileStream << "HResult是: " << hr << endl; } if (pSourceBuffer != nullptr) { // 删除pSourceBuffer; } SafeRelease(&pDecoder); SafeRelease(&pFrame); SafeRelease(&pSourceBitmap); SafeRelease(&pLock); return hr; }
HRESULT App::LoadResourceBitmap( ID2D1RenderTarget *pRenderTarget, IWICImagingFactory *pIWICFactory, PCWSTR resourceName, PCWSTR resourceType, UINT destinationWidth, UINT destinationHeight, ID2D1Bitmap **ppBitmap ) { IWICBitmapDecoder *pDecoder = NULL; IWICBitmapFrameDecode *pSource = NULL; IWICStream *pStream = NULL; IWICFormatConverter *pConverter = NULL; IWICBitmapScaler *pScaler = NULL; HRSRC imageResHandle = NULL; HGLOBAL imageResDataHandle = NULL; void *pImageFile = NULL; DWORD imageFileSize = 0; // Locate the resource. imageResHandle = FindResourceW(HINST_THISCOMPONENT, resourceName, resourceType); HRESULT hr = imageResHandle ? S_OK : E_FAIL; if (SUCCEEDED(hr)) { // Load the resource. imageResDataHandle = LoadResource(HINST_THISCOMPONENT, imageResHandle); hr = imageResDataHandle ? S_OK : E_FAIL; } if (SUCCEEDED(hr)) { // Lock it to get a system memory pointer. pImageFile = LockResource(imageResDataHandle); hr = pImageFile ? S_OK : E_FAIL; } if (SUCCEEDED(hr)) { // Calculate the size. imageFileSize = SizeofResource(HINST_THISCOMPONENT, imageResHandle); hr = imageFileSize ? S_OK : E_FAIL; } if (SUCCEEDED(hr)) { // Create a WIC stream to map onto the memory. hr = pIWICFactory->CreateStream(&pStream); } if (SUCCEEDED(hr)) { // Initialize the stream with the memory pointer and size. hr = pStream->InitializeFromMemory( reinterpret_cast<BYTE*>(pImageFile), imageFileSize ); } if (SUCCEEDED(hr)) { // Create a decoder for the stream. hr = pIWICFactory->CreateDecoderFromStream( pStream, NULL, WICDecodeMetadataCacheOnLoad, &pDecoder ); } if (SUCCEEDED(hr)) { // Create the initial frame. hr = pDecoder->GetFrame(0, &pSource); } if (SUCCEEDED(hr)) { // Convert the image format to 32bppPBGRA // (DXGI_FORMAT_B8G8R8A8_UNORM + D2D1_ALPHA_MODE_PREMULTIPLIED). hr = pIWICFactory->CreateFormatConverter(&pConverter); } if (SUCCEEDED(hr)) { // If a new width or height was specified, create an // IWICBitmapScaler and use it to resize the image. if (destinationWidth != 0 || destinationHeight != 0) { UINT originalWidth, originalHeight; hr = pSource->GetSize(&originalWidth, &originalHeight); if (SUCCEEDED(hr)) { if (destinationWidth == 0) { FLOAT scalar = static_cast<FLOAT>(destinationHeight) / static_cast<FLOAT>(originalHeight); destinationWidth = static_cast<UINT>(scalar * static_cast<FLOAT>(originalWidth)); } else if (destinationHeight == 0) { FLOAT scalar = static_cast<FLOAT>(destinationWidth) / static_cast<FLOAT>(originalWidth); destinationHeight = static_cast<UINT>(scalar * static_cast<FLOAT>(originalHeight)); } hr = pIWICFactory->CreateBitmapScaler(&pScaler); if (SUCCEEDED(hr)) { hr = pScaler->Initialize( pSource, destinationWidth, destinationHeight, WICBitmapInterpolationModeCubic ); if (SUCCEEDED(hr)) { hr = pConverter->Initialize( pScaler, GUID_WICPixelFormat32bppPBGRA, WICBitmapDitherTypeNone, NULL, 0.f, WICBitmapPaletteTypeMedianCut ); } } } } else { hr = pConverter->Initialize( pSource, GUID_WICPixelFormat32bppPBGRA, WICBitmapDitherTypeNone, NULL, 0.f, WICBitmapPaletteTypeMedianCut ); } } if (SUCCEEDED(hr)) { //create a Direct2D bitmap from the WIC bitmap. hr = pRenderTarget->CreateBitmapFromWicBitmap( pConverter, NULL, ppBitmap ); } SafeRelease(&pDecoder); SafeRelease(&pSource); SafeRelease(&pStream); SafeRelease(&pConverter); SafeRelease(&pScaler); return hr; }
unsigned char *BBWin8Game::LoadImageData( String path,int *pwidth,int *pheight,int *pformat ){ if( !_wicFactory ){ DXASS( CoCreateInstance( CLSID_WICImagingFactory,0,CLSCTX_INPROC_SERVER,__uuidof(IWICImagingFactory),(LPVOID*)&_wicFactory ) ); } path=PathToFilePath( path ); IWICBitmapDecoder *decoder; if( !SUCCEEDED( _wicFactory->CreateDecoderFromFilename( path.ToCString<wchar_t>(),NULL,GENERIC_READ,WICDecodeMetadataCacheOnDemand,&decoder ) ) ){ return 0; } unsigned char *data=0; IWICBitmapFrameDecode *bitmapFrame; DXASS( decoder->GetFrame( 0,&bitmapFrame ) ); UINT width,height; WICPixelFormatGUID pixelFormat; DXASS( bitmapFrame->GetSize( &width,&height ) ); DXASS( bitmapFrame->GetPixelFormat( &pixelFormat ) ); if( pixelFormat==GUID_WICPixelFormat24bppBGR ){ unsigned char *t=(unsigned char*)malloc( width*3*height ); DXASS( bitmapFrame->CopyPixels( 0,width*3,width*3*height,t ) ); data=(unsigned char*)malloc( width*4*height ); unsigned char *s=t,*d=data; int n=width*height; while( n-- ){ *d++=s[2]; *d++=s[1]; *d++=s[0]; *d++=0xff; s+=3; } free( t ); }else if( pixelFormat==GUID_WICPixelFormat32bppBGRA ){ unsigned char *t=(unsigned char*)malloc( width*4*height ); DXASS( bitmapFrame->CopyPixels( 0,width*4,width*4*height,t ) ); data=t; int n=width*height; while( n-- ){ //premultiply alpha unsigned char r=t[0]; t[0]=t[2]*t[3]/255; t[1]=t[1]*t[3]/255; t[2]=r*t[3]/255; t+=4; } } if( data ){ *pwidth=width; *pheight=height; *pformat=4; } bitmapFrame->Release(); decoder->Release(); gc_force_sweep=true; return data; }
HRESULT LoadBitmapFromFile( PCWSTR uri, UINT dweight, UINT dheight, ID2D1Bitmap **bitmap ) { HRESULT hr = S_OK; IWICImagingFactory* pWICFactory = NULL; IWICBitmapDecoder* pDecoder = NULL; IWICBitmapScaler* pScaler = NULL; IWICBitmapFrameDecode* pSource = NULL; IWICFormatConverter* pConverter = NULL; hr = CoCreateInstance( CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, IID_IWICImagingFactory, (LPVOID*)&pWICFactory); if (SUCCEEDED(hr)) { hr = pWICFactory->CreateDecoderFromFilename( uri, NULL, GENERIC_READ, WICDecodeMetadataCacheOnLoad, &pDecoder); } if (SUCCEEDED(hr)) { hr = pDecoder->GetFrame(0, &pSource); } if (SUCCEEDED(hr)) { hr = pWICFactory->CreateFormatConverter(&pConverter); } if (SUCCEEDED(hr)) { UINT oWeight, oHeight; hr = pSource->GetSize(&oWeight, &oHeight); if (SUCCEEDED(hr)) { hr = pWICFactory->CreateBitmapScaler(&pScaler); if (SUCCEEDED(hr)) { hr = pScaler->Initialize( pSource, dweight, dheight, WICBitmapInterpolationModeCubic); } if (SUCCEEDED(hr)) { hr = pConverter->Initialize( pScaler, GUID_WICPixelFormat32bppPBGRA, WICBitmapDitherTypeNone, NULL, 0.f, WICBitmapPaletteTypeMedianCut ); } } } if (SUCCEEDED(hr)) { hr = pRT->CreateBitmapFromWicBitmap(pConverter, bitmap); } Safe_Release(pWICFactory); Safe_Release(pDecoder); Safe_Release(pScaler); Safe_Release(pSource); Safe_Release(pConverter); return hr; }
// Create a Direct2D bitmap from the specified file name HRESULT DemoApp::LoadBitmapFromFile( ID2D1RenderTarget *pRenderTarget, IWICImagingFactory *pIWICFactory, PCWSTR uri, UINT destinationWidth, UINT destinationHeight, ID2D1Bitmap **ppBitmap) { HRESULT hr = S_OK; IWICBitmapDecoder *pDecoder = NULL; IWICBitmapFrameDecode *pSource = NULL; IWICStream *pStream = NULL; IWICFormatConverter *pConverter = NULL; IWICBitmapScaler *pScaler = NULL; hr = pIWICFactory->CreateDecoderFromFilename( uri, NULL, GENERIC_READ, WICDecodeMetadataCacheOnLoad, &pDecoder); if (SUCCEEDED(hr)) { // Create the initial frame hr = pDecoder->GetFrame(0, &pSource); } if (SUCCEEDED(hr)) { // Convert the image format to 32bppPBGRA // (DXGI_FORMAT_B8G8R8A8_UNORM + D2D1_ALPHA_MODE_PREMULTIPLIED). hr = pIWICFactory->CreateFormatConverter(&pConverter); } if (SUCCEEDED(hr)) { // If a new width or height was specified, create an // IWICBitmapScaler and use it to resize the image. if (destinationWidth != 0 || destinationHeight != 0) { UINT originalWidth, originalHeight; hr = pSource->GetSize(&originalWidth, &originalHeight); if (SUCCEEDED(hr)) { if (destinationWidth == 0) { FLOAT scalar = static_cast<FLOAT>(destinationHeight) / static_cast<FLOAT>(originalHeight); destinationWidth = static_cast<UINT>(scalar * static_cast<FLOAT>(originalWidth)); } else if (destinationHeight == 0) { FLOAT scalar = static_cast<FLOAT>(destinationWidth) / static_cast<FLOAT>(originalWidth); destinationHeight = static_cast<UINT>(scalar * static_cast<FLOAT>(originalHeight)); } hr = pIWICFactory->CreateBitmapScaler(&pScaler); if (SUCCEEDED(hr)) { hr = pScaler->Initialize( pSource, destinationWidth, destinationHeight, WICBitmapInterpolationModeCubic); } if (SUCCEEDED(hr)) { hr = pConverter->Initialize( pScaler, GUID_WICPixelFormat32bppPBGRA, WICBitmapDitherTypeNone, NULL, 0.f, WICBitmapPaletteTypeMedianCut); } } } else // Don't scale the image. { hr = pConverter->Initialize( pSource, GUID_WICPixelFormat32bppPBGRA, WICBitmapDitherTypeNone, NULL, 0.f, WICBitmapPaletteTypeMedianCut); } } if (SUCCEEDED(hr)) { // Create a Direct2D bitmap from the WIC bitmap. hr = pRenderTarget->CreateBitmapFromWicBitmap( pConverter, NULL, ppBitmap); } SafeRelease(&pDecoder); SafeRelease(&pSource); SafeRelease(&pStream); SafeRelease(&pConverter); SafeRelease(&pScaler); return hr; }
ID2D1Bitmap * BaseButton::LoadBitmap(wchar_t* sz_path) { ID2D1Bitmap *p_bmp=NULL; IWICBitmapDecoder *pDecoder = NULL; IWICBitmapFrameDecode *pSource = NULL; IWICStream *pStream = NULL; IWICFormatConverter *pConverter = NULL; IWICBitmapScaler *pScaler = NULL; HRESULT hr; hr = g_pIWICFactory->CreateDecoderFromFilename(sz_path,NULL,GENERIC_READ,WICDecodeMetadataCacheOnLoad,&pDecoder); if (SUCCEEDED(hr)) { // Create the initial frame. hr = pDecoder->GetFrame(0, &pSource); } if (SUCCEEDED(hr)) { // Convert the image format to 32bppPBGRA // (DXGI_FORMAT_B8G8R8A8_UNORM + D2D1_ALPHA_MODE_PREMULTIPLIED). hr = g_pIWICFactory->CreateFormatConverter(&pConverter); } if (SUCCEEDED(hr)) { // If a new width or height was specified, create an // IWICBitmapScaler and use it to resize the image. UINT originalWidth, originalHeight; hr = pSource->GetSize(&originalWidth, &originalHeight); } if (SUCCEEDED(hr)) { hr =g_pIWICFactory->CreateBitmapScaler(&pScaler); } if (SUCCEEDED(hr)) { hr = pScaler->Initialize(pSource,50,30,WICBitmapInterpolationModeCubic); } if (SUCCEEDED(hr)) { hr = pConverter->Initialize(pScaler,GUID_WICPixelFormat32bppPBGRA,WICBitmapDitherTypeNone,NULL,0.f,WICBitmapPaletteTypeMedianCut); } if (SUCCEEDED(hr)) { // Create a Direct2D bitmap from the WIC bitmap. hr =m_pRenderTarget->CreateBitmapFromWicBitmap(pConverter,NULL,&p_bmp); } SafeRelease(&pDecoder); SafeRelease(&pSource); SafeRelease(&pStream); SafeRelease(&pConverter); SafeRelease(&pScaler); // if (SUCCEEDED(hr)) // { // return TRUE; // } // else // return FALSE; return p_bmp; }
bool Image::Initialize(wchar_t *filename, Graphics *graphics) { std::ifstream file; IWICImagingFactory *pWIC; IWICStream *stream; IWICBitmapDecoder *decoder; IWICBitmapFrameDecode *frame; unsigned int width, height, twidth, theight, maxsize, bpp, i, support, rowPitch, imageSize; float ratio; WICPixelFormatGUID pixelFormat; DXGI_FORMAT format; IWICComponentInfo *cinfo; IWICPixelFormatInfo *pfinfo; IWICBitmapScaler *scaler; bool autogen = false; D3D11_TEXTURE2D_DESC desc; D3D11_SUBRESOURCE_DATA initData; D3D11_SHADER_RESOURCE_VIEW_DESC SRVDesc; file.open(filename, std::ios::in | std::ios::binary | std::ios::ate); if(!file.is_open()) return false; m_size = file.tellg(); file.seekg(0, std::ios::beg); m_bytes = new unsigned char [m_size]; file.read((char *)m_bytes, m_size); file.close(); RETURN_FAIL( CoCreateInstance( CLSID_WICImagingFactory, nullptr, CLSCTX_INPROC_SERVER, __uuidof(IWICImagingFactory), (LPVOID*)&pWIC ) ); RETURN_FAIL( pWIC->CreateStream( &stream ) ); RETURN_FAIL( stream->InitializeFromMemory( m_bytes, m_size ) ); RETURN_FAIL( pWIC->CreateDecoderFromStream( stream, 0, WICDecodeMetadataCacheOnDemand, &decoder ) ); RETURN_FAIL( decoder->GetFrame( 0, &frame ) ); RETURN_FAIL( frame->GetSize( &width, &height ) ); SAFE_RELEASE( stream ); SAFE_RELEASE( decoder ); if( width <= 0 || height <= 0 ) return false; maxsize = D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION; if( width > maxsize || height > maxsize ) { ratio = static_cast<float>(height) / static_cast<float>(width); if(width > height) { twidth = maxsize; theight = static_cast<unsigned int>( static_cast<float>(maxsize) * ratio ); } else { theight = maxsize; twidth = static_cast<unsigned int>( static_cast<float>(maxsize) / ratio ); } } else { twidth = width; theight = height; } RETURN_FAIL( frame->GetPixelFormat( &pixelFormat ) ); format = DXGI_FORMAT_UNKNOWN; for( i = 0; i < _countof(g_WICFormats); ++i ) { if( memcmp( &g_WICFormats[i].wic, &pixelFormat, sizeof(GUID) ) == 0 ) { format = g_WICFormats[i].dxgi; break; } } RETURN_FAIL( pWIC->CreateComponentInfo( pixelFormat, &cinfo ) ); RETURN_FAIL( cinfo->QueryInterface( __uuidof(IWICPixelFormatInfo), (LPVOID*)&pfinfo ) ); RETURN_FAIL( pfinfo->GetBitsPerPixel( &bpp ) ); SAFE_RELEASE( cinfo ); SAFE_RELEASE( pfinfo ); RETURN_FAIL( graphics->GetDevice()->CheckFormatSupport( format, &support ) ); if( !(support & D3D11_FORMAT_SUPPORT_TEXTURE2D) ) return false; rowPitch = ( twidth * bpp + 7 ) / 8; imageSize = rowPitch * theight; std::unique_ptr<uint8_t[]> temp( new (std::nothrow) uint8_t[ imageSize ] ); if( !temp ) return false; if( twidth == width && theight == height ) { RETURN_FAIL( frame->CopyPixels( 0, rowPitch, imageSize, temp.get() ) ); } else { RETURN_FAIL( pWIC->CreateBitmapScaler( &scaler ) ); RETURN_FAIL( scaler->Initialize( frame, twidth, theight, WICBitmapInterpolationModeFant ) ); RETURN_FAIL( scaler->CopyPixels( 0, rowPitch, imageSize, temp.get() ) ); SAFE_RELEASE( scaler ); } SAFE_RELEASE( frame ); if( support & D3D11_FORMAT_SUPPORT_MIP_AUTOGEN ) { autogen = true; } desc.Width = twidth; desc.Height = theight; desc.MipLevels = (autogen) ? 0 : 1; desc.ArraySize = 1; desc.Format = format; desc.SampleDesc.Count = 1; desc.SampleDesc.Quality = 0; desc.Usage = D3D11_USAGE_DEFAULT; desc.CPUAccessFlags = 0; desc.BindFlags = (autogen) ? D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET : D3D11_BIND_SHADER_RESOURCE; desc.MiscFlags = (autogen) ? D3D11_RESOURCE_MISC_GENERATE_MIPS : 0; initData.pSysMem = temp.get(); initData.SysMemPitch = rowPitch; initData.SysMemSlicePitch = imageSize; RETURN_FAIL( graphics->GetDevice()->CreateTexture2D( &desc, (autogen) ? nullptr : &initData, &m_texture2D ) ); //ZeroMemory( &SRVDesc, sizeof( SRVDesc ) ); memset( &SRVDesc, 0, sizeof( SRVDesc ) ); SRVDesc.Format = desc.Format; SRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; SRVDesc.Texture2D.MipLevels = (autogen) ? -1 : 1; RETURN_FAIL( graphics->GetDevice()->CreateShaderResourceView( m_texture2D, &SRVDesc, &m_shaderResourceView ) ); if( autogen ) { graphics->GetContext()->UpdateSubresource( m_texture2D, 0, nullptr, temp.get(), rowPitch, imageSize ); graphics->GetContext()->GenerateMips( m_shaderResourceView ); } SAFE_RELEASE(pWIC); }
HRESULT touchmind::Context::LoadResourceBitmap(ID2D1RenderTarget *pRenderTarget, IWICImagingFactory *pIWICFactory, PCWSTR resourceName, PCWSTR resourceType, UINT destinationWidth, UINT destinationHeight, ID2D1Bitmap **ppBitmap) { #ifdef TOUCHMIND_CONTEXT_DEBUG LOG_ENTER; #endif HRESULT hr = S_OK; IWICBitmapDecoder *pDecoder = nullptr; IWICBitmapFrameDecode *pSource = nullptr; IWICStream *pStream = nullptr; IWICFormatConverter *pConverter = nullptr; IWICBitmapScaler *pScaler = nullptr; HRSRC imageResHandle = nullptr; HGLOBAL imageResDataHandle = nullptr; void *pImageFile = nullptr; DWORD imageFileSize = 0; imageResHandle = FindResourceW(HINST_THISCOMPONENT, resourceName, resourceType); hr = imageResHandle ? S_OK : E_FAIL; if (SUCCEEDED(hr)) { imageResDataHandle = LoadResource(HINST_THISCOMPONENT, imageResHandle); hr = imageResDataHandle ? S_OK : E_FAIL; } if (SUCCEEDED(hr)) { pImageFile = LockResource(imageResDataHandle); hr = pImageFile ? S_OK : E_FAIL; } if (SUCCEEDED(hr)) { imageFileSize = SizeofResource(HINST_THISCOMPONENT, imageResHandle); hr = imageFileSize ? S_OK : E_FAIL; } if (SUCCEEDED(hr)) { hr = pIWICFactory->CreateStream(&pStream); #ifdef DEBUG_GPU_RESOURCE LOG(SEVERITY_LEVEL_INFO) << L"[GPU RESOURCE] IWICStream = [" << std::hex << pStream << L"]" << std::dec; #endif } if (SUCCEEDED(hr)) { hr = pStream->InitializeFromMemory(reinterpret_cast<BYTE *>(pImageFile), imageFileSize); } if (SUCCEEDED(hr)) { hr = pIWICFactory->CreateDecoderFromStream(pStream, nullptr, WICDecodeMetadataCacheOnLoad, &pDecoder); #ifdef DEBUG_GPU_RESOURCE LOG(SEVERITY_LEVEL_INFO) << L"[GPU RESOURCE] IWICBitmapDecoder = [" << std::hex << pDecoder << L"]" << std::dec; #endif } if (SUCCEEDED(hr)) { hr = pDecoder->GetFrame(0, &pSource); } if (SUCCEEDED(hr)) { hr = pIWICFactory->CreateFormatConverter(&pConverter); #ifdef DEBUG_GPU_RESOURCE LOG(SEVERITY_LEVEL_INFO) << L"[GPU RESOURCE] IWICFormatConverter = [" << std::hex << pConverter << L"]" << std::dec; #endif } if (SUCCEEDED(hr)) { if (destinationWidth != 0 || destinationHeight != 0) { UINT originalWidth, originalHeight; hr = pSource->GetSize(&originalWidth, &originalHeight); if (SUCCEEDED(hr)) { if (destinationWidth == 0) { FLOAT scalar = static_cast<FLOAT>(destinationHeight) / static_cast<FLOAT>(originalHeight); destinationWidth = static_cast<UINT>(scalar * static_cast<FLOAT>(originalWidth)); } else if (destinationHeight == 0) { FLOAT scalar = static_cast<FLOAT>(destinationWidth) / static_cast<FLOAT>(originalWidth); destinationHeight = static_cast<UINT>(scalar * static_cast<FLOAT>(originalHeight)); } hr = pIWICFactory->CreateBitmapScaler(&pScaler); #ifdef DEBUG_GPU_RESOURCE LOG(SEVERITY_LEVEL_INFO) << L"[GPU RESOURCE] IWICBitmapScaler = [" << std::hex << pScaler << L"]" << std::dec; #endif if (SUCCEEDED(hr)) { hr = pScaler->Initialize(pSource, destinationWidth, destinationHeight, WICBitmapInterpolationModeCubic); if (SUCCEEDED(hr)) { hr = pConverter->Initialize(pScaler, GUID_WICPixelFormat32bppPBGRA, WICBitmapDitherTypeNone, nullptr, 0.f, WICBitmapPaletteTypeMedianCut); } } } } else { hr = pConverter->Initialize(pSource, GUID_WICPixelFormat32bppPBGRA, WICBitmapDitherTypeNone, nullptr, 0.f, WICBitmapPaletteTypeMedianCut); } } if (SUCCEEDED(hr)) { hr = pRenderTarget->CreateBitmapFromWicBitmap(pConverter, nullptr, ppBitmap); #ifdef DEBUG_OUTPUT_GPU_RESOURCE LOG(SEVERITY_LEVEL_INFO) << L"[GPU RESOURCE] ID2D1Bitmap = [" << std::hex << *ppBitmap << L"]" << std::dec; #endif } SafeRelease(&pDecoder); SafeRelease(&pSource); SafeRelease(&pStream); SafeRelease(&pConverter); SafeRelease(&pScaler); #ifdef TOUCHMIND_CONTEXT_DEBUG LOG_LEAVE_HRESULT(hr); #endif return hr; }
ID2D1Bitmap* d2d::CreateBitmapFromResource(int idPic, int destinationWidth, int destinationHeight) { // Locate the resource. HRSRC imageResHandle = FindResource(NULL, MAKEINTRESOURCE(idPic), L"PNG"); if (imageResHandle == nullptr) { return nullptr; } // Load the resource. HGLOBAL imageResDataHandle = LoadResource(NULL, imageResHandle); //If hModule is NULL, the system loads the resource from the module that was used to create the current process HRESULT hr = imageResDataHandle ? S_OK : E_FAIL; if (FAILED(hr)) { return nullptr; } // Lock it to get a system memory pointer. void* pImageFile = LockResource(imageResDataHandle); if (pImageFile == nullptr) { return nullptr; } // Calculate the size. DWORD imageFileSize = SizeofResource(NULL, imageResHandle); if (imageFileSize == 0) { return nullptr; } // Create a WIC stream to map onto the memory. IWICStream *pStream = nullptr; hr = m_pWICFactory->CreateStream(&pStream); if (FAILED(hr)) { return nullptr; } // Initialize the stream with the memory pointer and size. hr = pStream->InitializeFromMemory(reinterpret_cast<BYTE*>(pImageFile), imageFileSize); if (FAILED(hr)) { return nullptr; } // Create a decoder for the stream. IWICBitmapDecoder *pDecoder = nullptr; hr = m_pWICFactory->CreateDecoderFromStream(pStream, NULL, WICDecodeMetadataCacheOnLoad, &pDecoder); if (FAILED(hr)) { return nullptr; } // Create the initial frame. IWICBitmapFrameDecode *pSource = nullptr; hr = pDecoder->GetFrame(0, &pSource); if (FAILED(hr)) { return nullptr; } // Convert the image format to 32bppPBGRA // (DXGI_FORMAT_B8G8R8A8_UNORM + D2D1_ALPHA_MODE_PREMULTIPLIED). IWICFormatConverter *pConverter = NULL; hr = m_pWICFactory->CreateFormatConverter(&pConverter); if (FAILED(hr)) { return nullptr; } // If a new width or height was specified, create an // IWICBitmapScaler and use it to resize the image. if (destinationWidth != 0 || destinationHeight != 0) { UINT originalWidth, originalHeight; hr = pSource->GetSize(&originalWidth, &originalHeight); if (SUCCEEDED(hr)) { if (destinationWidth == 0) { FLOAT scalar = static_cast<FLOAT>(destinationHeight) / static_cast<FLOAT>(originalHeight); destinationWidth = static_cast<UINT>(scalar * static_cast<FLOAT>(originalWidth)); } else if (destinationHeight == 0) { FLOAT scalar = static_cast<FLOAT>(destinationWidth) / static_cast<FLOAT>(originalWidth); destinationHeight = static_cast<UINT>(scalar * static_cast<FLOAT>(originalHeight)); } IWICBitmapScaler *pScaler = nullptr; hr = m_pWICFactory->CreateBitmapScaler(&pScaler); if (SUCCEEDED(hr)) { hr = pScaler->Initialize(pSource,destinationWidth,destinationHeight,WICBitmapInterpolationModeCubic); if (SUCCEEDED(hr)) { hr = pConverter->Initialize(pScaler,GUID_WICPixelFormat32bppPBGRA,WICBitmapDitherTypeNone,NULL,0.f,WICBitmapPaletteTypeMedianCut); } } SafeRelease(pScaler); } } else { hr = pConverter->Initialize(pSource, GUID_WICPixelFormat32bppPBGRA, WICBitmapDitherTypeNone, NULL, 0.f, WICBitmapPaletteTypeMedianCut); } if (FAILED(hr)) { return nullptr; } //create a Direct2D bitmap from the WIC bitmap. ID2D1Bitmap* resBitmap = nullptr; hr = m_pRenderTarget->CreateBitmapFromWicBitmap(pConverter, NULL, &resBitmap); if (FAILED(hr) || resBitmap == nullptr) { return nullptr; } SafeRelease(pDecoder); SafeRelease(pSource); SafeRelease(pStream); SafeRelease(pConverter); pokerlog << "CreateBitmapFromResource " << idPic << " OK." << endl; return resBitmap; }
void LoadJPG(wchar_t *pwszJpg, HWND hwnd) { IWICImagingFactory *pFactory = NULL; HRESULT hr = CoCreateInstance(CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pFactory)); if (SUCCEEDED(hr)) { IWICBitmapDecoder *pDecoder = NULL; hr = pFactory->CreateDecoderFromFilename(pwszJpg, NULL, GENERIC_READ, WICDecodeMetadataCacheOnDemand, &pDecoder); if (SUCCEEDED(hr)) { IWICBitmapFrameDecode *pIDecoderFrame = NULL; hr = pDecoder->GetFrame(0, &pIDecoderFrame); if (SUCCEEDED(hr)) { IWICFormatConverter *pFC = NULL; hr = pFactory->CreateFormatConverter(&pFC); hr = pFC->Initialize(pIDecoderFrame, GUID_WICPixelFormat24bppBGR, WICBitmapDitherTypeNone, NULL, 0.0, WICBitmapPaletteTypeCustom); const int nBytesPixel = 3; // GUID_WICPixelFormat24bppBGR 每像素3字节(24bits) BITMAPINFO bmpInfo; ZeroMemory(&bmpInfo, sizeof(BITMAPINFO)); bmpInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); hr = pIDecoderFrame->GetSize((UINT*)&bmpInfo.bmiHeader.biWidth, (UINT*)&bmpInfo.bmiHeader.biHeight); bmpInfo.bmiHeader.biPlanes = 1; bmpInfo.bmiHeader.biBitCount = 8 * nBytesPixel; bmpInfo.bmiHeader.biCompression = BI_RGB; BYTE *pBuf = NULL; HDC hdc = GetDC(hwnd); bmpInfo.bmiHeader.biHeight *= -1; // BMP 方向调整 HBITMAP hBmp = CreateDIBSection(hdc, &bmpInfo, DIB_RGB_COLORS, (void**)&pBuf, NULL, 0); bmpInfo.bmiHeader.biHeight *= -1; // 计算扫描线 unsigned int cbStride = nBytesPixel * bmpInfo.bmiHeader.biWidth; unsigned int total = cbStride*bmpInfo.bmiHeader.biHeight; hr = pFC->CopyPixels(NULL, cbStride, total, pBuf); // HSL色彩空间变换 DirectX::XMVECTORF32 colorTransofrom = { 1.0f, 1.0f, 1.0f, 1.0f }; if (SUCCEEDED(hr)) { for (int i = 0; i < bmpInfo.bmiHeader.biHeight; i++) { for (int j = 0; j < bmpInfo.bmiHeader.biWidth; j++) { BYTE *pColor = pBuf + cbStride*i + j * nBytesPixel; DirectX::XMVECTOR colorM = DirectX::PackedVector::XMLoadUByteN4((DirectX::PackedVector::XMUBYTEN4*)pColor); colorM = DirectX::XMColorRGBToHSL(colorM); colorM = DirectX::XMColorModulate(colorM, colorTransofrom); colorM = DirectX::XMColorHSLToRGB(colorM); DirectX::PackedVector::XMStoreUByteN4((DirectX::PackedVector::XMUBYTEN4*)pColor, colorM); SetPixel(hdc, j, i, RGB(pColor[2], pColor[1], pColor[0])); } } } ReleaseDC(hwnd, hdc); if (SUCCEEDED(hr)) { MakeMemDC(hBmp, hwnd); InvalidateRect(hwnd, NULL, TRUE); } hr = pFC->Release(); pIDecoderFrame->Release(); } pDecoder->Release(); } pFactory->Release(); } }
HRESULT LoadResourceBitmap( ID2D1RenderTarget* pRendertarget, IWICImagingFactory* pIWICFactory, PCWSTR resourceName, PCWSTR resourceType, UINT destinationWidth, UINT destinationHeight, ID2D1Bitmap** ppBitmap ) { HRESULT hr = S_OK; IWICBitmapDecoder* pDecoder = NULL; IWICBitmapFrameDecode* pSource = NULL; IWICStream* pStream = NULL; IWICFormatConverter* pConverter = NULL; IWICBitmapScaler* pScaler = NULL; HRSRC imageResHandle = NULL; HGLOBAL imageResDataHandle = NULL; void* pImageFile = NULL; DWORD imageFileSize = 0; // Find the resource then load it imageResHandle = FindResource(HINST_THISCOMPONENT, resourceName, resourceType); hr = imageResHandle ? S_OK : E_FAIL; if (SUCCEEDED(hr)) { imageResDataHandle = LoadResource(HINST_THISCOMPONENT, imageResHandle); hr = imageResDataHandle ? S_OK : E_FAIL; } // Lock the resource and calculate the image's size if (SUCCEEDED(hr)) { // Lock it to get the system memory pointer pImageFile = LockResource(imageResDataHandle); hr = pImageFile ? S_OK : E_FAIL; } if (SUCCEEDED(hr)) { // Calculate the size imageFileSize = SizeofResource(HINST_THISCOMPONENT, imageResHandle); hr = imageFileSize ? S_OK : E_FAIL; } // Create an IWICStream object if (SUCCEEDED(hr)) { // Create a WIC stream to map onto the memory hr = pIWICFactory->CreateStream(&pStream); } if (SUCCEEDED(hr)) { // Initialize the stream with the memory pointer and size hr = pStream->InitializeFromMemory( reinterpret_cast<BYTE*>(pImageFile), imageFileSize ); } // Create IWICBitmapDecoder if (SUCCEEDED(hr)) { // Create a decoder for the stream hr = pIWICFactory->CreateDecoderFromStream( pStream, NULL, WICDecodeMetadataCacheOnLoad, &pDecoder ); } // Retrieve a frame from the image and store it in an IWICBitmapFrameDecode object if (SUCCEEDED(hr)) { // Create the initial frame hr = pDecoder->GetFrame(0, &pSource); } // Before Direct2D can use the image, it must be converted to the 32bppPBGRA pixel format. // To convert the image format, use the IWICImagingFactory::CreateFormatConverter method to create an IWICFormatConverter object, then use the IWICFormatConverter object's Initialize method to perform the conversion. if (SUCCEEDED(hr)) { // Convert the image format to 32bppPBGRA // (DXGI_FORMAT_B8G8R8A8_UNORM + D2D1_ALPHA_MODE_PREMULTIPLIED). hr = pIWICFactory->CreateFormatConverter(&pConverter); } if (SUCCEEDED(hr)) { // If a new width or height was specified, create and // IWICBitmapScaler and use it to resize the image. if (destinationWidth != 0 || destinationHeight != 0) { UINT originalWidth; UINT originalHeight; hr = pSource->GetSize(&originalWidth, &originalHeight); if (SUCCEEDED(hr)) { if (destinationWidth == 0) { FLOAT scalar = static_cast<FLOAT>(destinationHeight) / static_cast<FLOAT>(originalHeight); destinationWidth = static_cast<UINT>(scalar * static_cast<FLOAT>(originalWidth)); } else if (destinationHeight == 0) { FLOAT scalar = static_cast<FLOAT>(destinationWidth) / static_cast<FLOAT>(originalWidth); destinationHeight = static_cast<UINT>(scalar * static_cast<FLOAT>(originalHeight)); } hr = pIWICFactory->CreateBitmapScaler(&pScaler); if (SUCCEEDED(hr)) { hr = pScaler->Initialize( pSource, destinationWidth, destinationHeight, WICBitmapInterpolationModeCubic ); if (SUCCEEDED(hr)) { hr = pConverter->Initialize( pScaler, GUID_WICPixelFormat32bppPBGRA, WICBitmapDitherTypeNone, NULL, 0.f, WICBitmapPaletteTypeMedianCut ); } } } } else // use default width and height { hr = pConverter->Initialize( pSource, GUID_WICPixelFormat32bppPBGRA, WICBitmapDitherTypeNone, NULL, 0.f, WICBitmapPaletteTypeMedianCut ); } } // Finally, Create an ID2D1Bitmap object, that can be drawn by a render target and used with other Direct2D objects if (SUCCEEDED(hr)) { // Create a Direct2D bitmap from the WIC bitmap hr = pRendertarget->CreateBitmapFromWicBitmap( pConverter, NULL, ppBitmap ); } SAFE_RELEASE(pDecoder); SAFE_RELEASE(pSource); SAFE_RELEASE(pStream); SAFE_RELEASE(pConverter); SAFE_RELEASE(pScaler); return hr; }
// 从文件读取位图 HRESULT ImageRenderer::LoadBitmapFromFile( ID2D1DeviceContext *pRenderTarget, IWICImagingFactory2 *pIWICFactory, PCWSTR uri, UINT width, UINT height, ID2D1Bitmap1 **ppBitmap ){ IWICBitmapDecoder *pDecoder = nullptr; IWICBitmapFrameDecode *pSource = nullptr; IWICStream *pStream = nullptr; IWICFormatConverter *pConverter = nullptr; IWICBitmapScaler *pScaler = nullptr; HRESULT hr = pIWICFactory->CreateDecoderFromFilename( uri, nullptr, GENERIC_READ, WICDecodeMetadataCacheOnLoad, &pDecoder ); if (SUCCEEDED(hr)) { hr = pDecoder->GetFrame(0, &pSource); } if (SUCCEEDED(hr)) { hr = pIWICFactory->CreateFormatConverter(&pConverter); } if (SUCCEEDED(hr)) { if (width != 0 || height != 0) { UINT originalWidth, originalHeight; hr = pSource->GetSize(&originalWidth, &originalHeight); if (SUCCEEDED(hr)) { if (width == 0) { FLOAT scalar = static_cast<FLOAT>(height) / static_cast<FLOAT>(originalHeight); width = static_cast<UINT>(scalar * static_cast<FLOAT>(originalWidth)); } else if (height == 0) { FLOAT scalar = static_cast<FLOAT>(width) / static_cast<FLOAT>(originalWidth); height = static_cast<UINT>(scalar * static_cast<FLOAT>(originalHeight)); } hr = pIWICFactory->CreateBitmapScaler(&pScaler); if (SUCCEEDED(hr)) { hr = pScaler->Initialize( pSource, width, height, WICBitmapInterpolationModeCubic ); } if (SUCCEEDED(hr)) { hr = pConverter->Initialize( pScaler, GUID_WICPixelFormat32bppPBGRA, WICBitmapDitherTypeNone, nullptr, 0.f, WICBitmapPaletteTypeMedianCut ); } } } else { hr = pConverter->Initialize( pSource, GUID_WICPixelFormat32bppPBGRA, WICBitmapDitherTypeNone, nullptr, 0.f, WICBitmapPaletteTypeMedianCut ); } } if (SUCCEEDED(hr)) { hr = pRenderTarget->CreateBitmapFromWicBitmap( pConverter, nullptr, ppBitmap ); } ::SafeRelease(pDecoder); ::SafeRelease(pSource); ::SafeRelease(pStream); ::SafeRelease(pConverter); ::SafeRelease(pScaler); return hr; }