Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Using GDI+ from MFC C++ ???

532 views
Skip to first unread message

Peter Olcott

unread,
Mar 1, 2010, 4:06:39 PM3/1/10
to
All of the links that I have found say they are showing you
how to use GDI+ from C++, by they actually show you how to
use GDI+ from C, not C++. For example they show you how to
modify the WinMain() function. There is no WinMain()
function in my MFC code.

I want to be able to load and save PNG files and BMP files.
Since Windows now does this, I would prefer to use Windows
instead of any third party library.


David Lowndes

unread,
Mar 1, 2010, 4:25:33 PM3/1/10
to
>All of the links that I have found say they are showing you
>how to use GDI+ from C++, by they actually show you how to
>use GDI+ from C, not C++. For example they show you how to
>modify the WinMain() function. There is no WinMain()
>function in my MFC code.

Just because it's using WinMain doesn't necessarily mean it's using
'C' rather than C++.

Anyhow, what code are these examples putting in WinMain that is posing
you with a problem?

Dave

Peter Olcott

unread,
Mar 1, 2010, 4:34:56 PM3/1/10
to

"David Lowndes" <Dav...@example.invalid> wrote in message
news:f1coo5t5u8kc3q3q8...@4ax.com...

Now I have the problem simplified down to this command line
code sample will not compile:
http://msdn.microsoft.com/en-us/library/ms533837(VS.85).aspx
I am getting a bunch of link errors, here is one of them:

gdipng.obj : error LNK2019: unresolved external symbol
_GdipFree@4 referenced in function "public: static void
__cdecl Gdiplus::GdiplusBase::operator delete(void *)"

>
> Dave


David Ching

unread,
Mar 1, 2010, 4:41:34 PM3/1/10
to
"Peter Olcott" <NoS...@OCR4Screen.com> wrote in message
news:W7mdncFCK47CsRHW...@giganews.com...

> All of the links that I have found say they are showing you how to use
> GDI+ from C++, by they actually show you how to use GDI+ from C, not C++.
> For example they show you how to modify the WinMain() function. There is
> no WinMain() function in my MFC code.
>

You may want to read about CImage.

-- David

David Ching

unread,
Mar 1, 2010, 4:41:13 PM3/1/10
to
"Peter Olcott" <NoS...@OCR4Screen.com> wrote in message
news:rfKdndhqLPufrhHW...@giganews.com...

> Now I have the problem simplified down to this command line code sample
> will not compile:
> http://msdn.microsoft.com/en-us/library/ms533837(VS.85).aspx
> I am getting a bunch of link errors, here is one of them:
>
> gdipng.obj : error LNK2019: unresolved external symbol _GdipFree@4
> referenced in function "public: static void __cdecl
> Gdiplus::GdiplusBase::operator delete(void *)"
>

Are you linking with gdiplus.lib? This needs to go into the Linker
settings, I believe in the Additional Dependencies option.

-- David

Giovanni Dicanio

unread,
Mar 1, 2010, 4:43:14 PM3/1/10
to
"Peter Olcott" <NoS...@OCR4Screen.com> ha scritto nel messaggio
news:rfKdndhqLPufrhHW...@giganews.com...

> Now I have the problem simplified down to this command line code sample
> will not compile:
> http://msdn.microsoft.com/en-us/library/ms533837(VS.85).aspx
> I am getting a bunch of link errors, here is one of them:
>
> gdipng.obj : error LNK2019: unresolved external symbol _GdipFree@4
> referenced in function "public: static void __cdecl
> Gdiplus::GdiplusBase::operator delete(void *)"

Did you link with gdiplus.lib ?

Giovanni

Giovanni Dicanio

unread,
Mar 1, 2010, 4:46:00 PM3/1/10
to
"Peter Olcott" <NoS...@OCR4Screen.com> ha scritto nel messaggio
news:W7mdncFCK47CsRHW...@giganews.com...

> All of the links that I have found say they are showing you how to use
> GDI+ from C++, by they actually show you how to use GDI+ from C, not C++.

I think GDI+ is a *C++ API* (not a C API, like e.g. GDI).
I think you can't use GDI+ from pure C.

