CImage类提供了GetBits()函数来读取数据区,GetBits()函数返回的是图片最后一行第一个像素的地址,网上有人说返回指针的起始位置是不同的,有些图片返回的是左上角像素的地址,有些是左下角像素的地址,跟图片内部顺序有关。这里我们不必关心起始位置,只要很另外两个函数GetPitch()和GetHeight()一起使用就可以得到图片数据取得起始位置,定义数据区指针为BYTE*
img_Data
img_Data=(BYTE
*)m_Image.GetBits()+(m_Image.GetPitch()*(m_Image.GetHeight()-1));
这样,img_Data就是图片数据区的起始位置,这个公式是从codeproject里看到的,介绍的很精辟,可以从google里搜索到。其中GetHeight()函数返回图片的高度(以像素为单位)。GetPitch()返回图像的斜度,如果图像的顺序是从下到上(也就是GetBits()返回左上角像素的地址),这时GetPitch()返回一个负值,大小为图像宽所占有的字节数,例如24位800*600的图片,返回值应该是正或负的800*3。这样用每一行的字节数乘行数就可以得到起始位置了。
下面再引入两个函数,Load()用来装在一个图像,Draw()用来在一个矩形区域绘制图像,这两个函数比较好理解,看个例子就能明白。下面是一个显示图像的程序,这里只给出打开图像文件和显示图像的函数,用的是带滚动条的多文档模式。
void
CCImageTestView::OnFileOpen()
{
CString strFilter;
CSimpleArray
aguidFileTypes;
HRESULT hResult;
hResult =
m_Image.GetExporterFilterString(strFilter,aguidFileTypes,_T(“All Image
Files”));
if
(FAILED(hResult))
{
AfxMessageBox(“调用函数失败”);
return;
}
CFileDialog
dlg(TRUE,NULL,NULL,OFN_FILEMUSTEXIST,strFilter);
if (IDOK !=
dlg.DoModal())
{
return;
}
m_Image.Destroy();
//按打开按钮弹出一个打开文件的对话框
hResult = m_Image.Load(dlg.GetFileName());
//利用打开文件对话框返回的文件路径装载图像
if
(FAILED(hResult))
{
AfxMessageBox(“调用图片失败”);
return;
}
//以下是文档标题栏文字
CString
str;
str.LoadString(AFX_IDS_APP_TITLE);
AfxGetMainWnd()->SetWindowText(str+’-'+dlg.GetFileName());
OnInitialUpdate();
Invalidate();
}
绘图函数
void
CCImageTestView::OnDraw(CDC* pDC)
{
CCImageTestDoc* pDoc =
GetDocument();
ASSERT_VALID(pDoc);
if
(!pDoc)
return;
if(!m_Image.IsNull())
{
m_Image.Draw(pDC->m_hDC,0,0);//用Draw()函数绘图
}
}
再给出个初始化滚动条的函数作为补充。
void
CCImageTestView::OnInitialUpdate()
{
CScrollView::OnInitialUpdate();
CSize
sizeTotal;
// TODO: 计算此视图的合计大小
int
ImageW,ImageH;
if(!m_Image.IsNull())
{
ImageW=m_Image.GetWidth();
ImageH=m_Image.GetHeight();
sizeTotal.cx
= ImageW;
sizeTotal.cy =
ImageH;
}
else
{
sizeTotal.cx=sizeTotal.cy=100;
}
SetScrollSizes(MM_TEXT,
sizeTotal);
}