1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
#pragma once
 
 
// CImageViewer
 
#include "ImageBuffer.h"
#include <d2d1.h>
#include <wincodec.h>
#include <vector>
#include <list>
#include "afxmt.h"
 
enum ViewScaleType            { ViewScale_Origin=0, ViewScale_Zoom, ViewScale_Fit, ViewScale_Count };
enum DrawObjectType            { DrawObject_Line=0, DrawObject_Rectangle, DrawObject_Ellipse, DrawObject_Polygon, DrawObject_Count };
enum ColorBandShiftValue    { AlphaShiftValue = 24, RedShiftValue = 16, GreenShiftValue = 8, BlueShiftValue = 0 };
 
#define SafeRelease(T)        if(T)    {T->Release(); T = 0; }
#define SafeDelete(T)        if(T)    {delete T; T = 0; }
 
static UINT MakeColor(BYTE a, BYTE r, BYTE g, BYTE b)
{
    return (((UINT) (b) <<  BlueShiftValue) |
        ((UINT) (g) <<    GreenShiftValue) |
        ((UINT) (r) <<  RedShiftValue) |
        ((UINT) (a) <<    AlphaShiftValue));
}
 
struct SDoublePos
{
    SDoublePos(double dX=0, double dY=0) 
    {
        dPosX = dX;
        dPosY = dY;
    }
    double dPosX;
    double dPosY;
};
typedef std::vector<SDoublePos>                        VectorDoublePos;
typedef std::vector<SDoublePos>::iterator            VectorDoublePosIt;
typedef std::vector<SDoublePos>::const_iterator        constVectorDoublePosIt;
 
struct SDrawObject
{
public:
    SDrawObject()    { Reset(); }
    ~SDrawObject()    { Reset(); }
 
    void Reset()
    {
        nIndex            = 0;
        nType            = DrawObject_Line;
        strName            = _T("");
        nPenColor        = MakeColor(0,255,0,0);
        nBrushColor        = MakeColor(0,0,0,0);
        dPenOpacity        = 0.6;
        dBrushOpacity    = 0.2;
        dPenSize        = 1; // 1pixel
 
        dPosX            = 0.0;            
        dPosY            = 0.0;        
        dSizeX            = 0.0;
        dSizeY            = 0.0;
 
        vecPolygon.clear();
    }
 
    double Left() const        { return dPosX; }
    double Top() const        { return dPosY; }
    double Right() const    { return (dPosX+dSizeX); }
    double Bottom() const    { return (dPosY+dSizeY); }
    double Width() const    { return dSizeX; }
    double Height() const    { return dSizeY; }
 
    int                nIndex;            // ¼ø¹ø
    int                nType;            // Å¸ÀÔ
    CString            strName;        // À̸§
    UINT            nPenColor;        // Ææ Ä÷¯
    double            dPenOpacity;    // Ææ ºÒÅõ¸íµµ        (0~1)
    UINT            nBrushColor;    // ºê·¯½Ã Ä÷¯
    double            dBrushOpacity;    // ºê·¯½Ã ºÒÅõ¸íµµ    (0~1)
 
    double            dPenSize;        // Ææ Å©±â            pixel
    double            dPosX;            // ¿øÁ¡ X            pixel
    double            dPosY;            // ¿øÁ¡ Y            pixel
    double            dSizeX;            // »çÀÌÁî X            pixel
    double            dSizeY;            // »çÀÌÁî Y            pixel
 
    VectorDoublePos    vecPolygon;        // Æú¸®°ï Á¤º¸        pixel
};
typedef std::list<SDrawObject>                    ListDrawObject;
typedef std::list<SDrawObject>::iterator        ListDrawObjectIt;
typedef std::list<SDrawObject>::const_iterator    constListDrawObjectIt;
 
class AFX_EXT_CLASS CImageViewer : public CWnd, public CImageBuffer
{
    DECLARE_DYNAMIC(CImageViewer)
 
public:
    CImageViewer(CWnd* pParentWnd=NULL);
    virtual ~CImageViewer();
 
