现在我试图在MFC对话框中显示图像。
代码如下。
void CTestview::OnDraw(CDC* pDC)
{
CDocument* pDoc = GetDocument();
// TODO: add draw code here
CRect rcWin;
GetWindowRect( &rcWin );
double ff;
ff=rcWin.Width();
rcWin.Height();
DoDisplayImage();
}
和
void CTestview::DoDisplayImage(void)
{
CPoint pt;
CRect rectClient;
CDC * pDC;
pDC = GetDC();
GetClientRect(rectClient);
int ii;
ii=slider_val;
(void) MagickCore::SetClientPath(fileposition);
InitializeMagick(fileposition);
Image m_Image;
Image m_blurgray;
int _imageHeight;
try {
//C:\work\mfc_test5\mfc_test5
m_Image.read(fileposition);
}
catch(Exception)
{
return ;
}
char str_x[10];
char str_y[10];
if (pDC != NULL)
{
m_blurgray.gaussianBlur(20,2); //blur
int nImageY;
int nImageX;
CSize sizeScaled;
// Clear the background
pDC->FillSolidRect(rectClient,pDC->GetBkColor());
pt = rectClient.TopLeft();
nImageX= m_Image.columns() ;
//nImageY = m_Image.rows();
CPoint aa;
aa = rectClient.Size();
// Extract the pixels from Magick++ image object
PixelPacket *pPixels = m_Image.getPixels(0,0,m_Image.columns(),m_Image.rows());
// Set up the Windows bitmap header
BITMAPINFOHEADER bmi;
bmi.biSize = sizeof(BITMAPINFOHEADER);
bmi.biWidth =m_Image.columns();
bmi.biHeight = (-1)*m_Image.rows();
bmi.biPlanes = 1;
bmi.biBitCount = 32;
bmi.biCompression = BI_RGB;
bmi.biSizeImage = 0;
bmi.biXPelsPerMeter = 0;
bmi.biYPelsPerMeter = 0;
bmi.biClrUsed = 0;
bmi.biClrImportant = 0;
// Blast it to the device context
SetStretchBltMode(pDC->m_hDC,COLORONCOLOR);
StretchDIBits(pDC->m_hDC,
0,
0,
m_Image.columns(),
m_Image.rows(),
0,
0,
m_Image.columns(),
m_Image.rows(),
pPixels,
(BITMAPINFO *)&bmi,
DIB_RGB_COLORS,
SRCCOPY);
//UpdateData(FALSE);
}
}
问题是当我将图像显示到视图中时,显示图像有很多延迟。 我不知道应该怎样做才能解决这个问题。
我已将代码更新如下。
#pragma once
#include <Magick++.h>
// CTestview view
class CTestview : public CScrollView
{
DECLARE_DYNCREATE(CTestview)
protected:
CTestview(); // protected constructor used by dynamic creation
virtual ~CTestview();
public:
#ifdef _DEBUG
virtual void AssertValid() const;
#ifndef _WIN32_WCE
virtual void Dump(CDumpContext& dc) const;
#endif
#endif
protected:
virtual void OnDraw(CDC* pDC); // overridden to draw this view
virtual void OnInitialUpdate(); // first time after construct
DECLARE_MESSAGE_MAP()
public:
void DoDisplayImage(void);
Image m_image
};
当我编译上面的代码时,我发现了一些错误。
------ Build started: Project: mfc_test5, Configuration: Release Win32 ------
Build started
PrepareForBuild:
Creating directory "C:\work\mfc_test5\mfc_test5\Release\".
InitializeBuildStatus:
Creating "Release\mfc_test5.unsuccessfulbuild" because "AlwaysCreate" was specified.
ClCompile:
stdafx.cpp
mfc_test5.cpp
c:\program files\imagemagick-6.8.6-q8\include\magick/pixel-accessor.h(160): warning C4244: '=' : conversion from 'double' to 'MagickCore::MagickRealType', possible loss of data
c:\work\mfc_test5\mfc_test5\mfc_test5\Testview.h(33): error C2143: syntax error : missing ';' before '}'
mfc_test5Dlg.cpp
c:\program files\imagemagick-6.8.6-q8\include\magick/pixel-accessor.h(160): warning C4244: '=' : conversion from 'double' to 'MagickCore::MagickRealType', possible loss of data
c:\work\mfc_test5\mfc_test5\mfc_test5\Testview.h(33): error C2143: syntax error : missing ';' before '}'
C:\Program Files\Intel\plsuite\include\ipl.h(778): warning C4819: The file contains a character that cannot be represented in the current code page (949). Save the file in Unicode format to prevent data loss
C:\Program Files\Intel\plsuite\examples\Tutorial.IPL\IPLROOMS\COOKROOM\macros.inc(21): warning C4005: '_ASSERTE' : macro redefinition
C:\Program Files\Microsoft Visual Studio 10.0\VC\include\crtdbg.h(213) : see previous definition of '_ASSERTE'
Build FAILED.
Time Elapsed 00:00:37.30
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
我找到了一些参考代码如下所示。您可以看到,以下代码使用Image m_image。
它怎么能这样使用?
// NtMagickView.h : interface of the CNtMagickView class
//
/////////////////////////////////////////////////////////////////////////////
#if !defined(AFX_NTMAGICKVIEW_H__8A45000C_6176_11D4_AC4F_400070168026__INCLUDED_)
#define AFX_NTMAGICKVIEW_H__8A45000C_6176_11D4_AC4F_400070168026__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#define NTMAGICK_DEFEXT "*.JPG;*.JPEG"
#define NTMAGICK_ALL "All Files (*.*)|*.*|"
#define NTMAGICK_BMP "Bitmaps (*.BMP;*.RLE)|*.BMP;*.RLE|"
#define NTMAGICK_GIF "GIF (*.GIF)|*.GIF|"
#define NTMAGICK_TIF "TIF (*.TIF;*.TIFF)|*.TIF;*.TIFF|"
#define NTMAGICK_JPEG "JPEG (*.JPG;*.JPEG)|*.JPG;*.JPEG|"
#define NTMAGICK_ICON "Icons (*.ICO)|*.ICO|"
class CNtMagickView : public CView
{
protected: // create from serialization only
CNtMagickView();
DECLARE_DYNCREATE(CNtMagickView)
// Attributes
public:
CString m_szFile;
Image * m_pImage;
CNtMagickDoc* GetDocument();
void DoDisplayError(CString szFunction, CString szCause);
void DoDisplayImage();
BOOL DoReadImage();
CSize Scale(CSize sizeSrc, CSize sizeTgt);
float ScaleFactor(BOOL bAllowZoom, CSize sizeSrc, CSize sizeTgt);
void UpdateUI(CCmdUI* pCmdUI);
// Operations
public:
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CNtMagickView)
public:
virtual void OnDraw(CDC* pDC); // overridden to draw this view
virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
protected:
//}}AFX_VIRTUAL
// Implementation
public:
virtual ~CNtMagickView();
#ifdef _DEBUG
virtual void AssertValid() const;
virtual void Dump(CDumpContext& dc) const;
#endif
protected:
// Generated message map functions
protected:
//{{AFX_MSG(CNtMagickView)
afx_msg void OnFileOpen();
afx_msg void OnImageFlipHorizontal();
afx_msg void OnUpdateImageFlipHorizontal(CCmdUI* pCmdUI);
afx_msg void OnImageFlipVertical();
afx_msg void OnUpdateImageFlipVertical(CCmdUI* pCmdUI);
afx_msg void OnImageRotate180();
afx_msg void OnUpdateImageRotate180(CCmdUI* pCmdUI);
afx_msg void OnImageRotate90();
afx_msg void OnUpdateImageRotate90(CCmdUI* pCmdUI);
afx_msg void OnImageRotate90ccw();
afx_msg void OnUpdateImageRotate90ccw(CCmdUI* pCmdUI);
afx_msg void OnFileClear();
afx_msg void OnUpdateFileClear(CCmdUI* pCmdUI);
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
#ifndef _DEBUG // debug version in NtMagickView.cpp
inline CNtMagickDoc* CNtMagickView::GetDocument()
{ return (CNtMagickDoc*)m_pDocument; }
#endif
/////////////////////////////////////////////////////////////////////////////
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_NTMAGICKVIEW_H__8A45000C_6176_11D4_AC4F_400070168026__INCLUDED_)
我已按照以下方式进行了编辑,但并未进行过调用。这是正确的吗?什么时候调用这个函数?
void CTestview::OnInitialUpdate()
{
CScrollView::OnInitialUpdate();
CSize sizeTotal;
// TODO: calculate the total size of this view
sizeTotal.cx = sizeTotal.cy = 100;
SetScrollSizes(MM_TEXT, sizeTotal);
m_pimage.read(fileposition);
}
答案 0 :(得分:0)
您不应直接在TestView的DC上绘制,而是创建兼容的内存DC,在那里执行所有绘图,然后将内存DC的内容复制到视图的DC。因为它更快!
为此,您可以更改要从OnDraw调用的函数以接收作为内存DC的参数,除了创建内存DC并将其内容复制回视图DC外,禁止自己在任何地方执行GetDC()。
你的OnDraw应该是
void CTestview::OnDraw(CDC* pDC)
{
CDocument* pDoc = GetDocument();
// TODO: add draw code here
CDC draw_dc;
CBitmap draw_bitmap;
CBitmap* old_bitmap;
CRect draw_area;
pDC->GetClipBox(draw_area);
draw_dc.CreateCompatibleDC(pDC);
draw_bitmap.CreateCompatibleBitmap(pDC, draw_area.Width(), draw_area.Height());
old_bitmap = (CBitmap*)draw_dc.SelectObject(&draw_bitmap);
OnPrepareDC(&draw_dc, NULL);
pDC->LPtoDP(draw_area);
draw_dc.OffsetViewportOrg(-draw_area.left, -draw_area.top);
pDC->DPtoLP(draw_area);
draw_dc.IntersectClipRect(draw_area);
DoDisplayImage(&draw_dc);
pDC->BitBlt(draw_area.left, draw_area.top, draw_area.Width(), draw_area.Height(), &draw_dc, 0, 0, SRCCOPY);
draw_dc.SelectObject(old_bitmap);
DeleteObject(draw_bitmap);
DeleteDC(draw_dc);
}
你可能已经注意到有一些剪辑代码;它使绘图更快,因为它不会在不需要它的地方绘制。最重要的部分是创建内存DC的draw_dc.CreateCompatibleDC(pDC);
;以及将内容从内存复制到视图的pDC->BitBlt( ... , SRCCOPY);
。
旁注:我删除了上面的行,因为它们对我来说似乎毫无用处。
现在您的DoDisplayImage
功能应该是:
void CTestview::DoDisplayImage(CDC* pDC)
{
CPoint pt;
CRect rectClient;
GetClientRect(rectClient);
int ii;
ii=slider_val;
(void) MagickCore::SetClientPath(fileposition);
InitializeMagick(fileposition);
Image m_Image;
Image m_blurgray;
int _imageHeight;
try {
//C:\work\mfc_test5\mfc_test5
m_Image.read(fileposition);
}
catch(Exception)
{
return ;
}
char str_x[10];
char str_y[10];
if (pDC != NULL)
{
m_blurgray.gaussianBlur(20,2); //blur
int nImageY;
int nImageX;
CSize sizeScaled;
// Clear the background
pDC->FillSolidRect(rectClient,pDC->GetBkColor());
pt = rectClient.TopLeft();
nImageX= m_Image.columns() ;
//nImageY = m_Image.rows();
CPoint aa;
aa = rectClient.Size();
// Extract the pixels from Magick++ image object
PixelPacket *pPixels = m_Image.getPixels(0,0,m_Image.columns(),m_Image.rows());
// Set up the Windows bitmap header
BITMAPINFOHEADER bmi;
bmi.biSize = sizeof(BITMAPINFOHEADER);
bmi.biWidth =m_Image.columns();
bmi.biHeight = (-1)*m_Image.rows();
bmi.biPlanes = 1;
bmi.biBitCount = 32;
bmi.biCompression = BI_RGB;
bmi.biSizeImage = 0;
bmi.biXPelsPerMeter = 0;
bmi.biYPelsPerMeter = 0;
bmi.biClrUsed = 0;
bmi.biClrImportant = 0;
// Blast it to the device context
SetStretchBltMode(pDC->m_hDC,COLORONCOLOR);
StretchDIBits(pDC->m_hDC,
0,
0,
m_Image.columns(),
m_Image.rows(),
0,
0,
m_Image.columns(),
m_Image.rows(),
pPixels,
(BITMAPINFO *)&bmi,
DIB_RGB_COLORS,
SRCCOPY);
//UpdateData(FALSE);
}
}
旁注:你似乎在这里也有无用的代码,即带有aa和ii变量的部分。