> For example they show you how to modify the WinMain() function. There is
> no WinMain() function in my MFC code.

There is a WinMain function in MFC code, but it is implemented by MFC and
not by you.

Personally, I like the MSDN approach of not using any C++ framework to show
GDI+ usage.
Why should they use MFC? Why not ATL? And what about other C++ frameworks?

If MSDN shows pure Win32 code samples, then you can adapt them in your
particular production framework, be it MFC or ATL or other...

Giovanni

Giovanni Dicanio

unread,
Mar 1, 2010, 4:51:32 PM3/1/10
to
This code compiles fine with VS2008 SP1 (note that GetEncoderClsid body is
required):

<code>

#include <windows.h>
#include <gdiplus.h>
#include <stdio.h>
using namespace Gdiplus;

#pragma comment(lib, "gdiplus.lib")


int GetEncoderClsid(const WCHAR* format, CLSID* pClsid)
{
UINT num = 0; // number of image encoders
UINT size = 0; // size of the image encoder array in bytes

ImageCodecInfo* pImageCodecInfo = NULL;

GetImageEncodersSize(&num, &size);
if(size == 0)
return -1; // Failure

pImageCodecInfo = (ImageCodecInfo*)(malloc(size));
if(pImageCodecInfo == NULL)
return -1; // Failure

GetImageEncoders(num, size, pImageCodecInfo);

for(UINT j = 0; j < num; ++j)
{
if( wcscmp(pImageCodecInfo[j].MimeType, format) == 0 )
{
*pClsid = pImageCodecInfo[j].Clsid;
free(pImageCodecInfo);
return j; // Success
}
}

free(pImageCodecInfo);
return -1; // Failure
}

INT main()
{
// Initialize GDI+.
GdiplusStartupInput gdiplusStartupInput;
ULONG_PTR gdiplusToken;
GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);

CLSID encoderClsid;
Status stat;
Image* image = new Image(L"Bird.bmp");

// Get the CLSID of the PNG encoder.
GetEncoderClsid(L"image/png", &encoderClsid);

stat = image->Save(L"Bird.png", &encoderClsid, NULL);

if(stat == Ok)
printf("Bird.png was saved successfully\n");
else
printf("Failure: stat = %d\n", stat);

delete image;
GdiplusShutdown(gdiplusToken);
return 0;
}

</code>


"Giovanni Dicanio" <giovanniD...@REMOVEMEgmail.com> ha scritto nel
messaggio news:egTZ1gYu...@TK2MSFTNGP06.phx.gbl...

Peter Olcott

unread,
Mar 1, 2010, 5:00:32 PM3/1/10
to

"Giovanni Dicanio" <giovanniD...@REMOVEMEgmail.com>
wrote in message
news:egTZ1gYu...@TK2MSFTNGP06.phx.gbl...

No, I thought that it would already know its own libraries.
Do you know the syntax for this?

cl -EHsc -O2 -linkgdiplus.lib %1.cpp
The above is one of several ways that it does not work.

>
> Giovanni
>
>


Peter Olcott

unread,
Mar 1, 2010, 5:08:59 PM3/1/10
to

"Giovanni Dicanio" <giovanniD...@REMOVEMEgmail.com>
wrote in message
news:ecIoelY...@TK2MSFTNGP06.phx.gbl...

> This code compiles fine with VS2008 SP1 (note that
> GetEncoderClsid body is required):

Yes, I wonder why they left that out? They should have at
least provided a link if it is not in the library.

Giovanni Dicanio

unread,
Mar 2, 2010, 4:35:04 AM3/2/10
to
"Peter Olcott" <NoS...@OCR4Screen.com> ha scritto nel messaggio
news:_Nadnak4gcGfpBHW...@giganews.com...

>> Did you link with gdiplus.lib ?
>
> No, I thought that it would already know its own libraries.
> Do you know the syntax for this?
>
> cl -EHsc -O2 -linkgdiplus.lib %1.cpp
> The above is one of several ways that it does not work.

In compilable code I posted above, I used a #pragma:

#pragma comment(lib, "gdiplus.lib")

Giovanni

Giovanni Dicanio

