Solved

Need to load an image from a file (not resource) and display it to screen

Posted on 2004-04-15
22
1,125 Views
Last Modified: 2012-05-05
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
Comment
Question by:shifty_mc
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 9
  • 8
  • 3
  • +2
22 Comments
 
LVL 4

Expert Comment

by:caner_elci
ID: 10834451
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
 
LVL 14

Expert Comment

by:wayside
ID: 10834452
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
 
LVL 14

Expert Comment

by:wayside
ID: 10834463
0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 13

Expert Comment

by:SteH
ID: 10834491
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
 
LVL 86

Expert Comment

by:jkr
ID: 10834526
Check out

http://www.codeguru.com/Cpp/G-M/bitmap/article.php/c1681/ ("Drawing a bitmap from a BMP file")
0
 
LVL 4

Expert Comment

by:caner_elci
ID: 10834537
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
 
LVL 14

Expert Comment

by:wayside
ID: 10834670
CImage works with jpg, gif, png, and bmp file formats.
0
 
LVL 4

Expert Comment

by:caner_elci
ID: 10834747
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
 

Author Comment

by:shifty_mc
ID: 10834830
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
 

Author Comment

by:shifty_mc
ID: 10834886
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
 

Author Comment

by:shifty_mc
ID: 10834908
scratch that- just worked on fourth attempt :)
0
 
LVL 4

Accepted Solution

by:
caner_elci earned 200 total points
ID: 10834956
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
 

Author Comment

by:shifty_mc
ID: 10837140
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
 
LVL 4

Expert Comment

by:caner_elci
ID: 10837637
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
 

Author Comment

by:shifty_mc
ID: 10837757
umm - just get the one error...

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

in the line Graphics g( pDC );
0
 
LVL 4

Expert Comment

by:caner_elci
ID: 10837776
Okay, try this:

Graphics g( pDC->GetSafeHdc() );

or

Graphics g( (HDC)pDC );
0
 

Author Comment

by:shifty_mc
ID: 10837874
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
 
LVL 4

Expert Comment

by:caner_elci
ID: 10837896
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
 

Author Comment

by:shifty_mc
ID: 10837916
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
 
LVL 4

Expert Comment

by:caner_elci
ID: 10837930
You're welcome.. I suggest you to use some transitions while switching between images :) Try color matrixes and Graphics methods...
0
 

Author Comment

by:shifty_mc
ID: 10837943
yep, that's all to come. I expect I'll be back on with many more questions in the near future :)
0
 
LVL 4

Expert Comment

by:caner_elci
ID: 10837951
Anytime you want :)

Have fun!

Caner
0

Featured Post

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Errors will happen. It is a fact of life for the programmer. How and when errors are detected have a great impact on quality and cost of a product. It is better to detect errors at compile time, when possible and practical. Errors that make their wa…
Container Orchestration platforms empower organizations to scale their apps at an exceptional rate. This is the reason numerous innovation-driven companies are moving apps to an appropriated datacenter wide platform that empowers them to scale at a …
The goal of the tutorial is to teach the user how to use functions in C++. The video will cover how to define functions, how to call functions and how to create functions prototypes. Microsoft Visual C++ 2010 Express will be used as a text editor an…
The viewer will learn additional member functions of the vector class. Specifically, the capacity and swap member functions will be introduced.

734 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question