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

 
Hint: For improved responsiveness ensure Javascript is enabled and choose 'Normal' from the Layout dropdown and hit 'Update'.
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 
Questionno source files??memberdumnbncool27 May '09 - 6:13 
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 
QuestionWhy can not be print?memberMila17 Sep '08 - 21:37 
GeneralErrormemberOonaa Lee25 Nov '07 - 15:16 
GeneralGreat article... but need some detailsmemberKiran Satish18 Oct '07 - 10:13 
Generaltoo slowmembermalfaro20 Sep '07 - 5:27 
GeneralAt last I make it.memberChhoto Bou15 Jan '07 - 18:47 
GeneralRuntime Error Solve. But .png File not shown in dialog.memberChhoto Bou15 Jan '07 - 18:32 
GeneralRe: Runtime Error Solve. But .png File not shown in dialog.membermihK15 Jan '07 - 20:11 
GeneralRe: Runtime Error Solve. But .png File not shown in dialog.membermihK15 Jan '07 - 20:22 
QuestionDialog based ExamplememberChhoto Bou15 Jan '07 - 17:42 
AnswerRe: Dialog based Examplemembermalfaro20 Sep '07 - 5:28 

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

Permalink | Advertise | Privacy | Mobile
Web02 | 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