内存绘图 动态修改

waltsin 2009-05-18 02:15:11
我从本地文件中读取一幅图片,使用CPictureHolder在内存中绘制,完成后拷贝到界面中,这样实现可以减少屏幕的闪烁。
现在的问题是:
我从本地读取的图片文件需要做一个简单的修改,在上面加上个斜线,比如:我图片文件里画的是一个正方形,我想等显示到界面上的时候是,正方形中间有一条从左上角到右下角的横线,而加横线是在内存中完成的。不知道如何解决?
...全文
159 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
wangcom 2009-05-19
  • 打赏
  • 举报
回复
CDC m_pDc_;
CBitmap m_blackbmp;
m_pDc_.CreateCompatibleDC(NULL);
m_blackbmp.CreateCompatibleBitmap(pDC,rc.Width(),rc.Height());
CPen pen;
pen.CreatePen(PS_SOLID,2,RGB(0,0,0));
CBrush brush(RGB(0,0,0));
m_pDc_.SelectObject(&pen);
m_pDc_.SelectObject(&brush);
m_pDc_.SelectObject(&m_blackbmp);
m_pDc_.FillRect(rc,&CBrush(RGB(255,255,255)));
//...
这里就可以绘制你想绘制的图了
//...
pDC->BitBlt(0,0,300,300,&m_pDc_,0,0,SRCCOPY);
m_blackbmp.DeleteObject();
m_pDc_.DeleteDC();
Ryanwen 2009-05-19
  • 打赏
  • 举报
回复
不正确? GetLastError()返回值是什么?
hNewBitmap = CreateCompatibleBitmap(pDC->GetSafeHdc(), m_sizeInPix.cx, m_sizeInPix.cy);这句可能会有问题,你窗口和图片大小一样?
hNewBitmap = CreateCompatibleBitmap(pDC->GetSafeHdc()); //可以写成这样,创建一个单色位图
waltsin 2009-05-19
  • 打赏
  • 举报
回复
这是新修改后的代码,麻烦各位给看一下
如果您真的能抽出时间来给我回帖,我非常感谢,如果您回复的时候少用一些问号,多给一些可行的方法,我将感激不尽
void OnDraw(CDC* pDC)
{
char chPicData[10240] = {0};
long nPicDataLen = 0;

FILE *fp = NULL;
fp = fopen("C:\\123.gif", "rb");
if (fp == NULL)
{
fclose(fp);
fp = NULL;
}
fseek(fp, 0, SEEK_END);
nPicDataLen = ftell(fp);
fclose(fp);
fp = NULL;

fp = fopen("C:\\123.gif", "rb");
if (fp == NULL)
{
fclose(fp);
fp = NULL;
}
fread(chPicData, nPicDataLen, 1, fp);
fclose(fp);

IStream *pStm;
HGLOBAL hGlobal = GlobalAlloc(GMEM_MOVEABLE, nPicDataLen);
LPVOID pvData = NULL;
if (hGlobal != NULL)
{
if ((pvData = GlobalLock(hGlobal)) != NULL)
{
memcpy(pvData, chPicData, nPicDataLen);
GlobalUnlock(hGlobal);
CreateStreamOnHGlobal(hGlobal, TRUE, &pStm);
}
}

IPicture *pPic;
HRESULT hr = OleLoadPicture(pStm, nPicDataLen, TRUE, IID_IPicture, (LPVOID*)&pPic);
if (SUCCEEDED(hr) && pPic != NULL)
{
// get width and height of picture
VERIFY(SUCCEEDED(pPic->get_Width(&m_sizeInHiMetric.cx)));
VERIFY(SUCCEEDED(pPic->get_Height(&m_sizeInHiMetric.cy)));

const int HIMETRIC_PER_INCH = 2540;

const HDC hDCScreen = ::GetDC(NULL);
ASSERT(hDCScreen != NULL);
// Pixels per logical inch along width
const int nPixelsPerInchX = ::GetDeviceCaps(hDCScreen, LOGPIXELSX);
// Pixels per logical inch along height
const int nPixelsPerInchY = ::GetDeviceCaps(hDCScreen, LOGPIXELSY);
VERIFY(::ReleaseDC(NULL, hDCScreen) != 0);

// convert himetric to pixels
m_sizeInPix.cx = (nPixelsPerInchX * m_sizeInHiMetric.cx +
HIMETRIC_PER_INCH / 2) / HIMETRIC_PER_INCH;
m_sizeInPix.cy = (nPixelsPerInchY * m_sizeInHiMetric.cy +
HIMETRIC_PER_INCH / 2) / HIMETRIC_PER_INCH;

pStm->Release();
FreeResource(hGlobal);

//显示图像到内存DC
HDC hMemDC;
HBITMAP hOldBitmap;
CBitmap bitmap;

hMemDC = CreateCompatibleDC(pDC->GetSafeHdc());
hNewBitmap = CreateCompatibleBitmap(pDC->GetSafeHdc(), m_sizeInPix.cx, m_sizeInPix.cy);
hOldBitmap = (HBITMAP)SelectObject(hMemDC, hNewBitmap);

CPen penRed(PS_SOLID, 10, RGB(255,0,0) );
CPen* pOldPen = CDC::FromHandle(hMemDC)->SelectObject(&penRed);
CDC::FromHandle(hMemDC)->MoveTo(0, 0);
CDC::FromHandle(hMemDC)->LineTo(200, 200);

pDC->BitBlt(200, 200, 200, 200, CDC::FromHandle(hMemDC), 0, 0, SRCCOPY);
CDC::FromHandle(hMemDC)->SelectObject(&pOldPen);
CDC::FromHandle(hMemDC)->SelectObject(hOldBitmap);
VERIFY(CDC::FromHandle(hMemDC)->DeleteDC());

pPic->Release();
pPic = NULL;
hNewBitmap = (HBITMAP)SelectObject(hMemDC,hOldBitmap);
}
}

