高手救命啊,一个画图程序 读写位图的I/O操作问题

Alain_Delone 2002-09-22 10:32:17
我们作业正做一个画图程序,我现在用DOCUMENT/VIEW结构,现在我很困惑我该怎么用DOC的 SERIAL函数将一个位图读入并关键是要用BITBLT存入一个CDC就行了,可我不知道该怎么弄,原来SDK程序中我是抄 WINDOWS程序设计上的例子的,现在
遇到了ARCHIEVE这个封装的对象我实在搞不懂了,请各位大侠帮忙
...全文
207 43 打赏 收藏 转发到动态 举报
写回复
用AI写文章
43 条回复
切换为时间正序
请发表友善的回复…
发表回复
stonespace 2002-09-23
  • 打赏
  • 举报
回复
你用CreateDIBSection的时候,参数HANDLE hSection不要给NULL,这样你就可以从HANDLE hSection中取得位图数据。

然后用GetObject可以取得那些头信息,参考diblook,可以看到那几个头在.bmp文件中的位置。
Alain_Delone 2002-09-23
  • 打赏
  • 举报
回复
diblook里根本就没有从DC往DIB对象或文件存内容,最多只有把文件中的图象贴上DC, 因为它的程序不改变图象大小,我的程序要改变图象大小,存的时候肯定要 新建一个DIB,然后把DC里的内容贴进去,可是我只知道可以通过CREATEDIBSECTION来创建一个HBITMAP,可以通过用DC SELECT这个BITMAP然后往这个DC贴图来改变HBITMAP,但是然后呢?我怎么建立HBITMAP和DIB对的关系?或者直接把HBITMAP的内容写入文件??

Alain_Delone 2002-09-23
  • 打赏
  • 举报
回复
我在ONOPENDOCUMENT()里把位图存入了内存DC,然后在 VIEW的ON DRAW函数里把它用BITBLT贴到VIEW上,怎么显示不出?
在ONDRAW中画了,ONPAINT还要写吗?
Alain_Delone 2002-09-23
  • 打赏
  • 举报
回复
哪里弄这些包?
stonespace 2002-09-23
  • 打赏
  • 举报
回复
diblook有一组函数,能够写入dib,不过它把所有的dib数据放在同一个缓冲区内,然后用一组函数取得每个信息头在缓冲区的位置。

CImage包也有类似的函数。
Alain_Delone 2002-09-23
  • 打赏
  • 举报
回复
我想用DIBSTRUCT这个封装的对象,建一个这个对象,例子上都是用这个对象打开文件读入其中,最后又保存,我要在保存前先创建这么个对象(根据内存DC中图片大小),把DC里的东西贴入这个对象内,然后再把这个DIB对象写入文件
但之前根据DC大小创建这么个对象要写很多信息头,我不知道怎么写,想找个封装好的函数,或代码,
Alain_Delone 2002-09-23
  • 打赏
  • 举报
回复
恩,我也该写一套自己的图片处理类,不然老是这么东拉西拉拉函数太乱了
stonespace 2002-09-23
  • 打赏
  • 举报
回复
我以前一直用ddb,效果从来没有问题,不过总是有一种不安的感觉。我还是想把我的类从ddb改为dib,因为这样输出的图形文件的质量和设备无关,比较可靠一些。
stonespace 2002-09-23
  • 打赏
  • 举报
回复
如果你的DIB对象是一个HBITMAP句柄,可以直接用BitBlt写入,再建一个内存DC就可以。
Alain_Delone 2002-09-23
  • 打赏
  • 举报
回复
哦,原来还有这么段历史啊,不过现在显卡技术那么高了,设备依赖性问题越来越小了吧
stonespace 2002-09-23
  • 打赏
  • 举报
回复
当年windows 3.1的时候,根本没有CreateDIBSection函数,我们都只能用CreateCompatibleBitmap来实现双缓冲区显示,避免闪烁。

不过如果你要保存bmp格式文件,还是用dib好,因为ddb和设备有关,如果设备支持的颜色数目少的话,会损失颜色。如果显卡是256色的vga,那生成的bmp文件会惨不忍睹。
Alain_Delone 2002-09-23
  • 打赏
  • 举报
回复
啊?不会吧,WINDOWS程序设计上说 CreateDIBSection创建的HBITMAP比较特别,难道Charles Pezold阴我?呵呵

你肯定吗?那我以前正是绕弯子了,想尽了办法搞成dib早知道我就用DDB了,唉
Alain_Delone 2002-09-23
  • 打赏
  • 举报
回复
哦,我没有画在FRAMEWND上,只是借它的DC 做CREATECOMPATIBLEDC的参数,我怕那时VIEW还没创建,现在图片能显示了,

但是我不知道该如何保存, 一般的标准代码都是打开DIB 文件然后又将DIB写回文件 ,我要先将屏幕上(或内存DC)上的东西写入一个DIB中,再将DIB写入文件,后者我有代码,关键是前者(将内存DC中的图写入一个DIB对象)该怎么弄?请各位指点
stonespace 2002-09-23
  • 打赏
  • 举报
回复
怎么会呢?

CreateCompatibleBitmap生成的HBITMAP hBitmap被SelectObject到dc后,在dc上画图也会反映到hBitmap上,msdn上的例子都是这样。
Alain_Delone 2002-09-23
  • 打赏
  • 举报
回复
是啊,可是这些方法返回的HBITMAP都是空的,没内容的啊,而且即使被SELECT进了 某个内存DC,并且在那个DC上画图或贴图,HBITMAP并不随DC变化啊
而用CREATEDIBSECTION 产生的HBITMAP 一旦被选如DC,是会随DC内容变化而变化的,所以我才要用它,这样可以将对DC的操作或改变反映到HBITMAP上,然后再存,
zhangxin123 2002-09-23
  • 打赏
  • 举报
回复
在DOC根本不用操作,在view的ondraw()中
CString filename;
filename=pDoc->GetPathName();
HBITMAP hBitmap=(HBITMAP)::LoadImage(NULL,filename,IMAGE_BITMAP,0,0,LR_LOADFROMFILE | LR_CREATEDIBSECTION);

if(hBitmap==NULL)
{
CString string;
string.Format(_T("%s does not contain a DIB"),lpszPathName);
AfxMessageBox(string);

return FALSE;
}

m_bitmap.Attach(hBitmap);
//
//return now if this device doesn't support palettes.
//

CClientDC dc (NULL);

if((dc.GetDeviceCaps(RASTERCAPS)& RC_PALETTE)==0) return TRUE;

//
//create a palette to go with the dib
//

if((HBITMAP)m_bitmap!=NULL)
{
DIBSECTION ds;
m_bitmap.GetObject(sizeof(DIBSECTION),&ds);

int nColors;
if(ds.dsBmih.biClrUsed!=0)
{
nColors=ds.dsBmih.biClrUsed;
}
else
{
nColors=1<< ds.dsBmih.biBitCount;
}
//
//create a halftone palette if the dib extend contains more
// than 256 colors.
//

if(nColors >256)
{
m_palette.CreateHalftonePalette(&dc);
}

//create a custom palette from the dib extend's color table
//if the number of colors is 256 or less.
//
else
{
RGBQUAD* pRGB=new RGBQUAD[nColors];

CDC memDC;
memDC.CreateCompatibleDC(&dc);
CBitmap *pOldBitmap=memDC.SelectObject(&m_bitmap);
::GetDIBColorTable((HDC)memDC,0,nColors,pRGB);
memDC.SelectObject(pOldBitmap);

UINT nSize=sizeof (LOGPALETTE)+(sizeof(PALETTEENTRY)*(nColors-1));

LOGPALETTE* pLP=(LOGPALETTE*)new BYTE[nSize];

pLP->palVersion=0x300;
pLP->palNumEntries=nColors;

for(int i=0;i<nColors;i++)
{
pLP->palPalEntry[i].peRed=pRGB[i].rgbRed;
pLP->palPalEntry[i].peGreen=pRGB[i].rgbGreen;
pLP->palPalEntry[i].peBlue=pRGB[i].rgbBlue;
pLP->palPalEntry[i].peFlags=0;
}

m_palette.CreatePalette(pLP);
delete[] pLP;
delete[] pRGB;
}
}

stonespace 2002-09-23
  • 打赏
  • 举报
回复
经典的方法是用CreateCompatibleBitmap创建内存bitmap,和CREATEDIBSECTION一样返回HBITMAP,参数少一些。那些编程的例子都是这么干。
Alain_Delone 2002-09-23
  • 打赏
  • 举报
回复
而是直接把内存dc的HBITMAP直接传入GetDIBits取出位图。这样做很简单,而且我试过,肯定行。

你说用内存DC的HBITMAP可是我DC里的内容是屏幕DC上贴上去的,而且尺寸会变的,所以在保存前我没有HBITMAP 对象和它关联啊,我哪来的HBITMAP参数来调用GETDIBBBITS 而且我不知道怎么创建一个 HBITMAP 里面能获得内存DC的位图信息而又不用CREATEDIBSECTION函数
stonespace 2002-09-23
  • 打赏
  • 举报
回复
用CreateDIBSection + GetDIBits行吗?如果这样我也修改自己的类,用这种方式不损失颜色。
stonespace 2002-09-23
  • 打赏
  • 举报
回复
我不用qq
加载更多回复(23)

16,472

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

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