/// <summary> /// Load an image from a resource into a buffer /// </summary> /// <param name="resourceName">name of image resource to load</param> /// <param name="resourceType">type of resource to load</param> /// <param name="nOutputWidth">width (in pixels) of scaled output bitmap</param> /// <param name="nOutputHeight">height (in pixels) of scaled output bitmap</param> /// <param name="pOutputBuffer">buffer that will hold the loaded image</param> /// <returns>S_OK on success, otherwise failure code</returns> HRESULT CColorBasics::LoadResourceImage(PCWSTR resourceName, PCWSTR resourceType, UINT nOutputWidth, UINT nOutputHeight, RGBQUAD* pOutputBuffer) { IWICImagingFactory* pIWICFactory = NULL; 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; HRESULT hrCoInit = CoInitialize(NULL); HRESULT hr = hrCoInit; if (SUCCEEDED(hr)) { hr = CoCreateInstance(CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, IID_IWICImagingFactory, (LPVOID*)&pIWICFactory); } if (SUCCEEDED(hr)) { // Locate the resource imageResHandle = FindResourceW(HINST_THISCOMPONENT, resourceName, resourceType); 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)) { hr = pIWICFactory->CreateBitmapScaler(&pScaler); } if (SUCCEEDED(hr)) { hr = pScaler->Initialize( pSource, nOutputWidth, nOutputHeight, WICBitmapInterpolationModeCubic ); } if (SUCCEEDED(hr)) { hr = pConverter->Initialize( pScaler, GUID_WICPixelFormat32bppPBGRA, WICBitmapDitherTypeNone, NULL, 0.f, WICBitmapPaletteTypeMedianCut); } UINT width = 0; UINT height = 0; if (SUCCEEDED(hr)) { hr = pConverter->GetSize(&width, &height); } // make sure the image scaled correctly so the output buffer is big enough if (SUCCEEDED(hr)) { if ((width != nOutputWidth) || (height != nOutputHeight)) { hr = E_FAIL; } } if (SUCCEEDED(hr)) { hr = pConverter->CopyPixels(NULL, width * sizeof(RGBQUAD), nOutputWidth * nOutputHeight * sizeof(RGBQUAD), reinterpret_cast<BYTE*>(pOutputBuffer)); } SafeRelease(pScaler); SafeRelease(pConverter); SafeRelease(pSource); SafeRelease(pDecoder); SafeRelease(pStream); SafeRelease(pIWICFactory); if (SUCCEEDED(hrCoInit)) { CoUninitialize(); } return hr; }
_Use_decl_annotations_ HRESULT DirectX::CreateWICTextureFromMemoryEx( ID3D11Device* d3dDevice, ID3D11DeviceContext* d3dContext, const uint8_t* wicData, size_t wicDataSize, size_t maxsize, D3D11_USAGE usage, unsigned int bindFlags, unsigned int cpuAccessFlags, unsigned int miscFlags, bool forceSRGB, ID3D11Resource** texture, ID3D11ShaderResourceView** textureView ) { if ( texture ) { *texture = nullptr; } if ( textureView ) { *textureView = nullptr; } if (!d3dDevice || !wicData || (!texture && !textureView)) return E_INVALIDARG; if ( !wicDataSize ) return E_FAIL; #ifdef _M_AMD64 if ( wicDataSize > 0xFFFFFFFF ) return HRESULT_FROM_WIN32( ERROR_FILE_TOO_LARGE ); #endif IWICImagingFactory* pWIC = _GetWIC(); if ( !pWIC ) return E_NOINTERFACE; // Create input stream for memory IWICStream* stream; HRESULT hr = pWIC->CreateStream( &stream ); if ( FAILED(hr) ) return hr; hr = stream->InitializeFromMemory( const_cast<uint8_t*>( wicData ), static_cast<DWORD>( wicDataSize ) ); if ( FAILED(hr) ) return hr; // Initialize WIC IWICBitmapDecoder* decoder; hr = pWIC->CreateDecoderFromStream( stream, 0, WICDecodeMetadataCacheOnDemand, &decoder ); if ( FAILED(hr) ) return hr; IWICBitmapFrameDecode* frame; hr = decoder->GetFrame( 0, &frame ); if ( FAILED(hr) ) return hr; hr = CreateTextureFromWIC( d3dDevice, d3dContext, frame, maxsize, usage, bindFlags, cpuAccessFlags, miscFlags, forceSRGB, texture, textureView ); if ( FAILED(hr)) return hr; if (texture != 0 && *texture != 0) { SetDebugObjectName(*texture, "WICTextureLoader"); } if (textureView != 0 && *textureView != 0) { SetDebugObjectName(*textureView, "WICTextureLoader"); } return hr; }
bool WICImageLoader::encodeImageData(std::string path, const unsigned char* data, size_t dataLen, WICPixelFormatGUID pixelFormat, int width, int height, GUID containerFormat) { assert(data != NULL); assert(dataLen > 0 && width > 0 && height > 0); IWICImagingFactory* pFact = getWICFactory(); HRESULT hr = E_FAIL; IWICStream* pStream = NULL; if (NULL != pFact) { hr = pFact->CreateStream(&pStream); } if (SUCCEEDED(hr)) { hr = pStream->InitializeFromFilename(StringUtf8ToWideChar(path).c_str(), GENERIC_WRITE); } IWICBitmapEncoder* pEnc = NULL; if (SUCCEEDED(hr)) { hr = pFact->CreateEncoder(containerFormat, NULL, &pEnc); } if (SUCCEEDED(hr)) { hr = pEnc->Initialize(pStream, WICBitmapEncoderNoCache); } IWICBitmapFrameEncode* pFrame = NULL; IPropertyBag2* pProp = NULL; if (SUCCEEDED(hr)) { hr = pEnc->CreateNewFrame(&pFrame, &pProp); } if (SUCCEEDED(hr)) { hr = pFrame->Initialize(pProp); } if (SUCCEEDED(hr)) { hr = pFrame->SetSize(width, height); } if (SUCCEEDED(hr)) { WICPixelFormatGUID targetFormat = pixelFormat; hr = pFrame->SetPixelFormat(&targetFormat); if (targetFormat != pixelFormat) { hr = E_INVALIDARG; } } if (SUCCEEDED(hr)) { size_t bpp = getBitsPerPixel(pixelFormat); size_t stride = (width * bpp + 7) / 8; hr = pFrame->WritePixels(height, stride, dataLen, (BYTE*)data); } if (SUCCEEDED(hr)) { hr = pFrame->Commit(); } if (SUCCEEDED(hr)) { hr = pEnc->Commit(); } SafeRelease(&pStream); SafeRelease(&pEnc); SafeRelease(&pFrame); SafeRelease(&pProp); return SUCCEEDED(hr); }