c++ - how use GDIPLUS library?

i'm trying use the GDIPLUS library. i did the include and i add the library to link options. but the image isn't showed:
1
2
3
4
5
6
7
8
9
10
11
12
13
hdcimage = CreateCompatibleDC(NULL);

            Gdiplus::Graphics graphics(hdcimage); //Handle to the device context

            //Load the image from a file
            const size_t len = filename.length() + 1;
            wchar_t wcstring[len];
            swprintf(wcstring, len, L"%s", filename.c_str());

            Gdiplus::Image img(wcstring);
            graphics.DrawImage(&img, 0, 0, img.GetWidth(), img.GetHeight());
            imageweight=img.GetWidth();
            imageheight=img.GetHeight();

what i'm doing wrong?
This would be better in the windows section.

The problem is graphics which has a 'compatible DC'. Not the real one. You need a BitBlt to the DC provide in the WM_PAINT message.

See:
http://msdn.microsoft.com/en-us/library/windows/desktop/dd183370%28v=vs.85%29.aspx
http://msdn.microsoft.com/en-us/library/windows/desktop/dd145213%28v=vs.85%29.aspx
Last edited on
1. did you initialize Gdiplus library?

Ref: http://msdn.microsoft.com/en-us/library/ms534077(v=vs.85).aspx

Ex:
1
2
3
4
5
6
7
8
9
10
11
    {
        // before any Gdiplus call
        GdiplusStartupInput gdiplusStartupInput;
        ULONG_PTR gdiplusToken;
        GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);

        // create graphics
        // load image 
        // check last status
        // draw image
    }


2. Check the load status of the image:
Image::GetLastStatus()
Ref: http://msdn.microsoft.com/en-us/library/ms535383(v=vs.85).aspx

1
2
3
4
5
6
7
8
9
Gdiplus::Status e = img.GetLastStatus();
if(e != Gdiplus::Ok)
{
    // ??? get detailed error info ref GdiPlusTypes.h
}
else
{
    // go ahead and draw
}


