Streaming IPicture object
Environment: VC++ 5.0-6.0, NT 4.0,Win2000, Win95/98
I really like the IPicture object. This COM object works very fine. However, I had some problem when I was trying to use it in a Document-View architecture. The main problem is implementation of serialization. To resolve this problem I built two classes.
The first class called CPictureObj. This class is responsible for drawing the picture. The second class, CPictureObjList, is a collection of picture objects. By using both of these classes it is easy to implement the following functionality:
- Load one or more images into document (*.bmp, *.jpeg, *.ico,etc...)
- Scale images(Zoom In, Zoom Out)
- Move images by cursor
- Alignment
- Save/Load images to/from compound document file.
Classes
classCPictureObj: publicCPictureHolder, publicCObject{ DECLARE_SERIAL(CPictureObj);public: CPictureObj(); CPictureObj(const CRect position);virtual~CPictureObj(); void RemoveAndDestroy();virtualvoid Copy( CPictureObj &right);virtualHRESULT WriteToStream(IStream* pStream);virtualHRESULT ReadFromStream(IStream* pStream); // Attributespublic: HorzAlign GetHorzAlign( void ) const; void SetHorzAlign( HorzAlign eHorzAlign ); VertAlign GetVertAlign( void ) const; void SetVertAlign( VertAlign eVertAlign ); BOOL GetSelected( void ) const; void SetSelected( BOOL bValue ); void SetVisible(BOOL bValue); BOOL GetVisible(); CRect GetPosition(); void SetPosition(const CRect pos); CRect GetStartRect(); void SetStartRect(const CRect pos); CString GetPathName(); void SetPathName(const CString pathname); OLE_HANDLE GetHandle(); CSize GetSize(); // in himetric CSize GetSize(CDC*pDC); // in pixel CSize GetSize(CWnd*pWnd); // in pixel BOOL IsValidPicture(); // Operationspublic: BOOL Load(LPCTSTR szFile); BOOL CreateFromFile(const CPoint pt); void ReleasePicture(); void MoveTo(const CRect& position, CWnd* pView); // Drawing picture void Draw(CDC* pDC); void Draw(CDC* pDC, CRect& rcBounds); void Draw(CDC* pDC, const CRect& rcPosition, const CRect& rcBounds); void DrawTracker(CDC* pDC); void DrawTracker(CDC* pDC, const CRect& rect); void ZoomIn(); void ZoomOut();protected: void CalcZoom(); void SetZoomToPosition();protected: HorzAlign m_eHorizAlign; VertAlign m_eVertAlign; BOOL m_bSelected; BOOL m_bVisible; CRect m_rcPosition; // in pixels CRect m_startRect; // in pixels int m_trackerStyle; int m_zoomX,m_zoomY; // Not serialized CString m_strPathName; };classCPictureObjList: publicCTypedPtrList{CObList, CPictureObj*} {public: ~CPictureObjList(); void RemoveAndDestroy(); void DeselectAll(); CSize ComputeMaxSize(); // in himetric CSize ComputeMaxSize(CDC* pDC); // in pixel CSize ComputeMaxSize(CWnd* pWnd); // in pixel CRect GetRect(); // in pixel CPictureObj* FindSelected(); CPictureObj* ObjectAt(const CPoint& pt); bool Remove(CPictureObj* pObj); void Draw(CDC* pDC); // Streaming HRESULT WriteToStream(IStream* pStream); HRESULT ReadFromStream(IStream* pStream); BOOL WriteToStorage(LPSTORAGE lpRootStg); BOOL ReadFromStorage(LPSTORAGE lpRootStg); };
Using the classes.
For use streaming picture create your document object derived from COleDocument.
classCYourDoc :publicCOleDocument
Define inside of document object the picture collection like here:
CPictureObjList m_objects;
Now, you can insert picture by simple way:
CPictureObj* pObj =newCPictureObj; pObj->CreateFromFile(CPoint(10,10)); m_objects.AddHead(pObj);
Also, you can load picture directly from the file:
CPictureObj* pObj =newCPictureObj; pObj->Load("MyFile.jpg"); m_objects.AddHead(pObj);
For scaling picture you can use ZoomIn, ZoomOut member functions:
CPictureObj* pObj = m_objects.FindSelected();
if(pObj)
{
pObj->ZoomIn();
}
Moving the selected picture is easy:
CPoint delta = point - c_last; CPictureObj* pSel = m_objects.FindSelected();if(pSel) { CRect position = pSel->GetPosition(); position += delta; pSel->MoveTo(position,this); }
Drawing collection of pictures is also easy:
GetDocument()->m_objects.Draw(pDC);
Implementation of picture serialization you can get from here:
voidCYourDoc::Serialize(CArchive& ar) { CWaitCursor wait; COleDocument::Serialize(ar);if(ar.IsStoring()) { m_objects.WriteToStorage(m_lpRootStg); }else{ m_objects.ReadFromStorage(m_lpRootStg); m_objects.DeselectAll(); } }
Downloads
Download demo project - 150 KbDownload source - 6.48 Kb

Comments
color blur when running in 65535 color mode + scrolling problem
Posted by Legacy on 06/05/2002 12:00amOriginally posted by: IonelB
I have a SDK aplication very much like ADCSee.
I am using IPicture to load images and I an having these problems
Independent of the file format the colors of the pictures are blured and the picture is wrecked. (However this does not happen if the picture ids displayed in ACDSee or another picture viewer which perhaps uses other techniques)
2. how do you scroll a picture realized with IPicture->render? I have tried it in the classical way (with WM_SIZE- SetScrollSize, WM_HSCROLL and WM_VSCROLL) but it seem that render only renders the portion of DC that is visible. When I scroll a blank portion of image or a blured mix of color is showed.
ReplyThenk you very much for any help,
Ionel
How crop the picture?
Posted by Legacy on 05/10/2002 12:00amOriginally posted by: BlackFox
Thank you
ReplyGDI+ Made easy
Posted by Legacy on 11/04/2001 12:00amOriginally posted by: Leandro Gustavo Biss Becker
Hi
Use gdi+ to manipulate pictures. See GDI+ codeguru session.
Replywoh! really great
Posted by Legacy on 11/03/2001 12:00amOriginally posted by: vikas saxena
ReplyReally nice, except...
Posted by Legacy on 11/01/2001 12:00amOriginally posted by: Jackson
This is really nice except on the menu the Zoom in and Zoom out buttons do the opposite of what they should
Reply