如题,我读取并显示了一个位图,图像倾斜,并且很多划痕,看到论坛上有人说是4字节对齐问题,我不懂,希望有讲的深刻的,来教育下小弟原图:打开后:
解决方案 »
- accept正常,但是recv超时
- 我现在在写一个IM的软件,大家能推荐几本用VC写的服务器相关的书吗?要详尽点的!
- 如何将ActiveX控件中的右键菜单事件传递给主程序?
- DrawText显示文字的问题,求救
- 怎么样能让菜单里的一项比较醒目呢?
- 更换背景失败!
- Windows消息大全
- 帮忙读读这段代码,GetSystemMetrics(SM-CXFRAME);GetSystemMetrics(SM-CYSIZE);特别这两个函数!最好没行都加注释~不好意思,我的分布
- 进来有分!!!!!!!!!!!!
- 字体问题
- 我在view中添加了OnLButtonDblClk响应函数?
- 使用CRecordset派生类后Close函数时发生错误,求大神解决
BITMAPINFO bmpInfo;
bmpInfo.bmiHeader = bmpInfoHeader;
HBITMAP hBitmap = CreateDIBitmap(pDC->m_hDC,&bmpInfoHeader,CBM_INIT,m_pImageData,&bmpInfo,DIB_RGB_COLORS);
HBITMAP hOldBmp = m_Image_repaired.GetBitmap();
m_Image_repaired.SetBitmap(hBitmap);来显示,有问题的就是m_pImageData部分,我的对齐代码是int temp_Width = (m_orgWidth*3+3)/4*4;
int externWidth;
externWidth =temp_Width - m_orgWidth*3;
int sizeofbuffer = temp_Width * m_orgHeight;
int k = 0;
BYTE* m_pImageTempBuffer = new BYTE[sizeofbuffer];
for (int n = 1; n <= m_orgHeight ; n++)
{
k = 0;
for (int m = 0; m < m_orgWidth * 3; m += 3)
{
m_pImageTempBuffer[m_orgWidth*3*(m_orgHeight-n)+k] = pData[m_orgWidth*3*(m_orgHeight-n)+m]; //blue
m_pImageTempBuffer[m_orgWidth*3*(m_orgHeight-n)+k+1] = pData[m_orgWidth*3*(m_orgHeight-n)+m+1];//green
m_pImageTempBuffer[m_orgWidth*3*(m_orgHeight-n)+k+2] = pData[m_orgWidth*3*(m_orgHeight-n)+m+2];//red
k += 3;
}
for(m=0;m<externWidth;m++)
{
m_pImageTempBuffer[m_orgWidth*3*(m_orgHeight-n)+k]=255;
k++;
}
}
delete []pData;
pData = new BYTE[sizeofbuffer];
memcpy(pData, m_pImageTempBuffer, sizeofbuffer);
delete []m_pImageTempBuffer;,m_pImageData就赋值为上述函数返回的pData;
如果宽为5,则每行实际占15字节,buf的每行末位只补1个0x00//16-15=1,申请buf时候=4*2
如果宽为6,则每行实际占18字节,buf的每行末位只补2个0x00//20-18=2,申请buf时候=5*2
如果宽为7,则每行实际占21字节,buf的每行末位只补3个0x00//24-21=3,申请buf时候=6*2验证方法:用画图做一个1*5的纯白色24位图并存盘,然后用UltraEdit打开
如果宽为5,则每行实际占15字节,buf的每行末位只补1个0x00//16-15=1,申请buf时候=16*2
如果宽为6,则每行实际占18字节,buf的每行末位只补2个0x00//20-18=2,申请buf时候=20*2
如果宽为7,则每行实际占21字节,buf的每行末位只补3个0x00//24-21=3,申请buf时候=24*2
我们在开发过程中也用到了3楼的方法:
int temp_Width = (m_orgWidth*3+3)/4*4;
注册送积分活动开始了!!! 注册即送积分 50! 积分可兑换礼品、免费发信息,免费打广告...
乌海信息网: 免费发布各类 二手信息、房产交易信息、物品交易信息、征婚、 交友、免费查询,免费发布。
有你更精彩.......
int temp_Width = (m_orgWidth*3+3)/4*4;
int externWidth;
externWidth =temp_Width - m_orgWidth*3;
int sizeofbuffer = temp_Width * m_orgHeight;
//int k = 0;
BYTE* m_pImageTempBuffer = new BYTE[sizeofbuffer];
memset(m_pImageTempBuffer,0,sizeofbuffer);
for (int n = 1; n <= m_orgHeight ; n++)
{
//k = 0;
for (int m = 0; m < m_orgWidth * 3; m += 3)
{
m_pImageTempBuffer[temp_Width*(m_orgHeight-n)+m] = pData[m_orgWidth*3*(m_orgHeight-n)+m]; //blue
m_pImageTempBuffer[temp_Width*(m_orgHeight-n)+m+1] = pData[m_orgWidth*3*(m_orgHeight-n)+m+1];//green
m_pImageTempBuffer[temp_Width*(m_orgHeight-n)+m+2] = pData[m_orgWidth*3*(m_orgHeight-n)+m+2];//red
//k += 3;
}
//for(m=0;m<externWidth;m++)
//{
// m_pImageTempBuffer[m_orgWidth*3*(m_orgHeight-n)+k]=255;
// k++;
//}
}
delete []pData;
pData = new BYTE[sizeofbuffer];
memcpy(pData, m_pImageTempBuffer, sizeofbuffer);
delete []m_pImageTempBuffer;
注意这里有假设,如果你的pData是对齐的,就需将
m_pImageTempBuffer[temp_Width*(m_orgHeight-n)+m] = pData[m_orgWidth*3*(m_orgHeight-n)+m]; //blue
改成下面的
m_pImageTempBuffer[temp_Width*(m_orgHeight-n)+m] = pData[temp_Width*(m_orgHeight-n)+m]; //bluegreen、red类似处理你要清楚pData中的结构
这个东西要自己写一遍才好啊你真的验证了吗?
void CTestGdiDlg::OnBnClickedButton5()
{
// 打开bmp文件
HBITMAP hBitmap = (HBITMAP)LoadImageW(NULL, L"D:\\源图.bmp",IMAGE_BITMAP,0,0,LR_LOADFROMFILE);
if(hBitmap == NULL)
AfxMessageBox(L"LoadImage");
CBitmap *pBitmap = CBitmap::FromHandle(hBitmap); // 得到图片格式
BITMAP bmp_info;
pBitmap->GetBitmap(&bmp_info); // 解析得到24位图的BITMAPINFO
BITMAPINFO *pBITMAPINFO = (BITMAPINFO*)malloc(sizeof(BITMAPINFOHEADER));
memset(pBITMAPINFO, 0, sizeof(BITMAPINFOHEADER));
BITMAPINFOHEADER *pInfo_Header = (BITMAPINFOHEADER *)pBITMAPINFO;
pInfo_Header->biSize = sizeof(BITMAPINFOHEADER);
pInfo_Header->biWidth = bmp_info.bmWidth;
pInfo_Header->biHeight = bmp_info.bmHeight;
pInfo_Header->biPlanes = 1;
pInfo_Header->biBitCount = 24;
pInfo_Header->biCompression = BI_RGB; // 创建兼容DC 选定对象->位图
CDC dcCompatible;
dcCompatible.CreateCompatibleDC(NULL);
dcCompatible.SelectObject(pBitmap); // 把兼容DC贴到DC上
CDC *pCurDC = this->GetDC();
pCurDC->BitBlt(0,0,bmp_info.bmWidth, bmp_info.bmHeight,&dcCompatible,0,0,SRCCOPY); // 获得数据buf
// 4字节对齐 每行所占位数(bmWidth * 3)保证为4的倍数 注意不是像素(bmWidth)保证为4的倍数
DWORD bufSize = (bmp_info.bmWidth * 3 + 3) / 4 * 4 * bmp_info.bmHeight;
BYTE * pBuffer = new BYTE[bufSize];
if(GetDIBits(dcCompatible.GetSafeHdc(), hBitmap, 0, bmp_info.bmHeight, pBuffer,
pBITMAPINFO, DIB_RGB_COLORS) == 0)
{
AfxMessageBox(L"GetDIBits");
} // 建立文件
CFile file;
file.Open(L"D:\\新图.bmp", CFile::modeCreate | CFile::modeWrite | CFile::typeBinary); // 写文件头
BITMAPFILEHEADER File_Header;
File_Header.bfType = 0x4d42;
File_Header.bfOffBits = sizeof(BITMAPFILEHEADER) + pInfo_Header->biSize;
File_Header.bfSize = File_Header.bfOffBits + bufSize;
File_Header.bfReserved1 = 0;
File_Header.bfReserved2 = 0;
file.Write(&File_Header, sizeof(BITMAPFILEHEADER)); // 写数据头
file.Write(pInfo_Header, sizeof(BITMAPINFOHEADER)); // 写数据
file.Write(pBuffer, bufSize); // 关闭文件 释放内存
file.Close();
delete []pBuffer;
free(pBITMAPINFO);
::DeleteObject(hBitmap);
this->ReleaseDC(pCurDC);
}
#define WIDTHBYTES(bits) (((bits) + 31) / 32 * 4)
代码贴来看看,很简单的。
假设为灰度位图一个像素一个字节,一行如果是13个像素,那么要四字节对齐,申请空间时这一行要申请16个像素,最后三个像素空着。彩色图像一个像素占3个字节,情况一样。
主要是微软DIB显示的时候有这个限制
实在想不通还搞什么位图的四字节。
明明白白你给我300个值,然后我调用SetPixel输出就可以了。
这四个字节是为了什么而存在。
位图储存在硬盘上,也要补齐四个字节吗?,既然没有,输出也同样可以没有,什么补齐四个字节,我看它就是狗屁(虽然我知道这样做肯定有用),但没办法了,我没看到具体用在哪里,只能乱吼几句,也泄我心中的莫名其妙以及想不通,无奈。
还有什么分配内存的时候,每行多分配四个字节。
我用的是函数获取硬盘真彩位图的大小,再减54得到多少,就分配多少内存,然后再用ReadFile函数从54字节开始读位图全部的数据,这部分数据是怎么的呢,每行补齐四字节了吗?
按我所想的,应该每三个字节描述一个像素点,可是老是不对。