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
Photos / Graphics SoftwareSoftwareImages and PhotosC++

Avatar of undefined
Last Comment
RonHarsh

8/22/2022 - Mon
Zoppo

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
ASKER
RonHarsh

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
Zoppo

Log in or sign up to see answer
Become an EE member today7-DAY FREE TRIAL
Members can start a 7-Day Free trial then enjoy unlimited access to the platform
Sign up - Free for 7 days
or
Learn why we charge membership fees
We get it - no one likes a content blocker. Take one extra minute and find out why we block content.
See how we're fighting big data
Not exactly the question you had in mind?
Sign up for an EE membership and get your own personalized solution. With an EE membership, you can ask unlimited troubleshooting, research, or opinion questions.
ask a question
Zoppo

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
All of life is about relationships, and EE has made a viirtual community a real community. It lifts everyone's boat
William Peck
ASKER
RonHarsh

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
Zoppo

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
ASKER
RonHarsh

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
Get an unlimited membership to EE for less than $4 a week.
Unlimited question asking, solutions, articles and more.
Zoppo

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
ASKER
RonHarsh

Thanks for the help!