How to read a png image and transfer to ID2D1Bitmap? - c++

I have a C++ project which uses Windows Animation Manager with Direct2D under Visual Studio 2010 to implement image sparkled animation.
But when I load a png image, the transparent can’t display correctly.
I use IWICImagingFactory and IWICBitmap to load the png image, and then create a D2D bitmap from the WIC bitmap. The D2D1_PIXEL_FORMAT’s alphaMode set as D2D1_ALPHA_MODE_PREMULTIPLIED and format set as DXGI_FORMAT_B8G8R8A8_UNORM. It seems only opaque and transparent without semitranslucent. And I try to change the D2D1_PIXEL_FORMAT’s alphaMode to D2D1_ALPHA_MODE_STRAIGHT but it doesn’t work. I also follow the sample code from MSDN ( http://msdn.microsoft.com/en-us/library/windows/desktop/ee719658(v=vs.85).aspx ), but nothing display. Can someone help me that how to load a png image and transfer to ID2D1Bitmap with correct alpha value? Thanks!

I already solved my question from the example code under \Microsoft SDKs\Windows\v7.1\Samples\multimedia\wic\wicviewerd2d. The important keyword is GUID_WICPixelFormat32bppPBGRA when initialize the IWICFormatConverter object.

Related

How to create and edit a bitmap

I'm trying to create a bitmap that I can change the pixels of and then update the window with that bitmap. I've tried to research a way to just create a bitmap, but that was to no avail.
I need to know how to create a blank bitmap, then change its pixels using x and y coordinates and a color, and then how to draw it to the window. I don't need to save it to the computer and I don't want to convert an existing image into a bitmap.
I'm on windows and using Visual Studio with C++
Just to specify, I need to know the syntax for creating a blank bitmap with a certain width and height, and also what function I need to use to change the pixels' colors, and then how to draw a bitmap to the window. Thank you.
There is a free library ImgSource that you can use which has a huge amount of functionality for images.
http://www.smalleranimals.com/isource.htm
It is available in MSDN, but using a library like ImgSource may be to your advantage.
It provides simple methods for rendering your image onto a device context. And there is a good support forum.

Loading PNG file. Need to get RGBA HBITMAP

I'm trying to create a splash screen that will show transparent png background. So at first I need to load png file into format that is acceptable for the UpdateLayeredWindow calls (basically HBITMAP with RGBA format).
At the moment, I've found Windows Imaging Component, but that does not work for VS2005 (which is mandatory requirement). Using some additional libraries is also a problem.
I've heard that GDI+ can do the trick, but I can't find a proper example unfortunately :( Can anyone help?

Using PNGs with Button Controls

I am trying to render a PNG on a button control for my dialog box (Visual Studio 2010 Professional). After doing some research, I found the following method which works for BMP files:
HBITMAP hBitmap = (HBITMAP) LoadImage(NULL, L"test.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
SendMessage(GetDlgItem(hDlg, IDC_BUTTON1), BM_SETIMAGE, IMAGE_BITMAP, (LPARAM)hBitmap);
This does not work with PNG files, though. After some more research, I found that there is a simple way to do this using GDI+:
HBITMAP hBitmap;
Gdiplus::Bitmap b(L"a.png");
b.GetHBITMAP(NULL, &hBitmap);
SendMessage(GetDlgItem(hDlg, IDC_BUTTON1), BM_SETIMAGE, IMAGE_BITMAP, (LPARAM)hBitmap);
I am not using GDI+ anywhere else in my program but I still need to include the headers, link to the library and initialize it just to accomplish this simple task. Is it worth all of this trouble? Is there a more standard way to do this?
I plan to render multiple PNGs (some transparent) on a single button.
EDIT: The (slightly modified) CreateDIBSectionFromBitmapSource() function that I am using to create the HBITMAP can be found here:
http://archive.msdn.microsoft.com/Project/Download/FileDownload.aspx?ProjectName=win7wicsamples&DownloadId=7549
Can you be a bit more specific about you mean by "Rendering" a PNG on a button control...
If you mean that you are trying to stick a .PNG image on a button, then yes there is an easier way. Just click on the button and go to 'Appearance in the properties menu. Click on 'BackgroundImage', select local resource, then browse to the image and load it. Done.
If this isn't what you mean to do, then I might suggest researching
System.Drawing.Image and using the GDI+
I am actually sitting here learning GDI+ as we speak. Be forewarned, it's a time and a half to learn.
GDI+ is a standard way for reading and rendering images in different format. Other way of doing this would be to create the PNG decoder component and acquiring the stream from it and pass it to LoadImage function, which is exactly what GDI+ does for you in the back ground. The image format encoders and decoders are part of window imaging component.
In terms of how decoding and rendering is going to perform for multiple images depends on what you are looking for and I am not sure about it. Let me just leave a few comments. What you may do and are doing now (through button's back-ground image option) is to decode the images once and keep them as bit map so when painting has to be done the bitmap is ready and no decoding needs to be done. This is what button's back-ground image painting does too, the button component keeps the bitmap handle you pass it and would just paint the same every it has to repaint. I don't think you need to worry about performance of painting a bitmap because it is done using Bitblt to the display device directly.

how to change the background colour of CImage object in mfc?

I have an windows app which contains some dialogs. the dialogs have been built using mfc. I am drawing some images (.png) on every dialog using CImage::Draw() method. I want to mention that I am not using any picture contol on the dialog to render these images instead I am loading them at runtime using some handle.till this everything is ok. now when the image is loaded the background of those images are coming as white. the images in the resource file does not have the white background. my question is how to change the background of these images while drawing them on the dialog? I want the background of the image similar to the color of default dialog which i am using.
One more question the .png images are not rendering well(the images are scattered) in the dialogs of windows server 2008 R2 machine. what could be the possible remedy for this?
any help will be appreciated.
Your PNG images are obviously not 32-bit. You need an alpha channel and a transparent background. Open your images in e.g. Paint.NET. I bet your background is white there too! Regarding the image quality, are you stretching your images on draw?
Edit: For 8-bit imagers, I believe a call to SetTransparentColor is required. For 32-bit images, perhaps this function will do: TransparentBlt

Show Win32 popup menu with PNG icons from resources

It's been a long time since I've had to deal with Win32 menus. I need to add some PNG icons to a Win32 context popup menu. Naturally, I want to preserve PNG transparency and all the per-pixel-alpha in the process. Is this possible?
I was thinking on using SetMenuItemBitmaps. Is that the way to go?
I imported my PNGs as "PNG" resources but I can't seem to load them neither with LoadBitmap nor with LoadImage. I found some suggestions about using Gdi+ but obviously I won't be drawing the menu - the system will.
There seems to be a way to get a HBITMAP from a Gdi+ Bitmap but it looks as if all the alpha is getting lost in the process. AFAIK, a HBITMAP can happily host alpha information.
You need GDI+ to load a PNG. Then you need to create a 32-bit alpha bitmap of the correct size, create a Graphics on the bitmap, and use DrawImage to copy the PNG to the bitmap. That gives you a bitmap with an alpha channel.
Something like this:
Image* pimgSrc = Image::FromFile("MyIcon.png"L, FALSE);
Bitmap* pbmpImage = new Bitmap(
iWidth, iHeight,
PixelFormat32bppARGB
);
Graphics* pgraphics = Graphics::FromImage(bmpImage))
{
// This draws the PNG onto the bitmap, scaling it if necessary.
// You may want to set the scaling quality
graphics->DrawImage(
imageSrc,
Rectangle(0,0, bmpImage.Width, bmpImage.Height),
Rectangle(0,0, imgSrc.Width, imgSrc.Height),
GraphicsUnitPixel
);
}
// You can now get the HBITMAP from the Bitmap object and use it.
// Don't forget to delete the graphics, image and bitmap when done.
Perhaps you could use icon instead?
Here are my reasons for using icons instead of PNGs:
The Win32 API has good support icons, and it relatively much easier to draw icons, since GDI+ is not required.
Icons also support 8-bit transparency (just like PNGs).
Icons can be any size in pixels (just like PNGs).
Icons can easily be embedded in the executable as a resource.
Icons can be edited via Visual Studio.
To load an icon from a resource or a file use:
LoadImage()
To draw the icon, use:
DrawIcon() or DrawIconEx()