Esempio n. 1
0
// 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;

}
Esempio n. 2
0
	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;
	}