我现在的问题是:
hNewBitmap = CreateCompatibleBitmap(pDC->GetSafeHdc(), m_sizeInPix.cx, m_sizeInPix.cy);
执行效果不正确,怎么才能从二进制的图片数据得到CBitmap指针?
Quers 2009-05-18
  • 打赏
  • 举报
回复
看看、、、、、、、、、、、、、、、、、、、、、、、
回帖是一种美德!每天回帖即可获得 10 分可用分!
lambochan 2009-05-18
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 waltsin 的回复:]
我的代码贴上,各位给看看
IStream *pIStream;
CPictureHolder m_pic;
CDC MemDC;
CBitmap bmpFace;
CBitmap *pOldBitmap;

//读取图片数据到char型数组中
//使用char型数组创建Stream对象
OleLoadPicture(pIStream, picturebufferlength, TRUE, IID_IPicture,(LPVOID*)&m_pic.m_pPict);
//得到图片的宽度和高度
SIZE sizeInHiMetric, sizeInPix;
m_pic.m_pPict->get_Width(&sizeInHiMetric.cx);
m_pic.m_pPict->get_Height(&sizeInHiMetric.cy);

//Calculate Its Size On a "Standard" (96 DPI) Device Context
sizeInPix.cx = MulDiv(sizeInHiMetric.cx, 96, HIMETRIC_INCH);
sizeInPix.cy = MulDiv(sizeInHiMetric.cy, 96, HIMETRIC_INCH);

HDC hDC = ::GetDC( NULL );

MemDC.CreateCompatibleDC(CDC::FromHandle(hDC));
bmpFace.CreateCompatibleBitmap(CDC::FromHandle(hDC), sizeInPix.cx, sizeInPix.cy);
//将这幅图片选入内存DC
pOldBitmap = MemDC.SelectObject(&bmpFace);

m_pic.m_pPict->Render(MemDC.GetSafeHdc(), 0, 0, sizeInPix.cx, sizeInPix.cy,
0, sizeInHiMetric.cy, sizeInHiMetric.cx, -sizeInHiMetric.cy, &rcBounds);

// MemDC.SelectObject( pOldBitmap ); 放后面

CPen penRed(PS_SOLID, 10, RGB(255,0,0) );
CPen* pOldPen = MemDC.SelectObject(&penRed);
MemDC.MoveTo(0,0);
MemDC.LineTo(sizeInHiMetric.cx,sizeInHiMetric.cy);
MemDC.SelectObject(pOldPen);

MemDC.SelectObject( pOldBitmap ); 放这里
ReleaseDC( NULL, hDC );

但是这样没有出现效果,不知道为什么

[/Quote]

~~
Ryanwen 2009-05-18
  • 打赏
  • 举报