now i can draw it. but i need build a private Image variable in my class:
1
2
3
4
5
6
7
8
class image
{
private:
    ULONG_PTR m_gdiplusToken;
    Gdiplus::GdiplusStartupInput gdiplusStartupInput;
    HDC hdcimage=CreateCompatibleDC(NULL);
    Gdiplus::Graphics graphics;
    Gdiplus::Image img;

but the img seems ignored :(
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
 image(	const string & filename)  : graphics(hdcimage),img(towstring(filename).c_str())
    {
        Gdiplus::GdiplusStartup(&m_gdiplusToken, &gdiplusStartupInput, NULL);
//Load the image from a file
            const size_t len = filename.length() + 1;
            wchar_t wcstring[len];
            swprintf(wcstring, len, L"%s", filename.c_str());

            Gdiplus::Image img2(wcstring);

            HBITMAP hbitmap=CreateBitmap(img2.GetWidth(),img2.GetHeight(),1,32,NULL);
            SelectObject(hdcimage, hbitmap);
            Gdiplus::Graphics graphics(hdcimage);
            graphics.DrawImage(&img2, 0, 0, img2.GetWidth(), img2.GetHeight());
            Gdiplus::Font fnt(L"Verdana", 10);
            Gdiplus::SolidBrush solidBrush(Gdiplus::Color(255, 255, 0, 0));

            Gdiplus::PointF pt(2, 2);
            Gdiplus::Pen      pen(Gdiplus::Color(255,0,255,0));
            graphics.DrawString(L"Drawing Text", -1,&fnt, pt,&solidBrush );
            graphics.DrawLine(&pen, 0, 0, 200, 100);
            imageweight=img2.GetWidth();
            imageheight=img2.GetHeight();
            UINT count = 0;
            count = img2.GetFrameDimensionsCount();
            GUID* pDimensionIDs = (GUID*)malloc(sizeof(GUID)*count);
            img2.GetFrameDimensionsList(pDimensionIDs, count);

            framecount=img2.GetFrameCount(&pDimensionIDs[0]);
            framedelay =img2.GetPropertyItemSize(PropertyTagFrameDelay);
            img.FromFile(wcstring);
            MessageBox(NULL,to_string(img.GetWidth()).c_str(),"gif width",MB_OK);
}

heres my function for convert the types:
1
2
3
4
5
6
7
std::wstring towstring(const std::string& s)
{
    const size_t len = s.length() + 1;
    wchar_t wcstring[len];
    swprintf(wcstring, len, L"%s", s.c_str());
    return wcstring;
}

why the img don't read the file?(because i recive '0', when i know that is 70)
You want to convert a cha* to a wchar_t* ? Use MultiByteToWideChar() API:
http://msdn.microsoft.com/en-us/library/windows/desktop/dd319072(v=vs.85).aspx

Or you can use mbstowcs which does the same thing I believe:
http://www.cplusplus.com/reference/cstdlib/mbstowcs/



I'd use always Unicode and avoid all this completely instead. Use MessageBoxW directly.
i use string because is more easy, then, to work
sorry.. these convertion is kill me :(
1
2
3
4
5
6
7
8
std::wstring towstring(const std::string& s)
{

    wstring Wstring;
    Wstring.resize(s.size());
    int c =  MultiByteToWideChar( CP_UTF8 , 0 , s.c_str() , s.size() , &Wstring[0], 0 );
    return Wstring;
}

and how i use it:
img.FromFile(towstring(filename));
filename is a string.
MultiByteToWideChar might remove compact some characters from the string resulting in Wstring having a smaller size() than s.size().

Here's a function you can use:

1
2
3
4
5
6
7
8
9
    std::wstring towstring(const std::string& v)
    {
        std::wstring out(v.size()+1,L'\0');

        int size = MultiByteToWideChar(CP_UTF8, 0, v.c_str(), -1, &out[0], out.size());

        out.resize(size-1);
        return out;
    }
Last edited on
Dish: your function works fine. the image is showed.
but theres a problem with img(it's a Image private variable from my image class) :(
1
2
img.FromFile(towstring(filename).c_str());
            MessageBox(NULL,to_string(img.GetWidth()).c_str(),"gif width",MB_OK);

why img isn't read the file?
(because the messagebox give me '0'(zero) instead 70)
Last edited on
http://msdn.microsoft.com/en-us/library/windows/desktop/ms535370%28v=vs.85%29.aspx


FromFile is a static member that returns a pointer to an image. Doing img.FromFile is incorrect as that will not modify 'img', but instead will return the image, which you are not capturing.

1
2
3
4
5
6
Image* img = Image::FromFile( filename );

// *img is now your image

// cleanup:
delete img;


Or... with RAII:

1
2
3
4
5
std::uniqe_ptr<Image> img( Image::FromFile(filename) );

// *img is now your image

// no cleanup necessary 
i did:
1
2
3
4
5
6
7
8
class image
{
private:
    ULONG_PTR m_gdiplusToken;
    Gdiplus::GdiplusStartupInput gdiplusStartupInput;
    HDC hdcimage=CreateCompatibleDC(NULL);
    Gdiplus::Graphics graphics;
    Image *img;

in image( const string & filename) constructor:
1
2
img->FromFile(towstring(filename).c_str());
            MessageBox(NULL,to_string(img->GetWidth()).c_str(),"gif width",MB_OK);

the Windows(Operation Sistem) give me an error and close the program:
"the program stops to responding"
That's because you're not doing what I showed.

EDIT:

1
2
3
img->FromFile  //<-  bad

img = Image::FromFile  // <- good 
Last edited on
finally i put it to work:
1
2
img=new Image(towstring(filename).c_str());
            MessageBox(NULL,to_string(img->GetWidth()).c_str(),"gif width",MB_OK);

i'm confused why they wanted a pointer instead a normal variable
i'm confused why they wanted a pointer instead a normal variable


Probably because the class is polymorphic. 'Image' is just the abstract base class... and it's actually creating like a 'Gif' object or something. </guess>
Last edited on
thanks for all... thank you
thanks for the others that tried to help me.. thanks for all to all
using Image, can i get\set the pixels colors or i must use the Bitmap?
Last edited on
Topic archived. No new replies allowed.