C++ Ondraw函数在vc++;用ImageMagick
现在我试图在MFC的对话框中显示视图中的图像 代码如下所示C++ Ondraw函数在vc++;用ImageMagick,c++,visual-c++,image-processing,mfc,imagemagick,C++,Visual C++,Image Processing,Mfc,Imagemagick,现在我试图在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(); } #pragma once
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();
}
#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 ==========
及
问题是,当我将图像显示到视图中时,显示图像有太多的延迟。
我不知道该怎么解决这个问题
更新1
我已经更新代码如下
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();
}
#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 ==========
我发现了一些参考代码,如下所示
它怎么能这样用呢
// 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_)
更新2
我编辑过如下内容,但它从未被称为。是这样吗?它什么时候调用这个函数
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);
}
您不应该直接在TestView的DC上绘制,而是创建一个兼容的内存DC,在那里进行所有绘制,然后将内存DC的内容复制到视图的DC上。因为它快多了 为此,您可以将函数更改为从OnDraw调用以接收作为内存DC的参数,并禁止您在任何地方执行GetDC(),除非创建内存DC并将其内容复制回视图DC 你的头发应该是这样的
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);
}
您可能已经注意到有一些剪辑代码;它使绘制速度更快,因为它不会在不需要绘制的地方绘制。最重要的部分是draw_dc.CreateCompatibleDC(pDC)代码>创建内存DC;以及pDC->BitBlt(…,srcopy)代码>将内容从内存复制到视图
旁注:我删除了你上面的台词,因为它们对我来说毫无用处
现在,您的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变量的部分。您是否尝试过使用计时器检测代码,以查看花费了多少时间?你的档案有多大?更新需要多长时间?是否可以在程序开始时而不是每次图形刷新前仅初始化一次ImageMagick?这是一个20像素的高斯模糊吗?这肯定会很慢。试着暂时删除它。@MarkSetchell在OnDraw()中作为显示方法的那种方法怎么样?我有什么需要改变的地方吗?很小的一点,但ff是用来做什么的,为什么它是双倍的?正确::Width()返回int.@Colin谢谢让我知道,我会尝试修复。但我认为它对显示延迟图像没有任何影响。对吗?为什么每次调用OnDraw
时都要从磁盘读取图像文件?