• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 1144
  • Last Modified:

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.
0
shifty_mc
Asked:
shifty_mc
  • 9
  • 8
  • 3
  • +2
1 Solution
 
caner_elciCommented:
In GDI+, you can use Image::FromFile() static function and Graphics::DrawImage() method..

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..
0
 
waysideCommented:
Check out the CImage class.

If you have access to MSDN, check out the SimpleImage example, it does exactly what you want to do.
0
 
waysideCommented:
0
Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

 
SteHCommented:
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
0
 
jkrCommented:
Check out

http://www.codeguru.com/Cpp/G-M/bitmap/article.php/c1681/ ("Drawing a bitmap from a BMP file")
0
 
caner_elciCommented:
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..
0
 
waysideCommented:
CImage works with jpg, gif, png, and bmp file formats.
0
 
caner_elciCommented:
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..
0
 
shifty_mcAuthor Commented:
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
0
 
shifty_mcAuthor Commented:
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
0
 
shifty_mcAuthor Commented:
scratch that- just worked on fourth attempt :)
0
 
caner_elciCommented:
shifty_mc,
I don't have GDI+ installed on this computer I'm using right now.. but, here are the samples: at http://www.codeguru.com/Cpp/G-M/gdi/gdi/article.php/c3667/ and http://www.codeproject.com/vcpp/gdiplus/GdiPThumbnailsViewer.asp

Also, try this:

Graphics g(dc);
Bitmap bmp = Bitmap::FromFile( A2W(picture_names[current_picture].c_str()),true );
g.DrawImage( bmp, 0, 0 );

And you can check http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdicpp/GDIPlus/GDIPlusReference/Classes/BitmapClass/BitmapMethods/FromFile.asp for Bitmap::FromFile() initializer..
0
 
shifty_mcAuthor Commented:
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
0
 
caner_elciCommented:
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 );
0
 
shifty_mcAuthor Commented:
umm - just get the one error...

cannot convert parameter 1 from 'class CDC *' to 'struct HDC__ *'

in the line Graphics g( pDC );
0
 
caner_elciCommented:
Okay, try this:

Graphics g( pDC->GetSafeHdc() );

or

Graphics g( (HDC)pDC );
0
 
shifty_mcAuthor Commented:
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.
0
 
caner_elciCommented:
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
0
 
shifty_mcAuthor Commented:
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.
0
 
caner_elciCommented:
You're welcome.. I suggest you to use some transitions while switching between images :) Try color matrixes and Graphics methods...
0
 
shifty_mcAuthor Commented:
yep, that's all to come. I expect I'll be back on with many more questions in the near future :)
0
 
caner_elciCommented:
Anytime you want :)

Have fun!

Caner
0

Featured Post

Upgrade your Question Security!

Add Premium security features to your question to ensure its privacy or anonymity. Learn more about your ability to control Question Security today.

  • 9
  • 8
  • 3
  • +2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now