| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 972 人关注过本帖
标题:JPG的显示造成程序耗费内存越来越多
只看楼主 加入收藏
youken
Rank: 1
等 级:新手上路
帖 子:37
专家分:0
注 册:2007-11-11
收藏
 问题点数:0 回复次数:2 
JPG的显示造成程序耗费内存越来越多
程序功能:对某些参数进行计算,并生成一列JPG图,如1.jpg,2.jpg,3.jpg。然后利用GDI+,将1.jpg读入进来并显示在视图上,点击下一张按钮,依次读入后面的JPG图。

问题:随着JPG图片的不断载入,程序所消耗的内存会逐步递增。

首先描述一下我这个程序的设计思路:这个程序通过计算,首先生成一列JPG图片并保存在某个硬盘路径中,然后程序会读取第一个JPG文件并将它显示在视图里,工具栏有个按钮,点击一下,程序会读取下一个JPG文件,显示在视图中。每次需要显示一个JPG时,会调用名为DrawPicture的函数,这是一个文档类的函数,它通过向视图发送消息,传递JPG图片的路径,并响应视图类的OnUpdate函数,JPG的载入和绘图都是在OnUpdate函数中具体执行的,由于涉及到图片的放大缩小和漫游,因此我用的是双缓冲方法来显示图片。

相关代码如下:

首先在试图的OnInitialUpdate中初始化
void CMy2008BAC35B02View::OnInitialUpdate()
{
// CScrollView::OnInitialUpdate();

// 内存画布的初始化设置
m_memDC.CreateCompatibleDC(NULL); // 准备一个内存DC
CDC * pDC = GetDC();
m_memBitmap.CreateCompatibleBitmap(pDC, 5000, 4000); // 准备一个5000*4000的位图画布
ReleaseDC(pDC);

// 滚动条初始化设置
SetScrollSizes();
}


然后自定义一个消息函数,用来接收菜单传入的图片的地址
// 自定义消息函数,当文档类向本视图发送WM_NOTIFY_DRAW消息时,执行该函数,接收来自对话框的
// 图件完整路径信息,并绘图
LRESULT CMy2008BAC35B02View::OnNotifyDraw(WPARAM wParam, LPARAM lParam)
{
CString *p_strGetPicPathName;
// 将lParam参数转换为指向CString的指针,这个指针指向的CString对象携带了图件完整路径信息
p_strGetPicPathName = (CString*)lParam;
m_strPicPathName = *p_strGetPicPathName; // 完整路径赋值给View的成员变量

CMy2008BAC35B02Doc *pDoc = GetDocument();
pDoc->UpdateAllViews(NULL); // 更新视图,调用视图类的OnUpdate函数
SetScrollSizes(); // 设置滚动条
return 1;
}
其中定义了成员变量
CString p_strGetPicPathName;


然后再定义几个成员变量
Image *image;
IStream *pStream;
HGLOBAL hMem;
并在视图类的构造函数中初始化为NULL。
在OnUpdate中执行具体的绘图
void CMy2008BAC35B02View::OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint)  
{
CFile file;
if (!file.Open(m_strPicPathName, CFile::modeRead))
{
MessageBox("无法打开结果图件。", "错误", MB_OK|MB_ICONSTOP);
return;
}

DWORD m_nFileLen;
m_nFileLen = file.GetLength();

// 每执行一次OnUpdate,都先清空内存
if (!hMem)
{
::GlobalFree(hMem);
hMem = NULL;
}
// 动态分配内存
// 分配的是固定内存,不是可移动的(GMEM_MOVEABLE),故不必锁定内存
hMem = ::GlobalAlloc(GMEM_FIXED, m_nFileLen);
if (hMem==NULL)
{
MessageBox("内存分配失败。", "错误", MB_OK|MB_ICONSTOP);
return;
}
if (file.Read(hMem, m_nFileLen)!=m_nFileLen)
{
MessageBox("读结果图件失败", "错误", MB_OK|MB_ICONSTOP);
::GlobalFree(hMem);
return;
}
file.Close();
pStream = NULL;
if (CreateStreamOnHGlobal(hMem, FALSE, &pStream)!=S_OK)
{
MessageBox("创建IStream对象失败。", "错误", MB_OK|MB_ICONSTOP);
::GlobalFree(hMem);
return;
}

if (!image)
{
delete image;
image = NULL;
}
image = Image::FromStream(pStream);
pStream->Release();

// 得到图像的宽和高
m_nPicWidth = image->GetWidth();
m_nPicHeight = image->GetHeight();

// 得到当前视图的宽和高
CRect rcClient;
GetClientRect(&rcClient);
m_nClientWidth = rcClient.Width();
m_nClientHeight = rcClient.Height();

// 得到图像缩放后的宽和高
m_nPicZoomedWidth = (int)(m_nPicWidth*m_nScale);
m_nPicZoomedHeight = (int)(m_nPicHeight*m_nScale);

// 求视图中显示图片的原点
m_nClientOriginX = (m_nClientWidth-m_nPicZoomedWidth)/2;
m_nClientOriginY = (m_nClientHeight-m_nPicZoomedHeight)/2;
if (m_nClientOriginX<0)
m_nClientOriginX = 0;
if (m_nClientOriginY<0)
m_nClientOriginY = 0;

// 在内存画布上显示图形
// 将准备的位图画布选入内存DC中成为内存画布
m_pOldBitmap = m_memDC.SelectObject(&m_memBitmap);
m_memDC.FillSolidRect(0, 0, 5000, 4000, RGB(255,255,255)); // 用白色填充整个内存画布
Graphics graphics(m_memDC.GetSafeHdc()); // 内存DC和GDI+的Graphics对象关联
// 设置插值模式改善图像缩放质量
graphics.SetInterpolationMode(InterpolationModeNearestNeighbor);
Rect destinationRc(0, 0, m_nPicZoomedWidth, m_nPicZoomedHeight);
// 在内存画布上显示图像
graphics.DrawImage(image, destinationRc, 0, 0, m_nPicWidth, m_nPicHeight, UnitPixel);
m_memDC.SelectObject(m_pOldBitmap);
Invalidate(); // 提示OnDraw重绘
}

最后在OnDraw中显示图像
void CMy2008BAC35B02View::OnDraw(CDC* pDC)
{
CMy2008BAC35B02Doc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here
// 直接绘制内存画布上的位图(双缓冲)
pDC->BitBlt(m_nClientOriginX, m_nClientOriginY, m_nPicZoomedWidth, m_nPicZoomedHeight,
&m_memDC, 0, 0, SRCCOPY);
}


如果按照上面的代码,分配的内存应该都是及时清空了的,因为每一次显示JPG时,都会先清空上一次分配的内存。但实际情况是随着JPG的不断显示,程序耗费的内存越来越多。不过,如果程序最小化了,貌似内存又被瞬间清空了,不知是怎么回事?
搜索更多相关主题的帖子: 内存 JPG 
2010-11-16 12:44
youken
Rank: 1
等 级:新手上路
帖 子:37
专家分:0
注 册:2007-11-11
收藏
得分:0 
手上没分,没法分配分数,但问题又很急,实在不好意思。
2010-11-16 12:45
hellovfp
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:禁止访问
威 望:30
帖 子:2976
专家分:7697
注 册:2009-7-21
收藏
得分:0 
好像没有看见memDC的释放。

我们都在路上。。。。。
2010-11-18 13:40
快速回复:JPG的显示造成程序耗费内存越来越多
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.029017 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved