I am loading a Image using WIC (windows imaging component). I need to modification in the image.
To get the pixel values I used this code. But the transparency is lost with this code ..
I changed the code from
m_pRT->CreateBitmapFromWicBitmap(m_pConvertedSourceBitmap, nullptr, &m_pD2DBitmap);
transparency is working with this.
to
OriginalImage = new RGBQUAD[1536 * 2048];
m_pConvertedSourceBitmap->CopyPixels(NULL, 1536 * sizeof(RGBQUAD), 1536 * 2048 * sizeof(RGBQUAD), reinterpret_cast<BYTE*>(OriginalImage));
/*
Calculations in RGBQUAD
*/
m_pD2DBitmap->CopyFromMemory(NULL, reinterpret_cast<BYTE*>(OriginalImage), 1536 * sizeof(RGBQUAD));
Now while displaying m_pD2DBitmap transparency is not working transparent area is changed to black..
Please tell me how to make that to transparent.
Here is the complete code. .
#include "App.h"
#include "resource.h"
#include <d2d1.h>
#include <strsafe.h>
#include <math.h>
#pragma comment(linker, \
"\"/manifestdependency:type='Win32' "\
"name='Microsoft.Windows.Common-Controls' "\
"version='6.0.0.0' "\
"processorArchitecture='*' "\
"publicKeyToken='6595b64144ccf1df' "\
"language='*'\"")
#pragma comment(lib, "ComCtl32.lib")
#pragma comment(lib, "d2d1")
Application::Application()
{
OriginalImage = new RGBQUAD[1536 * 2048];
}
Application::~Application()
{
delete[] OriginalImage;
OriginalImage = NULL;
}
template <typename T>
inline void SafeRelease(T *&p)
{
if (nullptr != p)
{
p->Release();
p = nullptr;
}
}
int APIENTRY wWinMain(
_In_ HINSTANCE hInstance,
_In_opt_ HINSTANCE hPrevInstance,
_In_ LPWSTR lpCmdLine,
_In_ int nShowCmd
)
{
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
Application application;
application.Run(hInstance, nShowCmd);
}
int Application::Run(HINSTANCE hInstance, int nCmdShow)
{
MSG msg = { 0 };
WNDCLASS wc;
// Dialog custom window class
ZeroMemory(&wc, sizeof(wc));
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.cbWndExtra = DLGWINDOWEXTRA;
wc.hCursor = LoadCursorW(NULL, IDC_ARROW);
wc.hIcon = LoadIconW(hInstance, MAKEINTRESOURCE(IDD_DIALOG1));
wc.lpfnWndProc = DefDlgProcW;
wc.lpszClassName = L"CoordinateMappingBasicsAppDlgWndClass";
if (!RegisterClassW(&wc))
{
return 0;
}
// Create main application window
HWND hWndApp = CreateDialogParamW(
NULL,
MAKEINTRESOURCE(IDD_DIALOG1),
NULL,
(DLGPROC)Application::MessageRouter,
reinterpret_cast<LPARAM>(this));
// Show window
ShowWindow(hWndApp, nCmdShow);
HRESULT hr = CoCreateInstance(
CLSID_WICImagingFactory,
nullptr,
CLSCTX_INPROC_SERVER,
IID_PPV_ARGS(&m_pIWICFactory)
);
if (SUCCEEDED(hr))
{
// Create D2D factory
hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &m_pD2DFactory);
}
// Main message loop
DrawImage();
//InvalidateRect(hWndApp, nullptr, TRUE);
while (WM_QUIT != msg.message)
{
while (PeekMessageW(&msg, NULL, 0, 0, PM_REMOVE))
{
// If a dialog message will be taken care of by the dialog proc
if (hWndApp && IsDialogMessageW(hWndApp, &msg))
{
continue;
}
TranslateMessage(&msg);
DispatchMessageW(&msg);
}
}
return static_cast<int>(msg.wParam);
}
LRESULT CALLBACK Application::MessageRouter(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
Application* pThis = NULL;
if (WM_INITDIALOG == uMsg)
{
pThis = reinterpret_cast<Application*>(lParam);
SetWindowLongPtr(hWnd, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(pThis));
}
else
{
pThis = reinterpret_cast<Application*>(::GetWindowLongPtr(hWnd, GWLP_USERDATA));
}
if (pThis)
{
return pThis->DlgProc(hWnd, uMsg, wParam, lParam);
}
return 0;
}
LRESULT CALLBACK Application::DlgProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
UNREFERENCED_PARAMETER(wParam);
UNREFERENCED_PARAMETER(lParam);
switch (message)
{
case WM_INITDIALOG:
{
// Bind application window handle
m_hWnd = hWnd;
}
break;
// If the titlebar X is clicked, destroy app
case WM_CLOSE:
DestroyWindow(hWnd);
break;
case WM_DESTROY:
// Quit the main message pump
PostQuitMessage(0);
break;
// Handle button press
case WM_COMMAND:
// If it was for the screenshot control and a button clicked event, save a screenshot next frame
/*
if (IDC_BUTTON_SCREENSHOT == LOWORD(wParam) && BN_CLICKED == HIWORD(wParam))
{
m_bSaveScreenshot = true;
}
*/
break;
}
return FALSE;
}
void Application::DrawImage(){
CreateDeviceResources(m_hWnd);
IWICBitmapDecoder *pDecoder = nullptr;
WCHAR szFileName[MAX_PATH] = L"sample1.png";
HRESULT hr = m_pIWICFactory->CreateDecoderFromFilename(
szFileName, // 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
);
IWICBitmapFrameDecode *pFrame = nullptr;
if (SUCCEEDED(hr))
{
hr = pDecoder->GetFrame(0, &pFrame);
}
if (SUCCEEDED(hr))
{
SafeRelease(m_pConvertedSourceBitmap);
hr = m_pIWICFactory->CreateFormatConverter(&m_pConvertedSourceBitmap);
}
if (SUCCEEDED(hr))
{
hr = m_pConvertedSourceBitmap->Initialize(
pFrame, // Input bitmap to convert
GUID_WICPixelFormat32bppPBGRA, // Destination pixel format
WICBitmapDitherTypeNone, // Specified dither pattern
nullptr, // Specify a particular palette
0.f, // Alpha threshold
WICBitmapPaletteTypeCustom // Palette translation type
);
}
if (SUCCEEDED(hr))
{
// Need to release the previous D2DBitmap if there is one
SafeRelease(m_pD2DBitmap);
//hr = m_pRT->CreateBitmapFromWicBitmap(m_pConvertedSourceBitmap, nullptr, &m_pD2DBitmap);
D2D1_SIZE_U size = D2D1::SizeU(1536, 2048);
hr = m_pRT->CreateBitmap(
size,
D2D1::BitmapProperties(D2D1::PixelFormat(DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_IGNORE)),
&m_pD2DBitmap
);
}
UINT wh=0, ht=0;
m_pConvertedSourceBitmap->GetSize(&wh,&ht);
WCHAR printval[63];
StringCchPrintf(printval, sizeof(printval), L"width %d and height %d ", wh, ht);
OutputDebugString(printval);
m_pConvertedSourceBitmap->CopyPixels(NULL, 1536 * sizeof(RGBQUAD), 1536 * 2048 * sizeof(RGBQUAD), reinterpret_cast<BYTE*>(OriginalImage));
/// Do the resize calculations Here
/////////////////////////////////////////
m_pD2DBitmap->CopyFromMemory(NULL, reinterpret_cast<BYTE*>(OriginalImage), 1536 * sizeof(RGBQUAD));
m_pRT->BeginDraw();
RECT rc;
hr = GetClientRect(m_hWnd, &rc);
D2D1_RECT_F rect = D2D1::RectF(rc.top, rc.left, rc.right, rc.bottom);
m_pRT->SetTransform(D2D1::Matrix3x2F::Identity());
// Clear the background
m_pRT->DrawBitmap(m_pD2DBitmap, rect);
//m_pRT->Clear(D2D1::ColorF(D2D1::ColorF::White));
m_pRT->EndDraw();
//delete[] tempImage;
SafeRelease(pDecoder);
SafeRelease(pFrame);
}
HRESULT Application::CreateDeviceResources(HWND hWnd)
{
HRESULT hr = S_OK;
if (!m_pRT)
{
RECT rc;
hr = GetClientRect(hWnd, &rc) ? S_OK : E_FAIL;
if (SUCCEEDED(hr))
{
auto renderTargetProperties = D2D1::RenderTargetProperties();
// Set the DPI to be the default system DPI to allow direct mapping
// between image pixels and desktop pixels in different system DPI settings
renderTargetProperties.dpiX = 96.0;
renderTargetProperties.dpiY = 96.0;
auto size = D2D1::SizeU(rc.right - rc.left, rc.bottom - rc.top);
hr = m_pD2DFactory->CreateHwndRenderTarget(
renderTargetProperties,
D2D1::HwndRenderTargetProperties(hWnd, size),
&m_pRT
);
}
}
return hr;
}
as per Jonathan,
After changing the GUID_WICPixelFormat32bppPBGRA
to GUID_WICPixelFormat32bppBGRA
now transparency is woking.. But it loses around the image..