Drawing an image on a window using GFL SDK in MFC - mfc

I want to load an image and want to draw it on a window in OnPaint of CMainFrame. Can any body tell me how can we achieve this using XnView's gfl library.
Thank You

I don't know anything about this library, but 20 seconds of Google shows that you should use one of http://www.xnview.com/wiki/index.php/GFL_Windows_specific to convert your image data to an HBITMAP, then use BitBlt() to copy that onto your window (you can find a lot of examples on how to do that everywhere, but in short you do CDC dc; dc.CreateCompatibleDC(); dc.SelectObject(your_bitmap); paintdc.BitBlt(dc, etc); )

Related

How can I rotate and make the image semitransparent at the same time by using ATL::CImage?

I just started using ATL::CImage in my MFC project, and this is very basic question about it.
I know ATL::CImage members support AlphaBlend() for controlling the transparency, and plgblt() for rotating. But they are all the independent functions for only "Displaying" on DC as I understand.
How Can I apply both transparency and rotation of the image and display/save it?
I know GDI+ supports everything what I want, but I wanna know how to realize them with CImage class members too.
Thank you.
This isn't possible in the same way. You can use a temporary DC for each operation.
Create a DC with a bitmap of the needed size.
Perform the operation of the CImage into the DC.
Get the Bitmap from the DC and form a new CImage or simply work on with the DC.
The better way is always to use GDI+ to perform such operations. CImage is only needed when you need to store the interim result, or need to reuse it.

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.

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.

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()

C++ Win32, easiest way to show a window with a bitmap

It's only for 'debugging' purposes, so I don't want to spend a lot of time with this, nor it is very important. The program exports the data as a png, jpg, svg, etc... -so it's not a big deal, though it could be good to see the image while it is being generated. Also, the program is going to be used in a Linux server; but I'll limit this 'feature' to the Win version.
I also don't want to use a library, except if it is very, very lightweight (I used CImg for a while, but I wasn't very happy with its speed, so I ended up writing the important functions myself and just using libjpeg and libpng directly).
I have the image in an ARGB format (32bpp), though converting the format won't be a problem at all. I would like to use Win32, creating a window from a function deep inside the code (no known hInstance, etc), and writing the bitmap. Fast and easy, hopefully.
But I don't know the win32api enough. I've seen that the only option to draw (GDI) is trough a HBITMAP object... Any code snippet or example I can rely on? Any consideration I might not overlook? Or maybe -considering my time constrains- should I just forget it?
Thanks!
The biggest piece of work here is actually registering the window class and writing a minimal window procedure. But if this is debug only code, you can actually skip that part. (I'll come back to that later).
If you have an HBITMAP, then you would use BitBlt or StretchBlt to draw it, but if you don't already have the image as an HBITMAP, then StretchDIBits is probably a better choice since you can use it if you only have a pointer to the bitmap data. You have to pass it a source and destination rectangle, a BITMAPINFOHEADER and a pointer to the raw bitmap data. Something like this
SIZE sBmp = { 100, 200 };
LPBITMAPINFOHEADER pbi; // the bitmap header from the file, etc.
LPVOID pvBits; // the raw bitmap bits
StretchDIBits (hdc, 0, 0, sBmp.cx, sBmp.cy,
0, 0, sBmp.cx, sBmp.cy,
pvBits, pbi,
DIB_RGB_COLORS,
SRCCOPY);
So the next part is how do I get a HDC to draw in? Well for Debug code, I often draw directly to the screen. HDC hdc = GetDC(NULL) will get a DC that can draw to the screen, but there are security issues and it doesnt' work the same with Aero in Windows Vista, so the other way is to draw onto a window. If you have a window that you can just draw over, then HDC hdc = GetDC(hwnd) will work.
The advantage of doing it this way is that you don't have to create and show a window, so it's less disruptive of code flow, It's helpful for debugging a specific problem, but not the sort of thing you can leave turned on all of the time.
For a longer term solution, You could create a dialog box and put your bitmap drawing call in the WM_PAINT or WM_ERASEBKGND message handler for the dialog box. But I don't recommend that you show a dialog box from deep inside code that isn't supposed to be doing UI. Showing a window, especially a dialog window will interfere with normal message flow in your application. If you want to use a dialog box for this bitmap viewer, then you want that dialog window to be something that the User shows, and that you just draw onto if it's there.
If you don't have access to an HINSTANCE, it's still possible to show a dialog box, it's just more work. That's sort of a different question.
About all you need is a handle to a device context (HDC). To display your data on it:
CreateDibSection to create a DIBSection.
Copy your data to the memory block returned by CreateDibSection.
create a DC compatible with the target DC.
Select the DIBSection into your newly created DC.
BitBlt (or StretchBlt) from your DC to the target DC.