unread,
Mar 2, 2010, 4:35:43 AM3/2/10
to
"Peter Olcott" <NoS...@OCR4Screen.com> ha scritto nel messaggio
news:svydnY0mtcxgpxHW...@giganews.com...

>> This code compiles fine with VS2008 SP1 (note that GetEncoderClsid body
>> is required):
>
> Yes, I wonder why they left that out? They should have at least provided a
> link if it is not in the library.

It's a documentation error.
I agree with you.

Giovanni

Joseph M. Newcomer

unread,
Mar 2, 2010, 9:39:02 AM3/2/10
to
I fail to understand the problem here. The transformation is generally trivial; anything
a C example initializes in WinMain, you would initialize in the OnInitInstance handler of
your app. This is elementary MFC.
joe

Joseph M. Newcomer [MVP]
email: newc...@flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm

Tom Serface

unread,
Mar 2, 2010, 10:36:58 PM3/2/10
to
I use GDI+ from C++ and it works just fine if you do, as many have
suggested, include the right libs. I also use the CImage class:

http://msdn.microsoft.com/en-us/library/bwea7by5(VS.80).aspx

that does a lot of the work for you. There are lots of interesting articles
on the web about this ATL class. I find it very easy to use. It supports
the same image types as GDI+ as you'd expect.

Tom

"Peter Olcott" <NoS...@OCR4Screen.com> wrote in message

news:W7mdncFCK47CsRHW...@giganews.com...

Peter Olcott

unread,
Mar 2, 2010, 10:51:02 PM3/2/10
to

"Tom Serface" <t...@camaswood.com> wrote in message
news:Ols4NLou...@TK2MSFTNGP02.phx.gbl...

>I use GDI+ from C++ and it works just fine if you do, as
>many have suggested, include the right libs. I also use
>the CImage class:
>
> http://msdn.microsoft.com/en-us/library/bwea7by5(VS.80).aspx
>
> that does a lot of the work for you. There are lots of
> interesting articles on the web about this ATL class. I
> find it very easy to use. It supports the same image
> types as GDI+ as you'd expect.
>
> Tom

The main thing (and possibly the only thing) that I need
from GDI+ is to read and write PNG files.

Peter Olcott

unread,
Mar 2, 2010, 11:03:58 PM3/2/10
to

"Tom Serface" <t...@camaswood.com> wrote in message
news:Ols4NLou...@TK2MSFTNGP02.phx.gbl...
>I use GDI+ from C++ and it works just fine if you do, as
>many have suggested, include the right libs. I also use
>the CImage class:
>
> http://msdn.microsoft.com/en-us/library/bwea7by5(VS.80).aspx
>
> that does a lot of the work for you. There are lots of
> interesting articles on the web about this ATL class. I
> find it very easy to use. It supports the same image
> types as GDI+ as you'd expect.

I don't think that it sued to load these other file types,
and was not aware that it did now until I examined it again.
I will try this out.

Tom Serface

unread,
Mar 3, 2010, 8:04:30 AM3/3/10
to
In that case CImage would work great for you. It can read, convert, and
save any of the GDI+ types.

Tom

"Peter Olcott" <NoS...@OCR4Screen.com> wrote in message

news:crydnUAuO991QRDW...@giganews.com...

Tom Serface

unread,
Mar 3, 2010, 8:10:17 AM3/3/10
to
Here's a tiny code snippet:

CImage image;
image.Load(csMyGraphicFile); // Don't need to know type at this point
HRESULT hr = image.Save(csPNGPath,Gdiplus::ImageFormatPNG);
if(SUCCEEDED(hr)) // It worked

Tom

"Peter Olcott" <NoS...@OCR4Screen.com> wrote in message

news:crydnUAuO991QRDW...@giganews.com...

Peter Olcott

unread,
Mar 3, 2010, 9:33:34 AM3/3/10
to

"Tom Serface" <t...@camaswood.com> wrote in message
news:e9SFSItu...@TK2MSFTNGP05.phx.gbl...

> In that case CImage would work great for you. It can
> read, convert, and save any of the GDI+ types.

