shifty_mc
asked on
Need to load an image from a file (not resource) and display it to screen
Hi,
I'm extremely frustrated! Can someone please tell me first - the best way to do this?... I've looked at using GDI+ with c++, and just about got it working, but not quite. This is probably my preferred way, if only because I've just done a project in C# and so am used to it, but if anyone knows other more traditional methods that's great as well.
I'm basically trying to write a very simple screensaver that displays images.
So I've got a "void CSaverWnd::OnTimer(UINT nIDEvent)" method that needs to go through a vector of strings (paths to image files), displaying the image related to the string.
Like I said, I kinda got something working - in gdi+ (took me forever to set up gdi+ but nevermind), but all sorts of things were going wrong that I couldn't understand.
If someone could give me some solid code they know works, I'll love you forever ;)
Cheers.
I'm extremely frustrated! Can someone please tell me first - the best way to do this?... I've looked at using GDI+ with c++, and just about got it working, but not quite. This is probably my preferred way, if only because I've just done a project in C# and so am used to it, but if anyone knows other more traditional methods that's great as well.
I'm basically trying to write a very simple screensaver that displays images.
So I've got a "void CSaverWnd::OnTimer(UINT nIDEvent)" method that needs to go through a vector of strings (paths to image files), displaying the image related to the string.
Like I said, I kinda got something working - in gdi+ (took me forever to set up gdi+ but nevermind), but all sorts of things were going wrong that I couldn't understand.
If someone could give me some solid code they know works, I'll love you forever ;)
Cheers.
Check out the CImage class.
If you have access to MSDN, check out the SimpleImage example, it does exactly what you want to do.
If you have access to MSDN, check out the SimpleImage example, it does exactly what you want to do.
Here's the on-line link to the SimpleImage example:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vcsample/html/vcsamSimpleImageSample.asp
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vcsample/html/vcsamSimpleImageSample.asp
Are those bitmaps? In that case ::LoadImage () can do the job.
HANDLE LoadImage(
HINSTANCE hinst, // handle of the instance containing the image
LPCTSTR lpszName, // name or identifier of image
UINT uType, // type of image
int cxDesired, // desired width
int cyDesired, // desired height
UINT fuLoad // load flags
);
hinst = NULL
lpszName = filepath
uType = IMAGE_BITMAP
cxDesired = cyDesired = LR_DEFAULTSIZE
fuLoad = LR_LOADFROMFILE
HANDLE LoadImage(
HINSTANCE hinst, // handle of the instance containing the image
LPCTSTR lpszName, // name or identifier of image
UINT uType, // type of image
int cxDesired, // desired width
int cyDesired, // desired height
UINT fuLoad // load flags
);
hinst = NULL
lpszName = filepath
uType = IMAGE_BITMAP
cxDesired = cyDesired = LR_DEFAULTSIZE
fuLoad = LR_LOADFROMFILE
Check out
http://www.codeguru.com/Cpp/G-M/bitmap/article.php/c1681/ ("Drawing a bitmap from a BMP file")
http://www.codeguru.com/Cpp/G-M/bitmap/article.php/c1681/ ("Drawing a bitmap from a BMP file")
Yes, you can also use CImage class of MFC.. but be careful, you will just be able to load .BMP files (and maybe .JPG, not sure about it).. Anyway, GDI+ will have some other advantages, especially when you are coding a screensaver.. Such as transparency (alpha channel).. You will be able to code some transitions while switching images.. And only disadvantage of GDI+ is distributing gdiplus.dll with your application.. not a big deal thou..
CImage works with jpg, gif, png, and bmp file formats.
Good for CImage then.. I wasn't sure of that.. So it was not the point.. CImage is too primitive compared to GDI+ classes.. That's why they developed GDI+.. no antialiasing, no transformations, no alpha channel, no color matrixes etc.. I don't think I need to count more..
ASKER
well I'll give the gdi+ way a go first - but caner_elci, can you be a bit more specific?
I tried your code...
CPaintDC dc(this);
using namespace Gdiplus;
Graphics* g = Graphics::FromHDC( dc );
USES_CONVERSION;
Image* img = Image::FromFile( A2W(picture_names[current_ picture].c _str()), true );
g->DrawImage( img, 0, 0 );
(these modifications are the only way I could get it to compile - and to be honest it's all a bit trial and error for me)
but am just getting a black screen.
Do I need to do anything to specifically tell it to paint?
Thanks
I tried your code...
CPaintDC dc(this);
using namespace Gdiplus;
Graphics* g = Graphics::FromHDC( dc );
USES_CONVERSION;
Image* img = Image::FromFile( A2W(picture_names[current_
g->DrawImage( img, 0, 0 );
(these modifications are the only way I could get it to compile - and to be honest it's all a bit trial and error for me)
but am just getting a black screen.
Do I need to do anything to specifically tell it to paint?
Thanks
ASKER
oh, and wayside - I tried to download the sample and it wouldn't let me, any ideas? Don't suppose there's any chance u could email it to me if it's small? Don't worry if not, cheers
ASKER
scratch that- just worked on fourth attempt :)
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
OK, I got it using gdi+... just about - for some reason the code would only work in the OnPaint method, no idea why unless anyone can enlighten me.
Thanks for your time anyway
Thanks for your time anyway
You can paint your window anytime, try using this->GetDC() as dc parameter in Graphics' constructor... In fact, use something like this:
CDC *pDC = GetDC();
Graphics g( pDC );
... do your painting here ...
ReleaseDC( pDC );
CDC *pDC = GetDC();
Graphics g( pDC );
... do your painting here ...
ReleaseDC( pDC );
ASKER
umm - just get the one error...
cannot convert parameter 1 from 'class CDC *' to 'struct HDC__ *'
in the line Graphics g( pDC );
cannot convert parameter 1 from 'class CDC *' to 'struct HDC__ *'
in the line Graphics g( pDC );
Okay, try this:
Graphics g( pDC->GetSafeHdc() );
or
Graphics g( (HDC)pDC );
Graphics g( pDC->GetSafeHdc() );
or
Graphics g( (HDC)pDC );
ASKER
yeah, both of those compiled, but get the same black screen still. I assume it's something to do with it being a screensaver and perhaps somewhere a black background is being painted over anything I try to draw, which is why it only works in the OnPaint method - drawing after the black maybe?
Unfortunately I've jumped into the deep end a bit and don't have time to stop and actually work out why everything does what it does (terrible I know) - a lot of it is kind of merged code from elsewhere so far.
I appreciate the help though.
Unfortunately I've jumped into the deep end a bit and don't have time to stop and actually work out why everything does what it does (terrible I know) - a lot of it is kind of merged code from elsewhere so far.
I appreciate the help though.
Do you remove the code in OnPaint when you add the code in any other event such as OnTimer()?
If so, please consider these:
You better just load the image in OnTimer() and then call this->Invalidate() to force an OnPaint()...
In OnPaint() you should not load any image and just draw the currently loaded image
If so, please consider these:
You better just load the image in OnTimer() and then call this->Invalidate() to force an OnPaint()...
In OnPaint() you should not load any image and just draw the currently loaded image
ASKER
yeah, that's what I'm working with at the mo, thanks for all your help - it really does save a lot of time coming to sites like this.
You're welcome.. I suggest you to use some transitions while switching between images :) Try color matrixes and Graphics methods...
ASKER
yep, that's all to come. I expect I'll be back on with many more questions in the near future :)
Anytime you want :)
Have fun!
Caner
Have fun!
Caner
For example :
Graphics g = Graphics::FromHDC( GetDC() );
Image img = Image::FromImage( "C:\\file.jpg", true );
g.DrawImage( &img, 0, 0 );
This will load the image and draw it at (0,0) coordinates of your current window's DC..