这段带码只对有的图可以,有的图就是斜的,灰的,还有串位的,应真么改啊void CBitmap2View::OnDraw(CDC* pDC)
{
CBitmap2Doc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here
if(str!=""){ //str是文件名
CWnd *m_pMainWnd;
m_pMainWnd = AfxGetMainWnd();
m_pMainWnd->SetWindowText("显示图片");//改变窗口标题 CFile cf;//文件变量,用来对文件操作
CFileException e;//出错处理
BITMAPFILEHEADER bmfh;//BMP文件头变量
BITMAPINFOHEADER bmih;//BMP文件信息变量
RGBTRIPLE *rgb;//24位真彩色数据格式
if (!cf.Open((LPCTSTR)str,CFile::modeRead, &e))//找到文件后,打开文件
{
MessageBox("Can not open the file!","24Open File");
return;
}
cf.SeekToBegin();
cf.Read(&bmfh,sizeof(bmfh));//读取文件头
cf.Read(&bmih,sizeof(bmih));//读取文件信息头
TRACE("\n%d\n",bmih.biBitCount);
rgb = new RGBTRIPLE[bmih.biWidth*bmih.biHeight];
cf.SeekToBegin();
cf.Seek(54,CFile::begin);//bmp图,54字节后为象素数据 //读取文件数据
if (cf.GetLength()>64*1024)
{
cf.ReadHuge(rgb,bmih.biWidth*bmih.biHeight*3);
}
else
{
cf.Read(rgb,bmih.biWidth*bmih.biHeight);
}
// cf.Read(rgb,bmih.biHeight*dwBytes);
//在屏幕上打点显示图像
for (int i=0; i<bmih.biHeight;i++)
{
for (int j=0; j<bmih.biWidth; j++)
{
pDC->SetPixel(j,bmih.biHeight-i,RGB(rgb[i*bmih.biWidth+j].rgbtRed,rgb[i*bmih.biWidth+j].rgbtGreen,rgb[i*bmih.biWidth+j].rgbtBlue));
}
} cf.Close();//关闭文件
delete rgb;//释放内存
pDC->TextOut(0,0,"24位真彩色图!");
ReleaseDC(pDC);
}
}
{
CBitmap2Doc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here
if(str!=""){ //str是文件名
CWnd *m_pMainWnd;
m_pMainWnd = AfxGetMainWnd();
m_pMainWnd->SetWindowText("显示图片");//改变窗口标题 CFile cf;//文件变量,用来对文件操作
CFileException e;//出错处理
BITMAPFILEHEADER bmfh;//BMP文件头变量
BITMAPINFOHEADER bmih;//BMP文件信息变量
RGBTRIPLE *rgb;//24位真彩色数据格式
if (!cf.Open((LPCTSTR)str,CFile::modeRead, &e))//找到文件后,打开文件
{
MessageBox("Can not open the file!","24Open File");
return;
}
cf.SeekToBegin();
cf.Read(&bmfh,sizeof(bmfh));//读取文件头
cf.Read(&bmih,sizeof(bmih));//读取文件信息头
TRACE("\n%d\n",bmih.biBitCount);
rgb = new RGBTRIPLE[bmih.biWidth*bmih.biHeight];
cf.SeekToBegin();
cf.Seek(54,CFile::begin);//bmp图,54字节后为象素数据 //读取文件数据
if (cf.GetLength()>64*1024)
{
cf.ReadHuge(rgb,bmih.biWidth*bmih.biHeight*3);
}
else
{
cf.Read(rgb,bmih.biWidth*bmih.biHeight);
}
// cf.Read(rgb,bmih.biHeight*dwBytes);
//在屏幕上打点显示图像
for (int i=0; i<bmih.biHeight;i++)
{
for (int j=0; j<bmih.biWidth; j++)
{
pDC->SetPixel(j,bmih.biHeight-i,RGB(rgb[i*bmih.biWidth+j].rgbtRed,rgb[i*bmih.biWidth+j].rgbtGreen,rgb[i*bmih.biWidth+j].rgbtBlue));
}
} cf.Close();//关闭文件
delete rgb;//释放内存
pDC->TextOut(0,0,"24位真彩色图!");
ReleaseDC(pDC);
}
}
解决方案 »
- 关于项目管理??
- 创建位图无法打开问题
- 用Visual studio 2010编写如下程序,运行成功,但出不了自己想要的结果,求原因,谢谢
- 封闭开发结束,透透气
- 新问题出炉---如何解决USEkey插入时让程序即时运行
- 哪有BoundsChecker7.1下载呀?
- 哪里有 Programming Applications for Microsoft Windows by Jeffrey Richter (4th ed., Microsoft Press, 1999)
- 编译和打包的问题,请指教。
- 谁用过网络蚂蚁或金山词霸.NET,它们的对话框是从屏幕中间扩大出来的,怎么实现?
- 在Edit Control中连续打开两个以上的文件粘贴在一起
- 怎样知道一个窗口停止响应了
- 问一个菜鸟的问题?
注意到这个就应该不是斜的了!!#define WIDTHBYTES(bits) (((bits) + 31) / 32 * 4)
另外,位图数据中的一行的字节宽度并不是简单的表示为图像的宽度乘像素结构的大小,而是能被4倍整除的最接近width*sizeof(RGB),用宏 WIDTHBYTES(bits)得到;
关于DIB位图的操作请使用MFC提供的API函数库 其定义在MSDN例子:DIBLOOK 中的dibapi.h,DIBAPI.CPP,myfile.cpp三个文件中.
还有,在显示位图的时候,不要使用SetPixel(),效率太低,而应当使用API函数SetDIBitsToDevice()具体参数,请查找MSDN
LPBITMAPFILEHEADER lpfh = (LPBITMAPFILEHEADER)pBuf;
LPBITMAPINFOHEADER lpih = (LPBITMAPINFOHEADER)(pBuf+sizeof(*lpfh));
DWORD noRowLength = ((lpih->biWidth*lpih->biBitCount+31)&~31)>>3;
这样得到的才是每行的字节数。
然后利用位图结构找到像素数据。
注意24位的图象没有颜色表,你读颜色表里的会出错的,直接读就可以了,自己
用SetPixel()计算bgr顺序的颜色值,记得是bgr不是rgb.
还有保证每一行是四的整数倍!!
先计算其实际的大小:
DWORD noRowLength = ((lpih->biWidth*lpih->biBitCount+31)&~31)>>3
用 noRowLength代替bmih.biWidth就可以了
我这么改的DWORD noRowLength = ((bmih.biWidth*bmih.biBitCount+31)&~31)>>3;
bmih.biWidth=noRowLength;
for (int i=0; i<bmih.biHeight;i++)
{
for (int j=0; j<bmih.biWidth; j++)
{
pDC->SetPixel(j,bmih.biHeight-i,RGB(rgb[i*bmih.biWidth+j].rgbtRed,rgb[i*bmih.biWidth+j].rgbtGreen,rgb[i*bmih.biWidth+j].rgbtBlue));
}
不行!然后我又这样改DWORD noRowLength = ((bmih.biWidth*bmih.biBitCount+31)&~31)>>3;
bmih.biWidth=noRowLength;
if (cf.GetLength()>64*1024)
{
cf.ReadHuge(rgb,bmih.biWidth*bmih.biHeight*3);//
}
else
{
cf.Read(rgb,bmih.biWidth*bmih.biHeight);
}
for (int i=0; i<bmih.biHeight;i++)
{
for (int j=0; j<bmih.biWidth; j++)
{
还是不行啊
=============================================
void CBitmap2View::ReadAndShow(CDC* pDC,CString& BmpName)
{
CFile file;
if(!file.Open(BmpName,CFile::modeRead))
return;
DWORD dwStart = file.GetPosition();
BITMAPFILEHEADER bmfh;
BITMAPINFOHEADER bmih;
//以下为了方便,省略鉴定..(要鉴定可自己加上)
file.Read(&bmfh,sizeof(BITMAPFILEHEADER));
file.Read(&bmih,sizeof(BITMAPINFOHEADER));
//计算24Bit图象位数据大小
DWORD dwLen = bmfh.bfSize - bmfh.bfOffBits;
//申请内存空间
BYTE *pData = (BYTE *)malloc(dwLen);
if(!pData)
return;
//读入位数据
file.Seek(dwStart + bmfh.bfOffBits,CFile::begin)
file.ReadHuge(pData,dwLen);
file.Close();
//建一幅空白hbitmap
void *pBits;
HBITMAP hBitmap = CreateDIBSection(pDC->m_hDC,(CONST BITMAPINFO *)&bmih,
DIB_RGB_COLORS,&pBits,NULL,0);
//copy bits data
memcpy(pBits,pData,dwLen);
GdiFlush();
free(pData);
//now ok..attach to CBitmap then show it..
CDC *m_pMemDC = new CDC;
m_pMemDC->CreateCompatibleDC(pDC);
CBitmap Bitmap,*pOldBitmap;
Bitmap.Attach(hBitmap);
pOldBitmap = m_pMemDC->SelectObject(&Bitmap);
//show it..
pDC->BitBlt(0,0,bmih.biWidth,bmih.biHeight,m_pMemDC,0,0,SRCCOPY);
//玩完,释放..
m_pMemDC->SelectObject(pOldBitmap);
Bitmap.Detach();
delete m_pMemDC;
DeleteObject(hBitmap);
//ok,good luck,byebye~~~
//夜渐已深..驱不散,星光引路催促归家,但是我心......
}
只是……
这个程序很难吗,没人能改好吗?
=======================
//在:rgb = new RGBTRIPLE[bmih.biWidth*bmih.biHeight];
//这句前面加上判断就ok.. //计算Bmp扫描行字节数
DWORD BytesPerLine = bmih.biWidth * 3;
if(BytesPerrLine % 4 != 0)
BytesPerLine = (BytesPerLine / 4 + 1) * 4;//四字节对齐;
DWORD dwLen = BytesPerLine * bmih.biHeight;
rgb = new RGBTRIPLE[dwLen];
//..............
//.........
不过,用这个结构来读,确实比较麻烦,因为需四字节对齐,而这个结构是3字节的。
试改如下:
================================================ //计算Bmp扫描行字节数
DWORD BytesPerLine = bmih.biWidth * 3;
if(BytesPerLine % 4 != 0)
BytesPerLine = (BytesPerLine / 4 + 1) * 4;//四字节对齐;
DWORD dwLen = BytesPerLine * bmih.biHeight;
//申请内存空间
BYTE *pData = (BYTE *)malloc(dwLen);
if(!pData)
return;
cf.SeekToBegin();
cf.Seek(54,CFile::begin);//bmp图,54字节后为象素数据
cf.ReadHuge(pData,dwLen);//先一次读入到内存,然后再转换到RGBTRIPLE数组 rgb = new RGBTRIPLE[bmih.biWidth*bmih.biHeight];//原来的这句是正确的
//转换
BYTE *pLine = NULL;
BYTE *pDesLine = NULL; for(int Q = 0;Q < bmih.biHeight;++Q)
{
//copy one scanline
pLine = &pData[Q * BytesPerLine];
pDesLine = &((BYTE *)rgb)[Q * bmih.biWidth];
memcpy(pDesLine,pLine,bmih.biWidth * 3);
}
free(pData); //然后
for (int i=0; i<bmih.biHeight;i++)
{
for (int j=0; j<bmih.biWidth; j++)
{
//.............=========================================================
这次应该没读取错误了,keke..
没办法,偶几乎不使用RGBTRIPLE
BYTE *pDesLine = NULL; for(int Q = 0;Q < bmih.biHeight;++Q)
{
//copy one scanline
pLine = &pData[Q * BytesPerLine];
pDesLine = &((BYTE *)rgb)[Q * bmih.biWidth * 3];//?强制转换需乘3?
//kaka~~偶也蒙了,讨厌的RGBTRIPLE >_<
memcpy(pDesLine,pLine,bmih.biWidth * 3);
}
cf.Seek(54,CFile::begin);//bmp图,54字节后为象素数据
cf.ReadHuge(pData,dwLen);//
这句错了,
谢谢各位了,
尤其是lambochan(打杂),谢谢你了