I don't think that it can handle TIFF files, but that its
OK. It is far less hassle than the GDI+ stuff. It only took
me about an hour to fully implement as opposed to ten hours
to halfway implement. The one thing that was holding me up
with the GDI+ stuff was that to get an HBITMAP, I had to
provide a background color. I can't see why it needs to know
this.

Peter Olcott

unread,
Mar 3, 2010, 9:50:18 AM3/3/10
to

"Tom Serface" <t...@camaswood.com> wrote in message
news:eL%23ygLtu...@TK2MSFTNGP06.phx.gbl...

> Here's a tiny code snippet:
>
> CImage image;
> image.Load(csMyGraphicFile); // Don't need to know type at
> this point
> HRESULT hr =
> image.Save(csPNGPath,Gdiplus::ImageFormatPNG);
> if(SUCCEEDED(hr)) // It worked
>
> Tom

Ah that is how you test to see if it worked, good I will add
this to my code. Also apparently it can infer the file save
type from the filename suffix, thus the explicit type does
not seem to be required. Since I am getting the filename
suffix from a common dialogbox, I can count on it being
correct.

David Webber

unread,
Mar 3, 2010, 5:36:35 PM3/3/10
to

"Peter Olcott" <NoS...@OCR4Screen.com> wrote in message

news:JpednSihRNSi7hPW...@giganews.com...


>
> "Tom Serface" <t...@camaswood.com> wrote in message
> news:e9SFSItu...@TK2MSFTNGP05.phx.gbl...

>> In that case CImage would work great for you. It can read, convert, and
>> save any of the GDI+ types.
>
> I don't think that it can handle TIFF files,

Yes it can. See ImageFormatTIFF

Dave

--
David Webber
Mozart Music Software
http://www.mozart.co.uk
For discussion and support see
http://www.mozart.co.uk/mozartists/mailinglist.htm

Tom Serface

unread,
Mar 3, 2010, 9:17:32 PM3/3/10
to
It can do any of the types that GDI+ can do so TIFF is include. However,
there are lots of formats to TIFF (like JPEG) so some of them may not work.
You'll want to do exception catching around the use of the class.

Tom

"Peter Olcott" <NoS...@OCR4Screen.com> wrote in message

news:JpednSihRNSi7hPW...@giganews.com...

Joseph M. Newcomer

unread,
Mar 4, 2010, 12:26:56 AM3/4/10
to
See below...

On Wed, 3 Mar 2010 08:50:18 -0600, "Peter Olcott" <NoS...@OCR4Screen.com> wrote:

>
>"Tom Serface" <t...@camaswood.com> wrote in message
>news:eL%23ygLtu...@TK2MSFTNGP06.phx.gbl...
>> Here's a tiny code snippet:
>>
>> CImage image;
>> image.Load(csMyGraphicFile); // Don't need to know type at
>> this point
>> HRESULT hr =
>> image.Save(csPNGPath,Gdiplus::ImageFormatPNG);
>> if(SUCCEEDED(hr)) // It worked
>>
>> Tom
>
>Ah that is how you test to see if it worked, good I will add
>this to my code. Also apparently it can infer the file save
>type from the filename suffix, thus the explicit type does
>not seem to be required. Since I am getting the filename
>suffix from a common dialogbox, I can count on it being
>correct.

****
Actually, it probably opens the file and looks at the header. GIF, TIFF, PNG, and JPEG
files all have distinctly different header information which can be detected.
joe
****

Ian Harvey

unread,
Mar 5, 2010, 1:19:15 AM3/5/10
to
On 4/03/2010 1:33 AM, Peter Olcott wrote:
> ...

> The one thing that was holding me up
> with the GDI+ stuff was that to get an HBITMAP, I had to
> provide a background color. I can't see why it needs to know
> this.

The Gdiplus image (represented by the Image/Bitmap object) may have
transparent regions - a feature of Gdiplus is that it supports images
that have an alpha channel.

GDI support for transparency is rather limited, so you need to nominate
a colour that will bleed through the transparent regions of your bitmap,
ahead of the actual display of the bitmap.

If your Gdiplus bitmap has no transparency you don't need to worry about
the background colour - you won't be able to see it!

0 new messages