回复
1、bmpFace.CreateCompatibleBitmap(&MemDC, sizeInPix.cx, sizeInPix.cy); 创建的兼容位图的时候不能以刚创建的兼容DC作为参数
2、MemDC.CreateCompatibleDC(NULL); 为什么以NULL创建兼容DC,你只是想获得位图信息?如果你要在窗口显示你应该以窗口的DC作为参数
3、你在兼容DC绘制完直线、矩形后,应该将兼容DC的内容显示到窗口DC中,如下代码
pDC->BitBlt(0, 0, bmpInfo.bmWidth, bmpInfo.bmHeight, &MemDC, 0, 0, SRCCOPY); //bmpInfo是BITMAP结构体,保存位图的信息
//pDC是显示窗口的DC指针
sun007700 2009-05-18
  • 打赏
  • 举报
回复
GDI+双缓冲技术
实现双缓冲的具体步骤
http://www.cnblogs.com/songsu/articles/1340110.html
fengrx 2009-05-18
  • 打赏
  • 举报
回复
不好意思,看错了。
你的真正显示部分的代码在哪里?
目前所有的操作都是在兼容DC中操作,操作完成后显示代码呢?
fengrx 2009-05-18
  • 打赏
  • 举报
回复
把画线的代码放在显示前

//先执行
CPen penRed(PS_SOLID, 10, RGB(255,0,0) );
CPen* pOldPen = MemDC->SelectObject(&penRed);
MemDC->MoveTo(0,0);
MemDC->LineTo(sizeInHiMetric.cx,sizeInHiMetric.cy);
MemDC->SelectObject(pOldPen);
//再执行
m_pic.m_pPict->Render(MemDC.GetSafeHdc(), 0, 0, sizeInPix.cx, sizeInPix.cy,
0, sizeInHiMetric.cy, sizeInHiMetric.cx, -sizeInHiMetric.cy, &rcBounds);

MemDC.SelectObject(MemDC,pOldBitmap );

waltsin 2009-05-18
  • 打赏
  • 举报
回复
我的代码贴上,各位给看看
IStream *pIStream;
CPictureHolder m_pic;
CDC MemDC;
CBitmap bmpFace;
CBitmap *pOldBitmap;

//读取图片数据到char型数组中
//使用char型数组创建Stream对象
OleLoadPicture(pIStream, picturebufferlength, TRUE, IID_IPicture,(LPVOID*)&m_pic.m_pPict);
//得到图片的宽度和高度
SIZE sizeInHiMetric, sizeInPix;
m_pic.m_pPict->get_Width(&sizeInHiMetric.cx);
m_pic.m_pPict->get_Height(&sizeInHiMetric.cy);

//Calculate Its Size On a "Standard" (96 DPI) Device Context
sizeInPix.cx = MulDiv(sizeInHiMetric.cx, 96, HIMETRIC_INCH);
sizeInPix.cy = MulDiv(sizeInHiMetric.cy, 96, HIMETRIC_INCH);

MemDC.CreateCompatibleDC(NULL);
bmpFace.CreateCompatibleBitmap(&MemDC, sizeInPix.cx, sizeInPix.cy);
//将这幅图片选入内存DC
pOldBitmap = MemDC.SelectObject(&bmpFace);

m_pic.m_pPict->Render(MemDC.GetSafeHdc(), 0, 0, sizeInPix.cx, sizeInPix.cy,
0, sizeInHiMetric.cy, sizeInHiMetric.cx, -sizeInHiMetric.cy, &rcBounds);

MemDC.SelectObject(MemDC,pOldBitmap );

CPen penRed(PS_SOLID, 10, RGB(255,0,0) );
CPen* pOldPen = MemDC->SelectObject(&penRed);
MemDC->MoveTo(0,0);
MemDC->LineTo(sizeInHiMetric.cx,sizeInHiMetric.cy);
MemDC->SelectObject(pOldPen);

但是这样没有出现效果,不知道为什么

hendriclee 2009-05-18
  • 打赏
  • 举报
回复
wutaihua 2009-05-18
  • 打赏
  • 举报
回复
你的要求,直接按照双缓冲的做法,是可以实现的。
Ryanwen 2009-05-18
  • 打赏
  • 举报
回复
用CDC不是很好解决吗? 把图象导入内存DC,在DC上绘图,在将内存DC拷贝到窗口DC显示 典型的双缓冲

15,979

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 界面
社区管理员
  • 界面
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