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); }
Image::Buffer * WIC::Api::CreateImage(char * buffer, unsigned bufferLength) { if(!factory) return 0; // Create input stream for memory IWICStream * stream = 0; factory->CreateStream(&stream); if(!stream) return 0; stream->InitializeFromMemory((unsigned char*)(buffer), static_cast<DWORD>(bufferLength)); IWICBitmapDecoder * decoder = 0; factory->CreateDecoderFromStream(stream, 0, WICDecodeMetadataCacheOnDemand, &decoder); if(!decoder) return 0; IWICBitmapFrameDecode * bitmapSource = 0; decoder->GetFrame(0, &bitmapSource); if(!bitmapSource) { decoder->Release(); return 0; } IWICBitmapSource * convertedSource = 0; WICConvertBitmapSource(GUID_WICPixelFormat32bppRGBA, bitmapSource, &convertedSource); bitmapSource->Release(); if(!convertedSource) { decoder->Release(); return 0; } // Create the bitmap from the image frame. IWICBitmap * bitmap = 0; factory->CreateBitmapFromSource( convertedSource, // Create a bitmap from the image frame WICBitmapCacheOnDemand, // Cache metadata when needed &bitmap); // Pointer to the bitmap convertedSource->Release(); decoder->Release(); if(!bitmap) return 0; unsigned width = 0, height = 0; bitmap->GetSize(&width, &height); WICRect lockRect = { 0, 0, width, height }; IWICBitmapLock * lock = 0; bitmap->Lock(&lockRect, WICBitmapLockWrite, &lock); if(!lock) { bitmap->Release(); return 0; } return new WIC::Buffer(bitmap, lock, width, height); }
SpriteSheet::SpriteSheet(wchar_t* filename, Graphics* gfx) { this->gfx = gfx; bmp = NULL; HRESULT hr; //create a wic factory IWICImagingFactory *wicFactory = NULL; hr = CoCreateInstance( CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, IID_IWICImagingFactory, (LPVOID*)&wicFactory); //create a decoder IWICBitmapDecoder *wicDecoder = NULL; hr = wicFactory->CreateDecoderFromFilename( filename, // THE FILE NAME NULL, // the preferred vendor GENERIC_READ, // we're reading the file, not writing WICDecodeMetadataCacheOnLoad, &wicDecoder); // read a frame from the image IWICBitmapFrameDecode* wicFrame = NULL; hr = wicDecoder->GetFrame(0, &wicFrame); // create a converter IWICFormatConverter *wicConverter = NULL; hr = wicFactory->CreateFormatConverter(&wicConverter); // setup the converter hr = wicConverter->Initialize( wicFrame, // frame GUID_WICPixelFormat32bppPBGRA, // pixel format WICBitmapDitherTypeNone, // irrelevant NULL, // no palette needed, irrlevant 0.0, // alpha transparency % irrelevant WICBitmapPaletteTypeCustom // irrelevant ); // use the converter to create an D2D1Bitmap /// ID2D1Bitmap* bmp; // this will be a member variable hr = gfx->GetRenderTarget()->CreateBitmapFromWicBitmap( wicConverter, // converter NULL, // D2D1_BITMAP_PROPERIES &bmp // destiatnion D2D1 bitmap ); if (wicFactory) wicFactory->Release(); if (wicDecoder) wicDecoder->Release(); if (wicConverter) wicConverter->Release(); if (wicFrame) wicFrame->Release(); }
HBITMAP LoadLocalPNG( const std::string& sPath, const RASize& sz ) { SetCurrentDirectory( Widen( g_sHomeDir ).c_str() ); ASSERT( _FileExists( sPath ) ); if( !_FileExists( sPath ) ) { RA_LOG( "File could not be found: %s\n", sPath.c_str() ); return nullptr; } HBITMAP hRetVal = nullptr; // Step 2: Decode the source image to IWICBitmapSource IWICBitmapDecoder* pDecoder = nullptr; HRESULT hr = g_UserImageFactoryInst.m_pIWICFactory->CreateDecoderFromFilename( Widen( sPath ).c_str(), // Image to be decoded nullptr, // Do not prefer a particular vendor GENERIC_READ, // Desired read access to the file WICDecodeMetadataCacheOnDemand, // Cache metadata when needed &pDecoder ); // Pointer to the decoder // Retrieve the first frame of the image from the decoder IWICBitmapFrameDecode* pFrame = nullptr; if( SUCCEEDED( hr ) ) hr = pDecoder->GetFrame( 0, &pFrame ); // Retrieve IWICBitmapSource from the frame if( SUCCEEDED( hr ) ) { SAFE_RELEASE( g_UserImageFactoryInst.m_pOriginalBitmapSource ); //##SD ??? pFrame->QueryInterface( IID_IWICBitmapSource, reinterpret_cast<void**>( &g_UserImageFactoryInst.m_pOriginalBitmapSource ) ); } // Step 3: Scale the original IWICBitmapSource to the client rect size // and convert the pixel format IWICBitmapSource* pToRenderBitmapSource = nullptr; if( SUCCEEDED( hr ) ) hr = ConvertBitmapSource( { 0, 0, sz.Width(), sz.Height() }, pToRenderBitmapSource ); // Step 4: Create a DIB from the converted IWICBitmapSource if( SUCCEEDED( hr ) ) hr = UserImageFactory_CreateDIBSectionFromBitmapSource( pToRenderBitmapSource, hRetVal ); SAFE_RELEASE( pToRenderBitmapSource ); SAFE_RELEASE( pDecoder ); SAFE_RELEASE( pFrame ); SAFE_RELEASE( g_UserImageFactoryInst.m_pOriginalBitmapSource ); return hRetVal; }
// Loads a PNG image from the specified stream (using Windows Imaging Component). IWICBitmapSource * LoadBitmapFromStream(IStream * ipImageStream) { // initialize return value IWICBitmapSource * ipBitmap = NULL; // load WIC's PNG decoder IWICBitmapDecoder * ipDecoder = NULL; IID i = IID_IWICBitmapDecoder; if (FAILED(CoCreateInstance(CLSID_WICPngDecoder, NULL, CLSCTX_INPROC_SERVER, i,//__uuidof(ipDecoder) (void **)&ipDecoder))) goto Return; // load the PNG if (FAILED(ipDecoder->Initialize(ipImageStream, WICDecodeMetadataCacheOnLoad))) goto ReleaseDecoder; // check for the presence of the first frame in the bitmap UINT nFrameCount = 0; if (FAILED(ipDecoder->GetFrameCount(&nFrameCount)) || nFrameCount != 1) goto ReleaseDecoder; // load the first frame (i.e., the image) IWICBitmapFrameDecode * ipFrame = NULL; if (FAILED(ipDecoder->GetFrame(0, &ipFrame))) goto ReleaseDecoder; // convert the image to 32bpp BGRA format with pre-multiplied alpha // (it may not be stored in that format natively in the PNG resource, // but we need this format to create the DIB to use on-screen) WICConvertBitmapSource(GUID_WICPixelFormat32bppPBGRA, ipFrame, &ipBitmap); ipFrame->Release(); ReleaseDecoder: ipDecoder->Release(); Return: return ipBitmap; }
// ========================================================= // Load the specified bitmap from file into D2D bitmap // ========================================================= BOOL Loader::LoadBitmapFromFile(LPCWSTR filename, const Graphics* graphicsWrapper, ID2D1Bitmap** ppBitmap) { if (!isInitialized) return FALSE; HRESULT hr; IWICBitmapDecoder *pDecoder = NULL; IWICBitmapFrameDecode *pSource = NULL; IWICFormatConverter *pConverter = NULL; hr = pFactory->CreateDecoderFromFilename(filename, NULL, GENERIC_READ, WICDecodeMetadataCacheOnDemand, &pDecoder); CHECK(failedDecoder); hr = pDecoder->GetFrame(0, &pSource); CHECK(failedGetFrame); hr = pFactory->CreateFormatConverter(&pConverter); CHECK(failedConverter); hr = pConverter->Initialize(pSource, GUID_WICPixelFormat32bppPBGRA, WICBitmapDitherTypeNone, NULL, 0.0, WICBitmapPaletteTypeMedianCut); CHECK(failedConversion); hr = graphicsWrapper->pRenderTarget->CreateBitmapFromWicBitmap(pSource, ppBitmap); CHECK(failedBitmap); return TRUE; failedBitmap: OutputDebugStringA("Loader::LoadBitmapFromFile -> Failed to create bitmap.\n"); failedConversion: pConverter->Release(); OutputDebugStringA("Loader::LoadBitmapFromFile -> Failed to initialise format converter.\n"); failedConverter: pSource->Release(); OutputDebugStringA("Loader::LoadBitmapFromFile -> Failed to create format converter.\n"); failedGetFrame: pDecoder->Release(); OutputDebugStringA("Loader::LoadBitmapFromFile -> Failed to get frame 0 from source bitmap.\n"); failedDecoder: OutputDebugStringA("Loader::LoadBitmapFromFile -> Failed to create bitmap decoder.\n"); return FALSE; }
HBITMAP ImageDecoder::loadImage(IWICBitmapDecoder *decoder) { IWICBitmapFrameDecode *frame = NULL; if (FAILED(decoder->GetFrame(0, &frame))) { throw Exception("could not get frame"); } IWICBitmapSource *bitmapSource = NULL; if (FAILED(WICConvertBitmapSource(GUID_WICPixelFormat32bppPBGRA, frame, &bitmapSource))) { throw Exception("could not convert bitmap"); } HBITMAP bitmap = convertFrameToBitmap(frame); frame->Release(); return bitmap; }
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(); }
void ImageDecoder::loadGifFromResource(const WCHAR *name, const WCHAR *type, std::vector<AnimatedGifFrame *> &frames) { unsigned char *bytes = NULL; DWORD size = 0; loadResource(name, type, bytes, size); IWICStream *stream = createStreamFromBytes(bytes, size); IWICBitmapDecoder *decoder = createDecoderFromStream(stream); unsigned int frameCount = 0; if (FAILED(decoder->GetFrameCount(&frameCount))) { throw Exception("could not get gif frame count"); } if (frameCount <= 1) { throw Exception("not a gif animation"); } for (unsigned int frameIndex = 0; frameIndex < frameCount; frameIndex++) { IWICBitmapFrameDecode *bitmapFrame = NULL; if (FAILED(decoder->GetFrame(frameIndex, &bitmapFrame))) { throw Exception("could not get frame"); } HBITMAP bitmap = convertFrameToBitmap(bitmapFrame); bitmapFrame->Release(); AnimatedGifFrame *frame = new AnimatedGifFrame(bitmap); frames.push_back(frame); } decoder->Release(); stream->Release(); }
HBITMAP ImageUtil::LoadImage(string path) { size_t pathFileExtDot = path.find_last_of('.'); if (pathFileExtDot == string::npos || pathFileExtDot + 1 >= path.length()) throw INETRException("[imgLoadFailed]"); string ext = path.substr(pathFileExtDot + 1); const GUID *decoderCLSID = nullptr; if (ext == "png") decoderCLSID = &CLSID_WICPngDecoder; else if (ext == "bmp") decoderCLSID = &CLSID_WICBmpDecoder; else if (ext == "gif") decoderCLSID = &CLSID_WICGifDecoder; else if (ext == "jpg" || ext == "jpeg") decoderCLSID = &CLSID_WICJpegDecoder; if (decoderCLSID == nullptr) throw INETRException("[unsupportedImg]: " + ext); IStream *pngFileStream; if (FAILED(SHCreateStreamOnFile(path.c_str(), STGM_READ, &pngFileStream))) throw INETRException("[imgLoadFailed]:\n" + path); IWICBitmapDecoder *bmpDecoder = nullptr; if (FAILED(CoCreateInstance(*decoderCLSID, nullptr, CLSCTX_INPROC_SERVER, __uuidof(bmpDecoder), reinterpret_cast<void**>(&bmpDecoder)))) throw INETRException("[imgDecFailed]"); if (FAILED(bmpDecoder->Initialize(pngFileStream, WICDecodeMetadataCacheOnLoad))) { bmpDecoder->Release(); throw INETRException("[imgDecFailed]"); } UINT bmpFrameCount = 0; if (FAILED(bmpDecoder->GetFrameCount(&bmpFrameCount)) && bmpFrameCount != 1) { bmpDecoder->Release(); throw INETRException("[imgDecFailed]"); } IWICBitmapFrameDecode *bmpFrame = nullptr; if (FAILED(bmpDecoder->GetFrame(0, &bmpFrame))) { bmpDecoder->Release(); throw INETRException("[imgDecFailed]"); } IWICBitmapSource *bmpSource = nullptr; WICConvertBitmapSource(GUID_WICPixelFormat32bppPBGRA, bmpFrame, &bmpSource); bmpFrame->Release(); bmpDecoder->Release(); UINT width = 0, height = 0; if (FAILED(bmpSource->GetSize(&width, &height)) || width == 0 || height == 0) throw INETRException("[imgDecFailed]"); BITMAPINFO bmInfo; ZeroMemory(&bmInfo, sizeof(bmInfo)); bmInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); bmInfo.bmiHeader.biWidth = width; bmInfo.bmiHeader.biHeight = -((LONG)height); bmInfo.bmiHeader.biPlanes = 1; bmInfo.bmiHeader.biBitCount = 32; bmInfo.bmiHeader.biCompression = BI_RGB; HBITMAP hbmp = nullptr; void *imageBits = nullptr; HDC screenDC = GetDC(nullptr); hbmp = CreateDIBSection(screenDC, &bmInfo, DIB_RGB_COLORS, &imageBits, nullptr, 0); ReleaseDC(nullptr, screenDC); if (hbmp == nullptr) throw INETRException("[imgDecFailed]"); const UINT bmpStride = width * 4; const UINT bmpSize = bmpStride * height; if (FAILED(bmpSource->CopyPixels(nullptr, bmpStride, bmpSize, static_cast<BYTE*>(imageBits)))) { DeleteObject(hbmp); hbmp = nullptr; throw INETRException("[imgDecFailed]"); } bmpSource->Release(); return hbmp; }
// 解码照片的基础位图文件的. 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 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 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; }
bool ResourceManager::LoadFile(ID2D1HwndRenderTarget* renderTarget, wchar_t * filename) { HRESULT result; IWICImagingFactory2* wicFactory; IWICBitmapDecoder* wicDecoder; IWICBitmapFrameDecode* wicFrame; IWICBitmapFlipRotator* wicFlip; IWICFormatConverter *wicConverter; Sprite* newSprite; // WIC의 각종 인터페이스를 사용하기 위한 factory 생성 result = CoCreateInstance(CLSID_WICImagingFactory, nullptr, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&wicFactory)); if (FAILED(result)) return false; // 파일을 읽고 디코딩 하기 위한 decoder 생성 result = wicFactory->CreateDecoderFromFilename(filename, nullptr, GENERIC_READ, WICDecodeMetadataCacheOnDemand, &wicDecoder); if (FAILED(result)) return false; // decoder에서 프레임을 얻어옴, // 일반적인 이미지 파일은 single frame만을 지원하므로 0으로 고정 result = wicDecoder->GetFrame(0, &wicFrame); if (FAILED(result)) return false; // 수평으로 뒤집힌 이미지를 얻기 위해 BitmapFlipRotator 생성 result = wicFactory->CreateBitmapFlipRotator(&wicFlip); if (FAILED(result)) return false; // wicFrame를 수평으로 뒤집음 wicFlip->Initialize(wicFrame, WICBitmapTransformFlipHorizontal); // WICBitmap을 D2DBitmap으로 변환시키기 위해 format converter 생성 result = wicFactory->CreateFormatConverter(&wicConverter); if (FAILED(result)) return false; // Converter[0]의 Format을 일반 이미지(wicFrame)에 맞춤 result = wicConverter->Initialize(wicFrame, GUID_WICPixelFormat32bppPBGRA, WICBitmapDitherTypeNone, NULL, 0.0f, WICBitmapPaletteTypeCustom); if (FAILED(result)) return false; // 리소스 정보를 저장 할 Sprite 생성 newSprite = new Sprite(renderTarget); if (!newSprite) return false; // WICBitmap을 D2DBitmap으로 변환 //result = renderTarget->CreateBitmapFromWicBitmap(wicConverter, nullptr, &m_Bitmap); result = renderTarget->CreateBitmapFromWicBitmap(wicConverter, nullptr, newSprite->GetBitmap()); if (FAILED(result)) return false; ID2D1Bitmap* bitmap = *(newSprite->GetBitmap()); int numberOfFrame = bitmap->GetSize().width / IMAGE_SIZE; int numberOfAction = bitmap->GetSize().height / IMAGE_SIZE; newSprite->Initialize(numberOfFrame, numberOfAction); wchar_t* buffer = new wchar_t[128]; wcscpy_s(buffer, wcslen(filename) + 1, filename); // 스프라이트 등록 m_Sprites.push_back(newSprite); m_Filenames.push_back(buffer); wicConverter->Release(); wicConverter = nullptr; wicFrame->Release(); wicFrame = nullptr; wicFlip->Release(); wicFlip = nullptr; wicDecoder->Release(); wicDecoder = nullptr; wicFactory->Release(); wicFactory = nullptr; return true; }
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 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; }
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; }
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; }
// ========================================================= // Load the specified bitmap from file into D2D bitmap // ========================================================= BOOL Loader::LoadBitmapFromResource(LPCWSTR resourceId, LPCWSTR resourceType, const Graphics* graphicsWrapper, ID2D1Bitmap** ppBitmap) { if (!isInitialized) return FALSE; HRESULT hr; IWICStream *pStream = NULL; IWICBitmapDecoder *pDecoder = NULL; IWICBitmapFrameDecode *pSource = NULL; IWICFormatConverter *pConverter = NULL; HRSRC imageResHandle = NULL; HGLOBAL imageResDataHandle = NULL; void *pImageFile = NULL; DWORD imageFileSize = 0; HMODULE module = GetModuleHandle(0); // Locate the resource imageResHandle = FindResource(module, resourceId, resourceType); if (!imageResHandle) { OutputDebugStringA("Loader::LoadBitmapFromResource -> Failed to locate resource.\n"); return FALSE; } imageResDataHandle = LoadResource(module, imageResHandle); if (!imageResDataHandle) { OutputDebugStringA("Loader::LoadBitmapFromResource -> Failed to load resource.\n"); return FALSE; } // lock resource to get pointer to data pImageFile = LockResource(imageResDataHandle); if (!pImageFile) { OutputDebugStringA("Loader::LoadBitmapFromResource -> Failed to lock resource for processing.\n"); return FALSE; } // get the size of the image imageFileSize = SizeofResource(module, imageResHandle); if (!imageFileSize) { OutputDebugStringA("Loader::LoadBitmapFromResource -> Failed to obtain size of image resource.\n"); return FALSE; } // now that we have everything, we create the stream hr = pFactory->CreateStream(&pStream); CHECK(failedCreateStream); // initialise the stream hr = pStream->InitializeFromMemory((byte*)pImageFile, imageFileSize); CHECK(failedStreamInit); hr = pFactory->CreateDecoderFromStream(pStream, NULL, WICDecodeMetadataCacheOnDemand, &pDecoder); CHECK(failedDecoder); hr = pDecoder->GetFrame(0, &pSource); CHECK(failedGetFrame); hr = pFactory->CreateFormatConverter(&pConverter); CHECK(failedConverter); hr = pConverter->Initialize(pSource, GUID_WICPixelFormat32bppPBGRA, WICBitmapDitherTypeNone, NULL, 0.0, WICBitmapPaletteTypeMedianCut); CHECK(failedConversion); hr = graphicsWrapper->pRenderTarget->CreateBitmapFromWicBitmap(pConverter, ppBitmap); CHECK(failedBitmap); return TRUE; failedBitmap: OutputDebugStringA("Loader::LoadBitmapFromFile -> Failed to create bitmap.\n"); failedConversion: pConverter->Release(); OutputDebugStringA("Loader::LoadBitmapFromFile -> Failed to initialise format converter.\n"); failedConverter: pSource->Release(); OutputDebugStringA("Loader::LoadBitmapFromFile -> Failed to create format converter.\n"); failedGetFrame: pDecoder->Release(); OutputDebugStringA("Loader::LoadBitmapFromFile -> Failed to get frame 0 from source bitmap.\n"); failedDecoder: pStream->Release(); OutputDebugStringA("Loader::LoadBitmapFromFile -> Failed to create bitmap decoder.\n"); return FALSE; failedStreamInit: OutputDebugStringA("Loader::LoadBitmapFromFile -> Failed to initialize WIC stream.\n"); return FALSE; failedCreateStream: OutputDebugStringA("Loader::LoadBitmapFromFile -> Failed to create WIC stream.\n"); return FALSE; }
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); }
Bitmap::Bitmap( std::wstring bitmapPath ) { HRESULT hr; if( m_WICFactory == nullptr ) { hr = CoCreateInstance( CLSID_WICImagingFactory , NULL , CLSCTX_INPROC_SERVER , IID_PPV_ARGS( &m_WICFactory ) ); if( hr == REGDB_E_CLASSNOTREG ) { CoCreateInstance( CLSID_WICImagingFactory1 , NULL , CLSCTX_INPROC_SERVER , IID_PPV_ARGS( &m_WICFactory ) ); } } m_Path = bitmapPath; IWICBitmapDecoder* bitmapDecoder = nullptr; hr = m_WICFactory->CreateDecoderFromFilename( bitmapPath.c_str() , nullptr , GENERIC_READ , WICDecodeMetadataCacheOnDemand , &bitmapDecoder ); IWICBitmapFrameDecode* bitmapFrameDecode = nullptr; if( SUCCEEDED( hr ) ) { bitmapDecoder->GetFrame( 0 , &bitmapFrameDecode ); } if( SUCCEEDED( hr ) ) { hr = m_WICFactory->CreateFormatConverter( &m_FmtConverter ); } if( SUCCEEDED( hr ) ) { hr = m_FmtConverter->Initialize( bitmapFrameDecode , GUID_WICPixelFormat32bppPBGRA , WICBitmapDitherTypeNone , NULL , 0.f , WICBitmapPaletteTypeCustom ); } D2DRenderer* renderer = BattleShipApp::GetInstance()->GetD2DRenderer(); if( m_FmtConverter != nullptr ) { renderer->GetHwndRenderTarget()->CreateBitmapFromWicBitmap( m_FmtConverter , nullptr , &m_D2DBitmap ); } if( bitmapDecoder != nullptr ) { bitmapDecoder->Release(); } if( bitmapFrameDecode != nullptr ) { bitmapFrameDecode->Release(); } }
//@https://msdn.microsoft.com/de-de/library/windows/desktop/dd756686(v=vs.85).aspx HRESULT BitmapDecoder::LoadBitmapFromFile(ID2D1RenderTarget * pRenderTarget, PCWSTR uri, ID2D1Bitmap ** ppBitmap) { IWICImagingFactory* pFactory; HRESULT hr = CoCreateInstance(CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, IID_IWICImagingFactory, (LPVOID*)&pFactory ); //IWICStream *pStream = NULL; //? //IWICBitmapScaler *pScaler = NULL; //? IWICBitmapDecoder *pDecoder = NULL; if (SUCCEEDED(hr)) { hr = pFactory->CreateDecoderFromFilename(uri, NULL, GENERIC_READ, WICDecodeMetadataCacheOnLoad, &pDecoder); } IWICBitmapFrameDecode *pSource = NULL; if (SUCCEEDED(hr)) { hr = pDecoder->GetFrame(0, &pSource); } IWICFormatConverter *pConverter = NULL; if (SUCCEEDED(hr)) { hr = pFactory->CreateFormatConverter(&pConverter); } if (SUCCEEDED(hr)) { hr = pConverter->Initialize( pSource, GUID_WICPixelFormat32bppPBGRA, WICBitmapDitherTypeNone, NULL, 0.f, WICBitmapPaletteTypeMedianCut ); } if (SUCCEEDED(hr)) { pRenderTarget->CreateBitmapFromWicBitmap(pConverter, NULL, ppBitmap); } if (pDecoder != nullptr) { pDecoder->Release();//SafeRelease(&pDecoder); } if (pSource != nullptr) { pSource->Release(); } //SafeRelease(&pSource); // pStream->Release();//SafeRelease(&pStream); if(pConverter!= nullptr) { pConverter->Release(); } //SafeRelease(&pConverter); // pScaler->Release();//SafeRelease(&pScaler); if (pFactory != nullptr) { pFactory->Release(); } 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; }