Click here to Skip to main content
Click here to Skip to main content

Using GDI+ in a Single Document MFC Project to Rotate, Zoom, and Constraint an Image

By , 27 Aug 2006
 

Introduction

The program loads images (BMP, GIF, JPEG/JPG/EXIF, PNG, TIF, ICON, WMF, EMF), applies some constraints related to window size (best fit, constraint width, constraint height, image original), rotates the image, makes zoom in & out effect and finally navigates through multi-page TIF images. It is useful if you need a image viewer class and image functionality in your C++ application. The problem is that I use GDI+. Developing with GDI+, there is a point most of us must go through.

First, go beyond pointers to GDI+ Image class that block access to every image file I load and view; now only the current loaded is blocked. No more headache with blocked temp image files, we got the key. How to make a big JPEG/JPG/EXIF move fast? I made it, but unfortunately it won't work for a rotation with 180 degrees. Just stretch the image in a hidden window: rotate 90 degrees Graphics::RotateTransform(...) , and display image, don't ask why! It will work to your surprise. I found many programmers that rotated an image with Image class method RotateFlip (and I did it too), instead of Graphics class method RotateTransform. This implies that an image will have negative values along X, Y axis and more ... but will have intact integrity of its internal structure. What I didn't solve is transparent background images management, and what to do to cheat image at a 180 angle rotation.

Background

C/C++ is great, but to know it from the very beginning.

Using the Code

The class that do everything that I discussed earlier is mvImage. So you will need this #include "mvImage.h" in your application. The mvImage class constructor needs a window handle HWND. The rest does the class through this handle. You can use this class in a single / multi document interface or dialog based MFC project. I will try a poor demonstration copying parts of the code here to show you: easier than this doesn't exist !

  1. Your CView derived class constructor will be like this:
    CDraw1View::CDraw1View() { m_Image = 0x000000 ; }
  • 2.1 Initialization of mvImage pointer comes in OnDraw once per application, the rest is redrawing the window surface.
    void CDraw1View::OnDraw(CDC* pDC)
    { 
        CDraw1Doc* pDoc = GetDocument(); 
        ASSERT_VALID(pDoc); 
    
        // TODO: add draw code for native data here 
        //init image pointer 
        if((m_Image == 0x000000) && (this->m_hWnd != 0x000000)) 
        { 
            m_Image = new mvImage(this->m_hWnd); 
        }//if 
        else
        {
            //redraw image window 
            if(m_Image->mvIsValidImage()) m_Image->mvOnPaint(); 
        } 
    }
  • 2.2 If your application is dialog based, use OnInitDialog to put this code in:
    .....
    
    if((m_Image == 0x000000) && (this->m_hWnd != 0x000000))
    { 
        m_Image = new mvImage(this->m_hWnd);
    }//if
    
    .....

    and OnPaint method with this code:

    if(m_Image->mvIsValidImage()) m_Image->mvOnPaint() ;
  1. To load and display an image with 'best fit' propriety, use this:
    .....
    
    CFileDialog Fdlg(TRUE) ;
    if(Fdlg.DoModal() == IDOK)
    {
        CString path = Fdlg.GetPathName() ; 
        m_Image->mvLoadImage(path) ;
    }//if
    else return ;
    
    //display image 'best fit' in wind.
    if(m_Image->mvIsValidImage()) m_Image->mvConstraintAll();
    
    .....
  2. Constraint all 'best fit' image in window, proceed like here:
    if(m_Image->mvIsValidImage())
    {
        m_Image->mvConstraintAll();
    }
  3. Constraint height ? like here:
    if(m_Image->mvIsValidImage())
        m_Image->mvConstraintHeight() ;
  4. Rotate left:
    if(m_Image->mvIsValidImage())
        m_Image->mvRotateLeft() ;
  5. Zoomin:
    if(m_Image->mvIsValidImage())
        m_Image->mvZoomIn() ;
  6. Entire vertical scroll function:
    void CDraw1View::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
    {
        // TODO: Add your message handler code here and/or call default
        if(m_Image->mvIsValidImage())
            m_Image->mvOnVScroll(nSBCode, nPos, pScrollBar) ;
    
        CView::OnVScroll(nSBCode, nPos, pScrollBar);
    }
  7. Route OnSize message like this:
    void CDraw1View::OnSize(UINT nType, int cx, int cy)
    {
        CView::OnSize(nType, cx, cy);
    
        if((m_Image != 0x000000) && (this->m_hWnd != 0x000000))
        {
            if(m_Image->mvIsValidImage()) 
                m_Image->mvOnSize(nType, cx, cy) ; 
        }
    }
  8. Multi-page TIFF navigation:
    if(m_Image->mvIsValidImage())
        m_Image->mvFrameFirst();

Searching through the source code in draw1View.cpp, you will find all the code you may be interested in.

History

  • 27th August, 2006: Initial post

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

