WEB开发网
开发学院软件开发VC TIF格式图像文件初探 阅读

TIF格式图像文件初探

 2009-10-27 20:31:22 来源:WEB开发网   
核心提示:回到OnOpenDocument成员函数中调用工具函数并获得全局内存块指针//构造BMP图象内存块if(!CreateBmpBuffer()){AfxMessageBox("构造BMP图象内存块失败");delete []pde;return FALSE;}//获得BMP内存块指针pDIB = (B

回到OnOpenDocument成员函数中调用工具函数并获得全局内存块指针

//构造BMP图象内存块
  if(!CreateBmpBuffer())
  {
    AfxMessageBox("构造BMP图象内存块失败");
    delete []pde;
    return FALSE;
  }
  //获得BMP内存块指针
  pDIB = (BYTE*)GlobalLock(m_hDIB);
  if(NULL == pDIB)
  {
    AfxMessageBox("获得BMP内存块指针失败");
    GlobalUnlock(m_hDIB);
    delete []pde;
    return FALSE;
  }  

以下是将图像信息填充到BMP内存块中,网上介绍BMP格式的文章很多,这里就不详述了。因测试图像数据表达的是0x00-0xff灰度,正好和BMP文件调色板索引值巧合。 故在代码中直接把图像数据信息当成索引即可,减少了编码复杂度。注:BMP文件中图像数据的第一行代表的是最终显示光栅的最后一行,所以在数据排列中要颠倒过来。

//构造BITMAPFILEHEADER并复制到BMP内存块
  BITMAPFILEHEADER bmfHdr;
  memset(&bmfHdr, 0, sizeof(BITMAPFILEHEADER));
  bmfHdr.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) +
            256*sizeof(RGBQUAD);
  bmfHdr.bfReserved1 = 0;
  bmfHdr.bfReserved2 = 0;
  bmfHdr.bfSize = bmfHdr.bfOffBits + m_dwBmSize;
  bmfHdr.bfType = 0x4d42;
  memmove(pDIB, &bmfHdr, sizeof(BITMAPFILEHEADER));
  
  //构造BITMAPINFOHEADER并复制到BMP内存块
  BITMAPINFOHEADER bmiHdr;
  memset(&bmiHdr, 0, sizeof(BITMAPINFOHEADER));
  bmiHdr.biBitCount = 8;
  bmiHdr.biClrImportant = 0;
  bmiHdr.biClrUsed = 0;
  bmiHdr.biCompression = 0;
  bmiHdr.biHeight = m_sizeDoc.cy;
  bmiHdr.biPlanes = 1;
  bmiHdr.biSize = sizeof(BITMAPINFOHEADER);
  bmiHdr.biSizeImage = 0;
  bmiHdr.biWidth = m_sizeDoc.cx;
  bmiHdr.biXPelsPerMeter = 2834;
  bmiHdr.biYPelsPerMeter = 2834;
  
  memmove((BITMAPFILEHEADER*)pDIB + 1, &bmiHdr, sizeof(BITMAPINFOHEADER));
  //构造256个RGBQUAD并复制到BMP内存块
  RGBQUAD* pRgbQuad = (RGBQUAD*)(pDIB + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER));
  RGBQUAD* pOldQuad = pRgbQuad;
  RGBQUAD rgbQuad;
  memset(&rgbQuad, 0, sizeof(RGBQUAD));
  for(i=0; i<256; i++)
  {
    rgbQuad.rgbBlue = i;
    rgbQuad.rgbGreen = i;
    rgbQuad.rgbRed = i;
    rgbQuad.rgbReserved = 0;
    pRgbQuad = pOldQuad + i;
    memmove(pRgbQuad, &rgbQuad, sizeof(RGBQUAD));
  }
  //填充所有像素数据, 颠倒图象数据从最后一行开始读起
  int j = 0;
  for(i=m_sizeDoc.cy-1; i>=0; i--)
  {
    file.Seek(sizeof(IFH) + i*m_sizeDoc.cx, CFile::begin);
    file.Read((BYTE*)(pRgbQuad + 1) + j*m_sizeDoc.cx, m_sizeDoc.cx);
    j++;
  }  

初始化BMP调色板,为显示BMP文件做准备

//初始化专用调色板
  BYTE buf[2+2+4*256];
  LOGPALETTE* pPal = (LOGPALETTE*)buf;
  pPal->palVersion = 0x300;
  pPal->palNumEntries = 256;
  for(i=0; i<255; i++)
  {
    pPal->palPalEntry[i].peBlue = i;
    pPal->palPalEntry[i].peFlags = 0;
    pPal->palPalEntry[i].peGreen = i;
    pPal->palPalEntry[i].peRed = i;
  }
  m_palDIB.CreatePalette(pPal);

最后是OnOpenDocument成员函数返回前的清理工作

GlobalUnlock(m_hDIB);
  delete []pde;
  return TRUE;

至此,TIF文件信息已转换为BMP图像并保存在全局内存块中了,接下来就可以在OnDraw中调用WinAPI函数StretchDIBits来显示它。

if(NULL == pDoc->m_hDIB)
  {
    return;
  }
  HDC hdc = pDC->m_hDC;
  BYTE* pBuf = (BYTE*)GlobalLock(pDoc->m_hDIB);
  pBuf += sizeof(BITMAPFILEHEADER);
  BYTE* pData = pBuf + sizeof(BITMAPINFOHEADER) + 256*sizeof(RGBQUAD);
  
  CPalette* pOldPal = pDC->SelectPalette(&pDoc->m_palDIB, TRUE);
  pDC->RealizePalette();
  ::SetStretchBltMode(hdc, COLORONCOLOR);
  ::StretchDIBits(hdc, 10, 10, pDoc->m_sizeDoc.cx, pDoc->m_sizeDoc.cy,
    0, 0, pDoc->m_sizeDoc.cx, pDoc->m_sizeDoc.cy, pData,
    (BITMAPINFO*)pBuf, DIB_RGB_COLORS, SRCCOPY);
  pDC->SelectPalette(pOldPal, FALSE);
  GlobalUnlock(pDoc->m_hDIB);

最后别忘了在文档类析构函数~CTiffTestDoc中销毁全局内存块

if(NULL != m_hDIB)
  {
    GlobalFree(m_hDIB);
    m_hDIB = NULL;
  }

四、结束语

测试用的TIF文件在工程目录下,文件名为SSS00.TIF。本人学习图形图像编程不久,文章难免挂一漏万,请高手指教。

上一页  1 2 3 

Tags:TIF 格式 图像

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接