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 ImageDecoder::loadImage(unsigned char *bytes, int size) { IWICStream *stream = createStreamFromBytes(bytes, size); IWICBitmapDecoder *decoder = createDecoderFromStream(stream); HBITMAP bitmap = loadImage(decoder); decoder->Release(); stream->Release(); return bitmap; }
// 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; }
HBITMAP ImageDecoder::loadImage(const std::string &filename) { WCHAR *wcharFilename = buildWcharString(filename); IWICBitmapDecoder *decoder = NULL; HRESULT result = factory->CreateDecoderFromFilename(wcharFilename, NULL, GENERIC_READ, WICDecodeMetadataCacheOnDemand, &decoder); delete[] wcharFilename; if (FAILED(result)) { throw Exception("could not create decoder"); } HBITMAP bitmap = loadImage(decoder); decoder->Release(); return bitmap; }
// ========================================================= // 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; }
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(); }
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(); }
//@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; }
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; }
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; }
// ========================================================= // 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; }
void PngViewer::load_png_with_wic() { static const D2D1_FACTORY_OPTIONS options = { D2D1_DEBUG_LEVEL_INFORMATION }; D2D1_BITMAP_PROPERTIES1 bmp_properties; ID2D1Factory2 * d2_factory; ID2D1Device1 * d2_device; ID2D1DeviceContext1 * context; IDXGISurface2 * surface; IWICBitmapDecoder * decoder; IWICBitmapFrameDecode * frame_decoder; IWICFormatConverter * format_converter; ID2D1Bitmap1 * png_texture; ID2D1Bitmap1 * bitmap; if(this->wic_factory->CreateDecoderFromFileHandle(reinterpret_cast<ULONG_PTR>(this->png_file_handle), nullptr, WICDecodeMetadataCacheOnLoad, &decoder) != S_OK) { return; } if(decoder->GetFrame(0, &frame_decoder) != S_OK) { decoder->Release(); return; } if(this->wic_factory->CreateFormatConverter(&format_converter) != S_OK) { frame_decoder->Release(); decoder->Release(); return; } format_converter->Initialize(frame_decoder, GUID_WICPixelFormat32bppPBGRA, WICBitmapDitherTypeNone, nullptr, 0.0, WICBitmapPaletteTypeMedianCut); frame_decoder->Release(); decoder->Release(); if(D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, options, &d2_factory) != S_OK) { format_converter->Release(); return; } if(d2_factory->CreateDevice(this->device_gi, &d2_device) != S_OK) { format_converter->Release(); d2_factory->Release(); return; } if(d2_device->CreateDeviceContext(D2D1_DEVICE_CONTEXT_OPTIONS_NONE, &context) != S_OK) { format_converter->Release(); d2_device->Release(); d2_factory->Release(); return; } if(this->swap_chain->GetBuffer(0, __uuidof(IDXGISurface2), (void **)&surface) != S_OK) { format_converter->Release(); context->Release(); d2_device->Release(); d2_factory->Release(); return; } ::memset(&bmp_properties, 0, sizeof(D2D1_BITMAP_PROPERTIES1)); bmp_properties.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED; bmp_properties.pixelFormat.format = DXGI_FORMAT_B8G8R8A8_UNORM; bmp_properties.bitmapOptions = D2D1_BITMAP_OPTIONS_TARGET | D2D1_BITMAP_OPTIONS_CANNOT_DRAW; if(context->CreateBitmapFromDxgiSurface(surface, &bmp_properties, &bitmap) != S_OK) { format_converter->Release(); surface->Release(); context->Release(); d2_device->Release(); d2_factory->Release(); return; } bmp_properties.bitmapOptions = D2D1_BITMAP_OPTIONS_TARGET; if(context->CreateBitmapFromWicBitmap(format_converter, &bmp_properties, &png_texture) != S_OK) { format_converter->Release(); bitmap->Release(); surface->Release(); context->Release(); d2_device->Release(); d2_factory->Release(); return; } context->SetTarget(bitmap); bitmap->CopyFromBitmap(nullptr, png_texture, nullptr); this->swap_chain->Present(1, 0); format_converter->Release(); png_texture->Release(); bitmap->Release(); surface->Release(); context->Release(); d2_device->Release(); d2_factory->Release(); }
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(); } }
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(); } }
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; }