2

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_WICPixelFormat32bppBGRAnow transparency is woking.. But it loses around the image..

enter image description here Thanks in advance !!

Wickkiey
  • 4,446
  • 2
  • 39
  • 46
  • 2
    Are the pixel formats the same? `GUID_WICPixelFormat32bppPBGRA` and `DXGI_FORMAT_B8G8R8A8_UNORM` I mean? For one thing, the WIC format looks like it might use pre-multipled alpha, but also the byte order looks like it might be reversed. Maybe try `GUID_WICPixelFormat32bppBGRA` instead? – Jonathan Potter May 12 '16 at 07:21
  • Also (and I'd bet this is the actual problem) `D2D1_ALPHA_MODE_IGNORE` looks wrong. – Jonathan Potter May 12 '16 at 07:24
  • @JonathanPotter Thanks for the fix. But now it is not transparent around the image. . Added to the question.. – Wickkiey May 12 '16 at 07:37

0 Answers0