    BOOL LoadImage(const CString& strFilename);
 
protected:
    DECLARE_MESSAGE_MAP()
 
public:
    // setter
    void    SetViewType(int nType);
    void    SetDrawViewName(BOOL bDraw);
    void    SetDrawObject(BOOL bDraw);
    void    SetDrawRoi(BOOL bDraw);
    void    SetViewName(const CString& strValue);
    void    SetRoiRect(const CRect& rtRect);
 
    void    SetScale(double dScale);
    void    SetWidthScale(double dScale);
    void    SetHeightScale(double dScale);
 
    // getter
    int        GetViewType() const;
    BOOL    GetDrawViewName() const;
    BOOL    GetDrawObject() const;
    BOOL    GetDrawRoi() const;
    CString    GetViewName() const;
    CRect    GetRoiRect() const;
        
    double    GetScale() const;
    double    GetWidthScale(void) const;
    double    GetHeightScale(void) const;
    
    int        GetHScrollPos(void) const;
    int        GetVScrollPos(void) const;
    int        GetScaleWidth(void);
    int        GetScaleHeight(void);
 
    // draw object
    void    AddDrawObject(const SDrawObject& drawObject);
    void    DeleteAllDrawObject(void);
 
    // clear screen
    void    ClearScreen();
public:
    afx_msg void OnPaint();
    afx_msg void OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);
    afx_msg void OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);
    afx_msg void OnSize(UINT nType, int cx, int cy);
    afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
 
protected:
    CWnd                *m_pParentWnd;
    
    // scroll pos
    int                    m_nVScroll;
    int                    m_nHScroll;
 
    // max scroll pos
    int                    m_nMaxVScroll;
    int                    m_nMaxHScroll;
 
    // image draw
    int                    m_nViewType;
    int                    m_nScaleWidth;
    int                    m_nScaleHeight;
    double                m_dWidthScale; 
    double                m_dHeightScale;
 
    // draw view name
    BOOL                m_bDrawViewName;
    CString                m_strViewName;
    
    // draw roi
    BOOL                m_bDrawRoi;
    SDrawObject            m_rtRoiRect;
 
    // draw object
    BOOL                m_bDrawObject;
    ListDrawObject        m_listDrawObject;
    
protected:
    void DrawViewName();
    void DrawRoi();
    void DrawObject();
    void DrawObject(const SDrawObject& object);
    void CalculateRect();    
 
protected:
    BOOL CreateRenderTarget(const CRect& rtRect);
    int CreateWicBitmap(int nWidthStep, int nHeight, int nChannels, BYTE* pBuffer);
 
    static BOOL IntersectsWith(const D2D1_RECT_F& rect1, const D2D1_RECT_F& rect2)
    {
        return (    rect1.left        < rect2.right &&
            rect1.top        < rect2.bottom &&
            rect1.right        > rect2.left &&
            rect1.bottom    > rect2.top);
    }
 
protected:
    IWICImagingFactory        *m_pWICFactory;
    IWICBitmap                *m_pWICBitmap;
    IWICFormatConverter        *m_pWICFormatConverter;
 
    ID2D1Factory            *m_pD2DFactory;
    ID2D1HwndRenderTarget    *m_pD2DRenderTarget;
    ID2D1Bitmap                *m_pD2DBitmap;
    CCriticalSection        *m_pD2DCriticalSection;
 
    int                        m_nWicBitmapWidthStep;
    int                        m_nWicBitmapHeight;
    int                        m_nWicBitmapChannels;
    CRect                    m_rtViewRect;                    // ÇöÀç ºäÀÇ Å©±âÁ¤º¸
    CRect                    m_rtOrgViewRect;                // ½ÇÀç ºäÀÇ Å©±âÁ¤º¸
    D2D1_RECT_F                m_rtSourceRect;                    // ¿øº» À̹ÌÁö Á¤º¸
    D2D1_RECT_F                m_rtDestRect;                    // ¸ñÇ¥ À̹ÌÁö Á¤º¸
    D2D1_RECT_F                m_rtRenderRect;
};