您的位置:首页 > 其它

由内存对齐讨论想到位图旋转

2004-03-25 17:28 204 查看
上一次看到CSDN上讨论内存对齐问题,当时想这个现在已经

不太需要讨论了,已经由CPU解决了。当时上一次,我考虑一道

位图旋转问题的时候想到了这个问题。

下面把位图旋转的解决方法贴出来与大家共享:

void CRotateBitmapView::OnFileOpen()
{
//载入位图
CFileDialog dlg(TRUE,"BMP","*.bmp");
if(dlg.DoModal()!=IDOK)
return;
CFile file;
file.Open(dlg.GetFileName(), CFile::modeRead);
file.Read(&m_bfHeader, sizeof(BITMAPFILEHEADER));
int nSize = m_bfHeader.bfOffBits - sizeof(BITMAPFILEHEADER);
m_pBMPInfo = (LPBITMAPINFOHEADER) new char[nSize];
file.Read(m_pBMPInfo, nSize);

DWORD dwBitlen=m_bfHeader.bfSize - m_bfHeader.bfOffBits;
m_lpBMPSrcBits = (LPBYTE) new char[dwBitlen];
file.Read(m_lpBMPSrcBits, dwBitlen);
file.Close();
Invalidate(true);
}

//Rotate 90 degrees to the right
void CRotateBitmapView::OnTodoRight()
{
if(!m_lpBMPSrcBits)
return;
int i,j;
int newWidth=0;
switch(m_pBMPInfo->biBitCount)
{
case 1:
return;
case 4:
m_BitsSize = (((m_pBMPInfo->biHeight+1)/2+3)/4*4) * m_pBMPInfo->biWidth;
m_lpBMPDstBits = (LPBYTE) new char[m_BitsSize];
memset(m_lpBMPDstBits,0,m_BitsSize);
BYTE tempbyte;
//memset(&tempbyte,0,1);
tempbyte = 0;
m_lpBMPDstBitsCopy = m_lpBMPDstBits;
for (i=0; i < m_pBMPInfo->biWidth; i++)
{
//从该行最后一个象素向前
m_lpBMPSrcBitsCopy = m_lpBMPSrcBits + (m_pBMPInfo->biWidth+1)/2 - (i+2)/2;
m_lpBMPDstBits = m_lpBMPDstBitsCopy + i*(((m_pBMPInfo->biHeight+1)/2+3)/4*4);
for (j=0; j < m_pBMPInfo->biHeight; j++)
{
if(m_pBMPInfo->biWidth%2==0)
{
if((i+1)%2==1)
{
tempbyte = *m_lpBMPSrcBitsCopy;
tempbyte = tempbyte<<4;
tempbyte = tempbyte>>4;
if((j+1)%2==1)
tempbyte = tempbyte<<4;
*m_lpBMPDstBits = (*m_lpBMPDstBits)|tempbyte;
m_lpBMPSrcBitsCopy +=((m_pBMPInfo->biWidth+1)/2+3)/4*4 ;
}
else
{
tempbyte = *m_lpBMPSrcBitsCopy;
tempbyte = tempbyte>>4;
tempbyte = tempbyte<<4;
if((j+1)%2==0)
tempbyte = tempbyte>>4;
*m_lpBMPDstBits = (*m_lpBMPDstBits)|tempbyte;
m_lpBMPSrcBitsCopy +=((m_pBMPInfo->biWidth+1)/2+3)/4*4 ;
}
}
else
{
if((i+1)%2==1)
{
tempbyte = *m_lpBMPSrcBitsCopy;
tempbyte = tempbyte>>4;
tempbyte = tempbyte<<4;
if((j+1)%2==0)
tempbyte = tempbyte>>4;
*m_lpBMPDstBits = (*m_lpBMPDstBits)|tempbyte;
m_lpBMPSrcBitsCopy +=((m_pBMPInfo->biWidth+1)/2+3)/4*4 ;
}

else
{
tempbyte = *(m_lpBMPSrcBitsCopy-1);
tempbyte = tempbyte<<4;
tempbyte = tempbyte>>4;
if((j+1)%2==1)
tempbyte = tempbyte<<4;
*m_lpBMPDstBits = (*m_lpBMPDstBits)|tempbyte;
m_lpBMPSrcBitsCopy +=((m_pBMPInfo->biWidth+1)/2+3)/4*4 ;
}

}
if((j+1)%2==0)
m_lpBMPDstBits++;
}
}
break;
case 8:
m_BitsSize = ((m_pBMPInfo->biHeight+3)/4*4) * m_pBMPInfo->biWidth;
m_lpBMPDstBits = (LPBYTE) new char[m_BitsSize];
memset(m_lpBMPDstBits,0,m_BitsSize);
m_lpBMPDstBitsCopy = m_lpBMPDstBits;
for (i=1; i <= m_pBMPInfo->biWidth; i++)
{
//从该行最后一个象素向前
m_lpBMPSrcBitsCopy = m_lpBMPSrcBits + m_pBMPInfo->biWidth - i;
for (j=0; j < m_pBMPInfo->biHeight; j++)
{

memcpy(m_lpBMPDstBits++,m_lpBMPSrcBitsCopy,1);
m_lpBMPSrcBitsCopy +=(m_pBMPInfo->biWidth+3)/4*4 ;//到下一行
}
m_lpBMPDstBits += ((m_pBMPInfo->biHeight+3)/4*4) - m_pBMPInfo->biHeight;//到上一行
}
break;
case 24:
m_BitsSize = (m_pBMPInfo->biHeight*24+31)/32 * 4 * m_pBMPInfo->biWidth;
m_lpBMPDstBits = (LPBYTE) new char[m_BitsSize];
memset(m_lpBMPDstBits,0,m_BitsSize);
m_lpBMPDstBitsCopy = m_lpBMPDstBits;
for (i = 1; i <= m_pBMPInfo->biWidth; i++)
{
//从该行最后一个象素向前
m_lpBMPSrcBitsCopy = m_lpBMPSrcBits + m_pBMPInfo->biWidth * 3 - i * 3;
for (j = 0; j < m_pBMPInfo->biHeight; j++)
{
memcpy(m_lpBMPDstBits,m_lpBMPSrcBitsCopy,3);
m_lpBMPDstBits += 3;//下一像素
m_lpBMPSrcBitsCopy += (m_pBMPInfo->biWidth*24+31)/32*4;//旧图的下一行
}
m_lpBMPDstBits = m_lpBMPDstBitsCopy + (((m_pBMPInfo->biHeight*24+31)/32)*4)*i;//新图的下一行
}

break;
case 32:
break;
}
if (m_lpBMPSrcBits!=NULL)
{
delete m_lpBMPSrcBits;
m_lpBMPSrcBits = NULL;
}
m_lpBMPSrcBits = m_lpBMPDstBitsCopy;
newWidth=m_pBMPInfo->biHeight;
m_pBMPInfo->biHeight = m_pBMPInfo->biWidth;
m_pBMPInfo->biWidth = newWidth;
Invalidate(true);

}

void CRotateBitmapView::OnDraw(CDC* pDC)
{
CRotateBitmapDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
//////////////////////////////////////////////////

if (m_lpBMPSrcBits != NULL)
{
StretchDIBits(pDC->GetSafeHdc(),50,50,m_pBMPInfo->biWidth,m_pBMPInfo->biHeight,
0, 0, m_pBMPInfo->biWidth, m_pBMPInfo->biHeight,
m_lpBMPSrcBits, (LPBITMAPINFO)m_pBMPInfo,
DIB_RGB_COLORS, SRCCOPY);
}
}

我上一个贴字的地址为:http://www.csdn.net/Develop/read_article.asp?id=24769

大家有什么意见也可以和我讨论。

我的信箱是:sunqing_nt@hotmail.com(也是我的msn)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: