Solved

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

Posted on 2004-04-15
22
1,118 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
  • 9
  • 8
  • 3
  • +2
22 Comments
 
LVL 4

Expert Comment

by:caner_elci
Comment Utility
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
Comment Utility
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
Comment Utility
0
 
LVL 13

Expert Comment

by:SteH
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
CImage works with jpg, gif, png, and bmp file formats.
0
 
LVL 4

Expert Comment

by:caner_elci
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
scratch that- just worked on fourth attempt :)
0
What Security Threats Are You Missing?

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

 
LVL 4

Accepted Solution

by:
caner_elci earned 200 total points
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
Okay, try this:

Graphics g( pDC->GetSafeHdc() );

or

Graphics g( (HDC)pDC );
0
 

Author Comment

by:shifty_mc
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
Anytime you want :)

Have fun!

Caner
0

Featured Post

Enabling OSINT in Activity Based Intelligence

Activity based intelligence (ABI) requires access to all available sources of data. Recorded Future allows analysts to observe structured data on the open, deep, and dark web.

Join & Write a Comment

Unlike C#, C++ doesn't have native support for sealing classes (so they cannot be sub-classed). At the cost of a virtual base class pointer it is possible to implement a pseudo sealing mechanism The trick is to virtually inherit from a base class…
In days of old, returning something by value from a function in C++ was necessarily avoided because it would, invariably, involve one or even two copies of the object being created and potentially costly calls to a copy-constructor and destructor. 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 be introduced to the member functions push_back and pop_back of the vector class. The video will teach the difference between the two as well as how to use each one along with its functionality.

743 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

Need Help in Real-Time?

Connect with top rated Experts

18 Experts available now in Live!

Get 1:1 Help Now