Link to home
Start Free TrialLog in
Avatar of RonHarsh
RonHarsh

asked on

CImage messed up color

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
Avatar of Zoppo
Zoppo
Flag of Germany image

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
Avatar of RonHarsh
RonHarsh

ASKER

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
ASKER CERTIFIED SOLUTION
Avatar of Zoppo
Zoppo
Flag of Germany image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
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
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
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
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
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
Thanks for the help!