mihK
Software Developer
Romania Romania
Member
No Biography provided

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
GeneralMy vote of 5membermanoj kumar choubey18 Feb '12 - 3:28 
Nice
Questionno source files??memberdumnbncool27 May '09 - 6:13 
hello, i'm not able to download the source files or the demo project from the links given at top of page. Can anyone help meplease :(
AnswerRe: no source files??membermihK27 May '09 - 7:37 
Can you try again now?
Could it be, that I changed the licence? It was for fun of course.
Now it's back as initial.
Sorry for inconveniences.
 
bug free bastard.

GeneralMemory Datamemberheracles710_rns12 Oct '08 - 16:34 
Hi,
I am devleoping a one image project.
I want to get memory data of image.
How can i do ?
Can i get data using this class?
Give me help.
Thank you.
QuestionWhy can not be print?memberMila17 Sep '08 - 21:37 
I use it in a ocx project. It can view image, but it can not be print. Why?
The key function is mvShowImage. How to modify it?
bool mvImage::mvShowImage(bool eraseBackground)
{
Graphics g(this->m_hwnd) ;
if(angle != 0.) g.RotateTransform(angle, MatrixOrderPrepend ) ;
 
//temporary solution to erase the background
if(eraseBackground)
{
Region Rgn ;
g.GetClip(&Rgn) ;
SolidBrush grayBrush(Color::White);
g.FillRegion(&grayBrush, &Rgn) ;
};
 
g.DrawImage(image, X+Ox , Y+Oy, DW, DH ) ;
g.Flush(FlushIntentionFlush) ;
return true ;
}
 
Have fun and be human!

GeneralErrormemberOonaa Lee25 Nov '07 - 15:16 
Hi,
 
Great work! That's too convenient for me!
 
But i found an error! Frown | :(
 
Except constraintAll mode, when sizing the view, if a scroll bar appears then the view receives the WM_SIZE message infinitly.
 
Can you tell me how can i repair this error?
 
email: oonaa3@hotmail.com
 
Thanks!
GeneralGreat article... but need some detailsmemberKiran Satish18 Oct '07 - 10:13 
Hi,
 
This article is a very good source for me to start using GDI+. But, from all the info over the net, one thing thats clear is, its great to use with bitmaps and very flexible with BMPs. But in this program it can open a TIFF image too, but I would like to access the tiff data and would like to save that data into a bitmap after I am done with some processing on that data.
 
Could you help me out in this??
 
thanks,
-Pav
 
PKNT

Generaltoo slowmembermalfaro20 Sep '07 - 5:27 
The fill region process of GDI+ in the ShowImage function is too slow.
You have to save in memoria the image file.

 
Mauricio Alfaro

GeneralAt last I make it.memberChhoto Bou15 Jan '07 - 18:47 
Hello!
 
At last i make it.
 
Thanks for your class. It is just great. not only great, i have no word to say. Just greater mannn...
 
Good workkkk.
 
Bye.
 
I am from Bangladesh. u can mail me to mizanmyself@yahoo.com.
 
Hope we meet again.
GeneralRuntime Error Solve. But .png File not shown in dialog.memberChhoto Bou15 Jan '07 - 18:32 
Hi!
 
how r u?
 
I am again.
 
I solved that runtime error. But now my.png file not show in dialog. A white blank space appear in my dialog and there is no sign of any Image.
 
How can I solve this problem????
 
would u plz tell me why this happend????
 
Thanks again.
Bye.
GeneralRe: Runtime Error Solve. But .png File not shown in dialog.membermihK15 Jan '07 - 20:11 
Sorry , I just got overwelmed with my linux stuffs. Please write to mizanmyself@yahoo.com that succeeded with this code, maybe he may help you. I'm in another country rith now and don't have any further development sources for this project. I now that it has also printing support.
Mihai.
 
Write bug free or else ... don't do it.

GeneralRe: Runtime Error Solve. But .png File not shown in dialog.membermihK15 Jan '07 - 20:22 
Sorry , didn't see it is you. My mistake. The response still remains. You must check gdi+ classes in detail and do things in debugger (extra check). You must use alternative image viewer program to see what kind of png is it. Pay attention to image proprieties, transparent background, gradient. All this I didn't solve properly at that time. I haven't enough time for all this. I wish you succeed.
Mihai.
 
Write bug free or else ... don't do it.

QuestionDialog based ExamplememberChhoto Bou15 Jan '07 - 17:42 
Hi!
 
Thanks for your great work. I wish to use your class in my dialog based project. As I'm new in MFC i need a dialog based example for VC6.
 
Would you plz help me ??????
 
I am stop for some run time Error - "The instruction at "0x00401e3f" referenced at "0xcccccd48". The memory could be "read" .
 
Click on OK to terminate the program......".
 
How can i solve it????
 
plz send me a dialog based example. It will helpfull for me.
 
sorry for convanienc.
 
Thanks again.
AnswerRe: Dialog based Examplemembermalfaro20 Sep '07 - 5:28 
I have a sample of using in a Dialog.
But i don't know to show it to you
 
Mauricio Alfaro

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web01 | 2.6.130516.1 | Last Updated 27 Aug 2006
Article Copyright 2006 by mihK
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid