Solved

CImage messed up color

Posted on 2014-03-05
12
883 Views
Last Modified: 2014-03-10
I am using the CImage class to open a pair of jpg files ( Image.load() ) and show them on a dialog. My user then has the ability to draw a circle, rectangle, or just a line to "Mark Up" the images then save and/or print the new image. All that functionality is great BUT whenever I try to resize an image ( Image.StretchBlt()  or Image.draw()) the color gets messed up usually it gets very dark.  Just as a test I tried using the CPicture wrapper which encapsulates IPicture and while it DOES NOT mess with the color, some of the other functionallity is missing...  How can I get CImage to scale without changing the colors?

A little more detail: I get the client rectangle, determine how wide the images can be to fit nicely then create new rectangles using the new image width and the aspect ratio of the CImage image. Then I  draw or stretchblt using the new rectangle as the destination ( it lies inside the client dc ) and the CIamge as the source. mode is SRCCOPY. The displayed image is sized correctly and positioned correctly but the color is messed up dark...


Regards
Ron H
0
Comment
Question by:RonHarsh
  • 5
  • 4
12 Comments
 
LVL 31

Expert Comment

by:Zoppo
ID: 39916967
Hi RonHarsh,

I tried to reproduce the problem but unfortunateley without success. I wrote a simple MFC dialog app where in OnPaint I use either CImage::Draw or CImage::StretchBlt to draw a CImage previously loaded with CImage::Load from a JPEG onto the CDialog. This works fine everytime with CImage::Draw, with CImage::StretchBlt it looks ugly when the bitmap is down-sized, but this can be improved by setting the DC's stretch-blit mode using dc.SetStretchBltMode( HALFTONE ).

Since I cannot reproduce it I guess the reason for your problem is one of the following:

1. Your drawing code does something more or different than mine which affects the output as you described:
- Could you post the drawing functionality you have implemented?

2. The JPEG you use is somehow strange and GdiPlus for any reason can't draw it properly when resizing it:
- Does it happen with any JPEG you test it with?

3. GdiPlus is not up to data. I once had a problem with drawn bitmaps where randomly partially filled with blue color on a Win 2003 Server whithout installed Windows Updates/Hotfixes. After updating the system this problem disappeared:
- Is you system up to date?

Best regards,

ZOPPO
0
 

Author Comment

by:RonHarsh
ID: 39917083
Hi Zoppo.  Here is my code from OnPaint(). Note the three versions with comments.  It is also noteworthy that when I used the IPicture class's render function the image is sized and positioned perfectly and the color is excellent however I was not able to figure out how to reload the image from the client rectangle to the IPicture object after my user had modified it.

Thanks
RonHarsh
codesnipit.docx
0
 
LVL 31

Accepted Solution

by:
Zoppo earned 500 total points
ID: 39917134
Well, I'm not sure if it has nay effects, but I think you don't need the 'SaveDC' and 'RestoreDC' calls so IMO you should remove them, at least for performance issue.

Further you should ensure to call ReleaseDC for pictDC after it's used.

Next I found (and this might be the real problem) that the way you call CImage::Draw seems to work different than the way I used it.

You use this function:
BOOL CImage::Draw(
	_In_ HDC hDestDC,
	_In_ int xDest,
	_In_ int yDest,
	_In_ int nDestWidth,
	_In_ int nDestHeight,
	_In_ int xSrc,
	_In_ int ySrc,
	_In_ int nSrcWidth,
	_In_ int nSrcHeight)

Open in new window

I tested with this one:
BOOL Draw(
	_In_ HDC hDestDC,
	_In_ const RECT& rectDest,
	_In_ Gdiplus::InterpolationMode interpolationMode)

Open in new window

Here you can see a screenshot where on the left side I used your call, on the right side
I used mine:Two different ways calling CImage::DrawIt seems the first one works the same as using StretchBlt which, as mentioned above, produces worse result without setting the destination DC's stretch-blit mode calling dc.SetStretchBltMode( HALFTONE ) before calling CImage::Draw or StretchBlt.

But maybe it's better to use the second method, it seems to draw the image better in any case and you can pass a parameter which controls the drawing quality. The code I tested looks like this:
	CClientDC dc( this );
	CRect rc = /*calculated destination rectangle*/
	m_image.Draw( dc.GetSafeHdc(), rc, Gdiplus::InterpolationModeDefault );

