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

原创 2004年03月25日 17:28:00

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

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

由内存对齐讨论想到位图旋转上一次看到CSDN上讨论内存对齐问题,当时想这个现在已经不太需要讨论了,已经由CPU解决了。当时上一次,我考虑一道位图旋转问题的时候想到了这个问题。下面把位图旋转的解决方法贴...
  • songtitan
  • songtitan
  • 2004年11月01日 18:16
  • 637

HBITMAP对位图数据存储的字节对齐

HBITMAP是常用的GDI对象,而GetDIBits可以从一个HBITMAP对象中获得其对应的位数据。其原型如下:int GetDIBits(    HDC hdc, // ha...
  • ConeZXY
  • ConeZXY
  • 2007年05月30日 14:39
  • 4097

由忧郁想到的

忧郁说的:有道德有文化有理想 为何没钱呢?而我认为:因为没有实力,没有学历没有资历,没有压力,没有动力,没有创造力,没有适应力,没有魄力,没有魅力,没有执行力,没有影响力!...
  • jasword
  • jasword
  • 2004年12月29日 04:07
  • 488

由玩游戏想到的

怎样才能快速上手一个游戏? 怎样才能快速掌握
  • ylfdrib
  • ylfdrib
  • 2014年04月13日 12:17
  • 446

由小游戏跳一跳想到的

元旦放假那天回家,一路上看到好多人都在玩那个游戏,感觉好巧啊,怎么都玩一个游戏。后来回到 家把微信更新了版本,赫然发发现了这个跳一跳的小游戏,玩了几次,最高玩到100多分,就没再玩了。 元旦回来上班...
  • zwl1584671413
  • zwl1584671413
  • 2018年01月04日 11:00
  • 121

由雪想到。。。。

大连今日降雪,飘飘洒洒,浑然天地。望着窗外,心有所想。。。想到了,川端康成的>;想到了,令狐冲在思过崖;想到了,香雪涧和晚来天欲雪,能饮一杯无?更想到了故乡的八景之"红崖积雪"......红崖积雪 红...
  • dragondwy
  • dragondwy
  • 2008年12月05日 12:06
  • 369

DIB(设备无关位图)旋转任意角度算法(单色位图)

网上很多位图旋转的程序,但是一般都是8位、24位、32位位图的旋转,这些大于8位的位图每个像素都可以用整个字节表示,所以用char数组很容易实现对应像素复制。但是要对单色位图进行旋转的话,就涉及到按位...
  • wangwenjing90
  • wangwenjing90
  • 2013年04月18日 10:09
  • 2357

VC MFC GDI 位图旋转算法

Function 1 newx = x.cos(angle) + y.sin(angle) newy = y.cos(angle) - x.sin(angle) 是以位图左上角为原点逆时针旋...
  • victorandroid
  • victorandroid
  • 2011年11月22日 16:35
  • 569

MFC下对位图的旋转

开始做一个项目,需要在MFC下旋转一个位图。遍寻网上各种资源,把代码copy下来发现不能用,悲催至极。           还有就是网上给出的很多代码本身有很多变量和项目工程有关,有关变量不够明确。...
  • tashengjinsheng
  • tashengjinsheng
  • 2017年03月17日 16:05
  • 783

as3对应照片信息旋转的修正

很多时候数码设备的照片旋转并不是像素本身的旋转, 而只是给照片增加了个Orientation...
  • zszeng
  • zszeng
  • 2014年07月08日 13:39
  • 714
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:由内存对齐讨论想到位图旋转
举报原因:
原因补充:

(最多只允许输入30个字)