static bool convert_file_icon(const HICON icon, Bmp& bmp) { static IWICImagingFactory* img_factory = 0; if (!img_factory) { // In VS 2011 beta, clsid has to be changed to CLSID_WICImagingFactory1 (from CLSID_WICImagingFactory) if (!SUCCEEDED(::CoInitialize(0)) || !SUCCEEDED(::CoCreateInstance(CLSID_WICImagingFactory1, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&img_factory)))) { return false; } } IWICBitmap* pBitmap = 0; IWICFormatConverter* pConverter = 0; UINT cx = 0, cy = 0; if (SUCCEEDED(img_factory->CreateBitmapFromHICON(icon, &pBitmap))) { if (SUCCEEDED(img_factory->CreateFormatConverter(&pConverter))) { if (SUCCEEDED(pConverter->Initialize(pBitmap, GUID_WICPixelFormat32bppPBGRA, WICBitmapDitherTypeNone, 0, 0.0f, WICBitmapPaletteTypeCustom))) { if (SUCCEEDED(pConverter->GetSize(&cx, &cy))) { const UINT stride = cx * sizeof(DWORD); const UINT buf_size = cy * stride; Byte* buf = new Byte[buf_size]; pConverter->CopyPixels(0, stride, buf_size, buf); bmp.load_bits_only(buf, buf_size, cx, -(int)cy); delete [] buf; } } pConverter->Release(); } pBitmap->Release(); } return true; }
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); }
BitmapWrapperD2D::BitmapWrapperD2D(bitmap bmp) { IWICBitmap* wic = 0; Graphics::locator.getfactory()->CreateBitmapFromMemory( bmp.width(), bmp.height(), GUID_WICPixelFormat32bppBGRA, 4 * bmp.width(), bmp.length(), (BYTE*)bmp.data(), &wic); if (wic != 0) { IWICFormatConverter* converter = nullptr; IWICBitmap* temp = nullptr; int result = Graphics::locator.getfactory()->CreateFormatConverter(&converter); if (result == 0) { converter->Initialize(wic, GUID_WICPixelFormat32bppPBGRA, WICBitmapDitherTypeNone, 0, 0.f, WICBitmapPaletteTypeMedianCut); Graphics::locator.getfactory()->CreateBitmapFromSource(converter, WICBitmapNoCache, &temp); converter->Release(); } wic->Release(); ID2D1BitmapRenderTarget* target = Graphics::locator.gettarget(); if (target) { target->CreateBitmapFromWicBitmap(temp, &source); temp->Release(); temp = nullptr; } else { source = nullptr; } } else { source = nullptr; } }
pair<imgcontext, size_t> imagecache::createimage(bitmap bmp) { size_t id = bmp.id(); if (temp[imgcon][id] || cache[imgcon][id]) { return make_pair(imgcon, id); } else { IWICBitmap* wic = 0; imgfactory->CreateBitmapFromMemory( bmp.width(), bmp.height(), GUID_WICPixelFormat32bppBGRA, 4 * bmp.width(), bmp.length(), (BYTE*)bmp.data(), &wic); if (wic) { IWICFormatConverter* spConverter = 0; int result = imgfactory->CreateFormatConverter(&spConverter); if (result == 0) { spConverter->Initialize(wic, GUID_WICPixelFormat32bppPBGRA, WICBitmapDitherTypeNone, NULL, 0.f, WICBitmapPaletteTypeMedianCut); imgfactory->CreateBitmapFromSource(spConverter, WICBitmapNoCache, &temp[imgcon][id]); spConverter->Release(); } wic->Release(); } } return make_pair(imgcon, id); }
Image::Buffer * WIC::Api::CreateImage(char * data, unsigned dataSize, unsigned w, unsigned h, Image::Format format) { IWICBitmap * bitmap = 0; factory->CreateBitmap(w, h, IMAGE_FORMAT_TO_WIC_GUID[format], WICBitmapCacheOnLoad, &bitmap); if(!bitmap) return 0; WICRect lockRect = { 0, 0, w, h }; IWICBitmapLock * lock = 0; bitmap->Lock(&lockRect, WICBitmapLockWrite, &lock); if(!lock) { bitmap->Release(); return 0; } unsigned bufferSize = 0; WICInProcPointer dataPointer = 0; lock->GetDataPointer(&bufferSize, &dataPointer); memcpy(dataPointer, data, dataSize); lock->Release(); lock = 0; if(format != Image::Format_4x8intRGBA) { IWICBitmapSource * convertedSource = 0; WICConvertBitmapSource(GUID_WICPixelFormat32bppRGBA, bitmap, &convertedSource); bitmap->Release(); bitmap = 0; if(!convertedSource) return 0; // Create the bitmap from the image frame. factory->CreateBitmapFromSource( convertedSource, // Create a bitmap from the image frame WICBitmapCacheOnDemand, // Cache metadata when needed &bitmap); // Pointer to the bitmap convertedSource->Release(); if(!bitmap) return 0; } bitmap->Lock(&lockRect, WICBitmapLockWrite, &lock); if(!lock) { bitmap->Release(); return 0; } return new WIC::Buffer(bitmap, lock, w, h); }
HRESULT CMainWindow::DecodeImageFromThumbCache( IShellItem *pShellItem, ID2D1Bitmap **ppBitmap ) { const UINT THUMB_SIZE = 256; // Read the bitmap from the thumbnail cache IThumbnailCache *pThumbCache; HRESULT hr = CoCreateInstance( CLSID_LocalThumbnailCache, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pThumbCache) ); if (SUCCEEDED(hr)) { ISharedBitmap *pBitmap; hr = pThumbCache->GetThumbnail( pShellItem, THUMB_SIZE, WTS_SCALETOREQUESTEDSIZE, &pBitmap, NULL, NULL ); if (SUCCEEDED(hr)) { HBITMAP hBitmap; hr = pBitmap->GetSharedBitmap( &hBitmap ); if (SUCCEEDED(hr)) { // Create a WIC bitmap from the shared bitmap IWICImagingFactory *pFactory; hr = CoCreateInstance( CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pFactory) ); if (SUCCEEDED(hr)) { IWICBitmap *pWICBitmap; hr = pFactory->CreateBitmapFromHBITMAP( hBitmap, NULL, WICBitmapIgnoreAlpha, &pWICBitmap ); if (SUCCEEDED(hr)) { // Create a D2D bitmap from the WIC bitmap hr = m_pRenderTarget->CreateBitmapFromWicBitmap( pWICBitmap, NULL, ppBitmap ); pWICBitmap->Release(); } pFactory->Release(); } } pBitmap->Release(); } pThumbCache->Release(); } return hr; }
// 解码照片的基础位图文件的. 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; }