CSDN博客

img Cocoky

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

发表于2004/3/25 17:28:00  725人阅读

分类: C++文档

上一次看到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)

0 0

相关博文

我的热门文章

img
取 消
img