Open in new window


Hope that helps,

ZOPPO
0
Back Up Your Microsoft Windows Server®

Back up all your Microsoft Windows Server – on-premises, in remote locations, in private and hybrid clouds. Your entire Windows Server will be backed up in one easy step with patented, block-level disk imaging. We achieve RTOs (recovery time objectives) as low as 15 seconds.

 
LVL 31

Expert Comment

by:Zoppo
ID: 39917146
Just as addition: I looked into the code of the two CImage::Draw variants:

In fact that one you use is just a wrapper for StretchBlt, so it's clear why you get the same result with both versions.

That one I used internally uses Gdiplus::Graphics::DrawImage which implements improved bitmap drawing compared to StretchBlt.

ZOPPO
0
 

Author Comment

by:RonHarsh
ID: 39917175
Now I am confused! None of the overloaded Draw functions in CImage takes three parameters as your example shows! Am I using the wrong library?

 
BOOL Draw(
   HDC hDestDC,
   int xDest,
   int yDest,
   int nDestWidth,
   int nDestHeight,
   int xSrc,
   int ySrc,
   int nSrcWidth,
   int nSrcHeight
) const throw( );

BOOL Draw(
   HDC hDestDC,
   const RECT& rectDest,
   const RECT& rectSrc
) const throw( );

BOOL Draw(
   HDC hDestDC,
   int xDest,
   int yDest
) const throw( );

BOOL Draw(
   HDC hDestDC,
   const POINT& pointDest
) const throw( );

BOOL Draw(
   HDC hDestDC,
   int xDest,
   int yDest,
   int nDestWidth,
   int nDestHeight
) const throw( );

BOOL Draw(
   HDC hDestDC,
   const RECT& rectDest
) const throw( );
 



RonHarsh
0
 
LVL 31

Expert Comment

by:Zoppo
ID: 39917220
Hm - which version of Visual Studio do you use? At least with VisualStudio 2010 which I use it's available. Anyway, it is not mentioned in MSDN even for VS 2010, I don't know why: http://msdn.microsoft.com/en-us/library/cz787xf9%28v=vs.100%29.aspx

You could simply check if it's available by searching the string InterpolationMode in the file atlimage.h in Visual Studio's include directories.

If it isn't there (so if you're using an older Visual Studio) you IMO have two options:

1. Simply use StretchBlt as above with a previous call to SetStretchBltMode
2. Implement your own functionality to use GdiPlus for drawing - this will produce nicer output.

ZOPPO
0
 

Author Comment

by:RonHarsh
ID: 39917223
OK, I used the  dc.SetStretchBltMode( HALFTONE )  and it seems to have fixed the issue! I am still interested in the Draw function that you used but I can work with what I have.


THANKS for the help!
RonHarsh
0
 
LVL 31

Expert Comment

by:Zoppo
ID: 39917238
Well, just try to check if the function is available as told above. If not implementing such bitmap drawing using GdiPlus is even simple, so if you want you could do it yourself to be able to use GdiPlus's interpolation modes which are nicer (but sometimes slower).

It'S even possible to load images and to draw onto images with GdiPlus, so maybe you should think about using it as a replacement for CImage at all if you can spend the effort. GdiPlus is much better than GDI which at least in this case is used by CImage.

ZOPPO
0
 

Author Closing Comment

by:RonHarsh
ID: 39917352
Thanks for the help!
0

Featured Post

Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
PC freezes and shutdowns becoming more frequent 17 135
C++ help/ Toy problem 19 29
Gaming Software 1 19
Need to make video of desktop 5 10
Today companies are subjected to more-and-more data, and it won't stop any time soon.  But there are obvious opportunities for reducing data, particularly data duplicated among companies.
In this article, you will read about the trends across the human resources departments for the upcoming year. Some of them include improving employee experience, adopting new technologies, using HR software to its full extent, and integrating artifi…
The viewer will learn how to successfully download and install the SARDU utility on Windows 7, without downloading adware.
In an interesting question (https://www.experts-exchange.com/questions/29008360/) here at Experts Exchange, a member asked how to split a single image into multiple images. The primary usage for this is to place many photographs on a flatbed scanner…

840 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