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

FreeImage help

5 views
Skip to first unread message

Aegis Delacour

unread,
Nov 4, 2009, 6:30:24 AM11/4/09
to
hi guys i need some urgent help here..could someone help me fix this
code..it compiles fine but just doesnt show up as i want it to..i need
to display a jpg on screen

void CLowerEicasDlg::screeny()
{
HDC hdc = CreateDC("DISPLAY", NULL, NULL, NULL);
HDC hdcC = CreateCompatibleDC(hdc);

int dest_x, dest_y, width, height;
dest_x=0;
dest_y=0;
width=800;
height=900;

FIBITMAP *fibmp_img = FreeImage_Load(FIF_JPEG, "screen1.JPG",
JPEG_DEFAULT);
StretchDIBits(hdcC, dest_x, dest_y, width, height, 0, 0, width,
height, FreeImage_GetBits(fibmp_img), FreeImage_GetInfo(fibmp_img),
DIB_RGB_COLORS, SRCCOPY);
FreeImage_Unload(fibmp_img);

DeleteDC(hdc);
DeleteDC(hdcC);

}

Joseph M. Newcomer

unread,
Nov 4, 2009, 8:48:39 AM11/4/09
to
THere are some deeper problems here.

But a superficial question: "just doesn't show up as I want it to" is not a really good
description of what you are seeing. Are you seeing nothing? Something that doesn't look
right? What?

The deeper problem is that you are drawing something on the main display, and at any
instant, any other app is free to redraw its pixels at any place on the screen, erasing
whatever your image is. So whatever you do, it will gradually degrade as other apps do
redrawing.

If your goal is to create a window that covers the screen for some duration while your
program does something else, that's a different question, but in that case you would not
be doing a CreateDC("Display") [note: the correct form is CreateDC(_T("Display")) so you
are Unicode-aware, and the file is _T("screen1.jpg"), and so on]; you would have a window
that is the size of the screen [be aware that "the screen" might mean "the user's primary
monitor" or "the user's current monitor"; you have to assume a multi-monitor environment],
and in that case you would using the CPaintDC of the OnPaint handler to draw. But the
code shown below is not really a good idea because it just splats some pixels onto some
piece of the screen, which then will be whimsically redrawn by windows underneath them.

I presume the magical values for destination and width shown here are just for
illustration, since on a real machine these numbers are meaningless noise. For example,
my primary monitor is 1920x1600 and my secondary monitor is 1280x1024, so numbers like 0,0
for the origin means "on the primary monitor" and the other two numbers do not correspond
to any monitor size I have ever known.

So what are you trying to accomplish with this code? There is probably a better way to do
it, but we need to know both your intended goal and what is wrong.
joe

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

Giovanni Dicanio

unread,
Nov 4, 2009, 12:52:39 PM11/4/09
to

"Joseph M. Newcomer" <newc...@flounder.com> ha scritto nel messaggio
news:6r03f5pfqupojtakn...@4ax.com...

>[note: the correct form is CreateDC(_T("Display")) so you
> are Unicode-aware, and the file is _T("screen1.jpg"), and so on];

OK regarding CreateDC, but I think that is not correct regard the file name.
In fact, if I understood right, the OP is using the open source "freeimage"
library, which has two different functions for loading the files.
One is FreeImage_Load, which takes a const char* as input, and another one
is FreeImage_LoadU, which takes a const wchar_t *.
So, the usual Win32 _T() pattern cannot be applied in this particular case.

For the OP: there is an article on CodeProject showing the use of freeimage
in MFC context:

http://www.codeproject.com/KB/graphics/graphicsuite.aspx?msg=628753

Giovanni

Joseph M. Newcomer

unread,
Nov 4, 2009, 1:22:26 PM11/4/09
to
OK, I was not familiar with the library interface. I assumed this was some Microsoft
class I had previously not encountered.
joe

Aegis Delacour

unread,
Nov 5, 2009, 10:13:25 AM11/5/09
to
Ok i think i was not very clear.
Here is what i need.
The entire program is very long, when a physical button is pressed..it
will go to the function screeny();
when it does that, it will load and display an image(Jpg) on full
screen...there is no need to stretch it out or anything as the image
WILL be
in the exact resolution of the monitor.

currently with that code, it just doesnt work..the program that was
running before i pessed the button is still running.

im really not sure why im finding it this hard to just display a
jpg..surely theres an easy way as this seems quite basic?

Joseph M. Newcomer

unread,
Nov 5, 2009, 11:28:17 AM11/5/09
to
The problem now is clear: you are experiencing the problem I told you that you would
experience.

First, the program that was running is *always* running; what you probably meant to say
was "the program that was running still displays". And that is correct behavior, given
the bad code you have. You simply cannot get the display DC, write pixels on it, and
expect to get just those pixels displayed; in fact, only under the most bizarre conditions
would that ever give a pretense of working.

What you have to do is create a window, make that window be the currently active window,
and in the OnPaint handler of that window draw your JPEG.

The system is working as documented and expected; you just tried to do something that is
guaranteed to work in the way you just described, so the fact that it works that way
should be no surprise.
joe

Giovanni Dicanio

unread,
Nov 5, 2009, 12:00:50 PM11/5/09
to

"Joseph M. Newcomer" <newc...@flounder.com> ha scritto nel messaggio
news:53v5f5dbei84app75...@4ax.com...

> What you have to do is create a window, make that window be the currently
> active window,
> and in the OnPaint handler of that window draw your JPEG.

To add to Joe's insights, when I had to display something in fullscreen, I
used DirectDraw component from DirectX, and in particular two methods of
this interface were useful for that purpose:

- IDirectDraw::SetCooperativeLevel with DDSCL_FULLSCREEN flag, to set
fullscreen mode;
- IDirectDraw::SetDisplayMode, to set the fullscreen resolution.

Giovanni

Joseph M. Newcomer

unread,
Nov 5, 2009, 12:55:42 PM11/5/09
to
And what about multiple monitors...

I have been guilty of multiple-monitor avoidance in the past, and these days, I have to be
really conscious of it. Multiple-monitor cards are now dirt cheap and readily available.
joe

Giovanni Dicanio

unread,
Nov 5, 2009, 1:10:12 PM11/5/09
to

"Joseph M. Newcomer" <newc...@flounder.com> ha scritto nel messaggio
news:9b46f5li7r6akrss6...@4ax.com...

> And what about multiple monitors...

I'm not sure, but IIRC DirectDraw has some function like
DirectDrawEnumerate(Ex) that allows you to enumerate available graphics
devices and monitors.

Giovanni

Joseph M. Newcomer

unread,
Nov 5, 2009, 4:18:02 PM11/5/09
to
Yes, but you have to use it. I've found that multi-monitor awareness is no longer
optional.
joe

Giovanni Dicanio

unread,
Nov 5, 2009, 5:44:04 PM11/5/09
to

"Joseph M. Newcomer" <newc...@flounder.com> ha scritto nel messaggio
news:g7g6f5l5sqpknm5ha...@4ax.com...

> I've found that multi-monitor awareness is no longer
> optional.

You are right.

Be multi-monitor aware could complicate code, but it is a good benefit for
the end user.

Giovanni

Aegis Delacour

unread,
Nov 6, 2009, 8:55:42 PM11/6/09
to
Thanks for the answers.
im guessing this is what you mean...

HWND hdc = CreateWindow();
HDC GetDC( HWND hdc );

but im not too sure about the parameters, could you help me fill it in
plz?


HWND CreateWindow(
LPCTSTR lpClassName,
LPCTSTR lpWindowName,
DWORD dwStyle,
int x,
int y,
int nWidth,
int nHeight,
HWND hWndParent,
HMENU hMenu,
HINSTANCE hInstance,
LPVOID lpParam
);

Joseph M. Newcomer

unread,
Nov 6, 2009, 11:05:19 PM11/6/09
to
See below...

On Fri, 6 Nov 2009 17:55:42 -0800 (PST), Aegis Delacour <eloq...@gmail.com> wrote:

>Thanks for the answers.
>im guessing this is what you mean...
>
>HWND hdc = CreateWindow();

****
In MFC, you would create a subclass of CWnd, e.g.,

class CMyFullScreen : public CWnd {
};

you would do this using the "Add New Class" function in VS. Therefore, you would NOT be
calling CreateWindow. Also, you would never call GetDC; that piece of code is completely
irrelevant
****


>HDC GetDC( HWND hdc );

****
Having created the class, you would now create a window. You need a variable which you
declare in a place (such as some view class you are using, or dialog class, or something,
but NOT a local variable); for example put it in your CLowerEicasDlg class

CMyFullScreen screen;

then in response to a button click you would do


void CLowerEicasDlg::OnSomeCondition()
{
LPCTSTR classname = AfxRegisterWndClass(0);
screen.CreateEx(0,
NULL,
WS_OVERLAPPED | WS_VISIBLE,
x0, y0,
width, height,
NULL,
NULL);
}

Note that error detection and recovery is left as an Exercise For The Reader.

Also, I did not specify x0, y0 and width, height since I leave those up to you to figure
out. They may be local variables you compute on the fly in OnSomeCondition method, or
class variables of CLowerEicasDlg that you have computed earlier.

Then to your CMyFullScreen class, you will add an OnPaint handler using the ClassWizard:

void CMyFullScreen::OnPaint()
{
CPaintDC dc(this);
... do your drawing here
}

Note that you do not ever, under any circumstances, do a GetDC. In those very rare and
exotic situations where you might need to draw outside the OnPaint handler, you would
declare a CClientDC variable, but you do not have that situation here.
****


>
>but im not too sure about the parameters, could you help me fill it in
>plz?
>
>
>HWND CreateWindow(
> LPCTSTR lpClassName,
> LPCTSTR lpWindowName,
> DWORD dwStyle,
> int x,
> int y,
> int nWidth,
> int nHeight,
> HWND hWndParent,
> HMENU hMenu,
> HINSTANCE hInstance,
> LPVOID lpParam
>);

****
This would be the raw API. But you are programming in MFC and this is irrelevant.

Note that your calls on CreateDC are also irrelevant. If you wanted to create a memory DC
to reduce flicker, you would declare
CDC memDC;
memDC.CreateCompatibleDC(&dc);
and work with the MFC methods for doing the drawing.
joe
****

Message has been deleted

Aegis Delacour

unread,
Nov 9, 2009, 6:12:42 AM11/9/09
to
wow thanks for the great replies but to be honest im a little
confused, i apologize for so many 'newbie' questions cause well im
pretty new to this coding.

so from what i get this is what i see...

CMyFullScreen screen; //This is a variable

class CMyFullScreen : public CWnd {
//Should anything go in here?
};


void screeny() //i don't need the 'condition here as i will be using a
function call to link here to display the image


{
LPCTSTR classname = AfxRegisterWndClass(0);
screen.CreateEx(0,
NULL,
WS_OVERLAPPED | WS_VISIBLE,

0, 0,
1280, 768,
NULL,
NULL);
}

void CMyFullScreen::OnPaint()
{
CPaintDC dc(this);
... do your drawing here

int dest_x, dest_y, width, height;
dest_x=0;
dest_y=0;
width=800;
height=900;

FIBITMAP *fibmp_img = FreeImage_Load(FIF_JPEG, "screen1.JPG",
JPEG_DEFAULT);
StretchDIBits(hdcC, dest_x, dest_y, width, height, 0, 0, width,
height, FreeImage_GetBits(fibmp_img), FreeImage_GetInfo
(fibmp_img),
DIB_RGB_COLORS, SRCCOPY);
FreeImage_Unload(fibmp_img);

dc.BitBlt(0, 0, bmpWidth, bmpHeight, &MemDC, 0, 0,SRCCOPY );

}


CMyFullScreen::LoadFromFile(const CString & filename) //Whats this
function for as i already drew the image in OnPaint dialog right?
{
// FreeImage class
fipWinImage img;

#ifdef _UNICODE
img.loadU("Screeny1.jpg");
#else
img.load("Screeny1.jpg");
#endif
....

// CRect with the image size
CRect r(CPoint(0,0), CSize(img.getWidth(), img.getHeight())) ;

// assuming MemDC is a protected CDC member variable of CMyFullScreen
// also a CBitmap member ( created CreateCompatibleBitmap) is selected
in
// that MemDC
img.draw(MemDC.GetSafeHdc(), r);
...

}

Joseph M. Newcomer

unread,
Nov 9, 2009, 9:14:59 AM11/9/09
to
See below...

On Mon, 9 Nov 2009 03:12:42 -0800 (PST), Aegis Delacour <eloq...@gmail.com> wrote:

>wow thanks for the great replies but to be honest im a little
>confused, i apologize for so many 'newbie' questions cause well im
>pretty new to this coding.
>
>so from what i get this is what i see...
>
>CMyFullScreen screen; //This is a variable
>
>class CMyFullScreen : public CWnd {
>//Should anything go in here?
>};

***
Since you will derive this by using Visual Studio's "Add Class" mechanism, you will start
out with a LOT of stuff there, but it doesn't matter, because it is automatically
generated for you. You will also add an OnPaint handler to the class once you have
created it.
****


>
>
>void screeny() //i don't need the 'condition here as i will be using a

****
Presumably this is a member function of some class.
****


>function call to link here to display the image
> {
> LPCTSTR classname = AfxRegisterWndClass(0);
> screen.CreateEx(0,
> NULL,
> WS_OVERLAPPED | WS_VISIBLE,
> 0, 0,
> 1280, 768,
> NULL,
> NULL);
> }
>
>void CMyFullScreen::OnPaint()
> {
> CPaintDC dc(this);
> ... do your drawing here
>
> int dest_x, dest_y, width, height;

****
It is poor style to use commas in declaration lists. One variable, one line:
CPoint dest;
CSize size;
****
> dest_x=0;
> dest_y=0;
> width=800;
> height=900;
****
dest.x = 0;
dest.y = 0;
size.cx = 800;
size.cy = 900;

Why use int when there are nicer data types for expressing these concepts?
****


>
> FIBITMAP *fibmp_img = FreeImage_Load(FIF_JPEG, "screen1.JPG",
> JPEG_DEFAULT);

> StretchDIBits(hdcC, dest_x, dest_y, width, height, 0, 0, width,
> height, FreeImage_GetBits(fibmp_img), FreeImage_GetInfo
>(fibmp_img),

****
Where id hdcC come from?
****


> DIB_RGB_COLORS, SRCCOPY);
> FreeImage_Unload(fibmp_img);
>
> dc.BitBlt(0, 0, bmpWidth, bmpHeight, &MemDC, 0, 0,SRCCOPY );
>
> }
>
>
>
>
>CMyFullScreen::LoadFromFile(const CString & filename) //Whats this
>function for as i already drew the image in OnPaint dialog right?

****
I have no idea. The concept seems to be left over from your old code. The only thing you
need is the #ifdef code.
****


>{
>// FreeImage class
>fipWinImage img;
>
>#ifdef _UNICODE
>img.loadU("Screeny1.jpg");

****
This should be
img.loadU(L"Screen1.jpg");
****


>#else
>img.load("Screeny1.jpg");
>#endif
>....
>
>// CRect with the image size
>CRect r(CPoint(0,0), CSize(img.getWidth(), img.getHeight())) ;
>
>// assuming MemDC is a protected CDC member variable of CMyFullScreen
>// also a CBitmap member ( created CreateCompatibleBitmap) is selected
>in
>// that MemDC
>img.draw(MemDC.GetSafeHdc(), r);
>...
>
>}

0 new messages