zoukankan      html  css  js  c++  java
  • 位图对齐及格式

    http://baike.baidu.com/view/189487.htm

    有关RGB三色空间我想大家都很熟悉,这里我想说的是在Windows下RGB颜色阵列存储的格式其实BGR。也就是说,对于24位的RGB位图像素数据格式是:

    蓝色B值 绿色G值 红色R值

    对于32位的RGB位图像素数据格式是:

    蓝色B值 绿色G值 红色R值 透明通道A值

    透明通道也称Alpha通道,该值是该像素点的透明属性,取值在0(全透明)到255(不透明)之间。对于24位的图像来说,因为没有Alpha通道,故整个图像都不透明。

    由于Windows在进行行扫描的时候最小的单位为4个字节,所以当
    图片宽 X 每个像素的字节数 != 4的整数倍
    时要在每行的后面补上缺少的字节,以0填充(一般来说当图像宽度为2的幂时不需要对齐)。位图文件里的数据在写入的时候已经进行了行对齐,也就是说加载的时候不需要再做行对齐。但是这样一来图片数据的长度就不是:宽 X 高 X 每个像素的字节数了,我们需要通过下面的方法计算正确的数据长度:
    //Calculate the image data size
    int iLineByteCnt = (((m_iImageWidth*m_iBitsPerPixel) + 3) >> 2) << 2;
    m_iImageDataSize = iLineByteCnt * m_iImageHeight;

    3D(OpenGL)的不同之处
    如果你是想用刚才我们得到的数据生成纹理对象,那么你还要请出下面的问题。
    首先,用来生成纹理的数据不需要对齐,也就是说不能在每行的后面加上对齐的字节。当然在OpenGL里要求纹理图片的尺寸为2的幂,所以这个问题实际上不存在;
    其次,我们得到的图形数据格式是BGR(BGRA),所以在生成纹理的时候,需指定格式为GL_BGR_EXT(GL_BGRA_EXT);否则需要做BGR->RGB(BGRA->RGBA)的转化。

    ------------------------------------------

    1、加载文件头
    //Load the file header
    BITMAPFILEHEADER header;
    memset(&header,0,sizeof(header));
    inf.read((char*)&header,sizeof(header));
    if(header.bfType != 0x4D42)
    return false;
    这个很简单,没有什么好说的。
    2、加载位图信息头
    //Load the image information header
    BITMAPINFOHEADER infoheader;
    memset(&infoheader,0,sizeof(infoheader));
    inf.read((char*)&infoheader,sizeof(infoheader));
    m_iImageWidth = infoheader.biWidth;
    m_iImageHeight = infoheader.biHeight;
    m_iBitsPerPixel = infoheader.biBitCount;
    这里我们得到了3各重要的图形属性:宽,高,以及每个像素颜色所占用的位数。
    3、行对齐
    由于Windows在进行行扫描的时候最小的单位为4个字节,所以当
    图片宽 X 每个像素的字节数 != 4的整数倍
    时要在每行的后面补上缺少的字节,以0填充(一般来说当图像宽度为2的幂时不需要对齐)。位图文件里的数据在写入的时候已经进行了行对齐,也就是说加载的时候不需要再做行对齐。但是这样一来图片数据的长度就不是:宽 X 高 X 每个像素的字节数了,我们需要通过下面的方法计算正确的数据长度:
    //Calculate the image data size
    int iLineByteCnt = (((m_iImageWidth*m_iBitsPerPixel) + 3) >> 2) << 2;
    m_iImageDataSize = iLineByteCnt * m_iImageHeight;
    4、加载图片数据
    对于24位和32位的位图文件,位图数据的偏移量为sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER),也就是说现在我们可以直接读取图像数据了。
    if(m_pImageData) delete []m_pImageData;
    m_pImageData = new unsigned char[m_iImageDataSize];
    inf.read((char*)m_pImageData,m_iImageDataSize);
    如果你足够细心,就会发现内存m_pImageData里的数据的确是BGR格式,可以用个纯蓝色或者是纯红色的图片测试一下。
    5、绘制
    好了,数据和属性我们都有了,现在就可以拿来随便用了,就和吃馒头一样,爱粘白糖粘白糖,爱粘红糖粘红糖。下面是我的GDI绘制代码,仅作参考。
    void CImage::DrawImage(HDC hdc,int iLeft,int iTop,int iWidth,int iHeight)
    {
    if(!hdc || m_pImageData == NULL)
    return;
    BITMAPINFO bmi;
    memset(&bmi,0,sizeof(bmi));
    bmi.bmiHeader.biSize = sizeof(BITMAPINFO);
    bmi.bmiHeader.biWidth = m_iImageWidth;
    bmi.bmiHeader.biHeight = m_iImageHeight;
    bmi.bmiHeader.biPlanes = 1;
    bmi.bmiHeader.biBitCount = m_iBitsPerPixel;
    bmi.bmiHeader.biCompression = BI_RGB;
    bmi.bmiHeader.biSizeImage = m_iImageDataSize;
    StretchDIBits(hdc,iLeft,iTop,iWidth,iHeight,
    0,0,m_iImageWidth,m_iImageHeight,
    m_pImageData,&bmi,DIB_RGB_COLORS,SRCCOPY);
    }

  • 相关阅读:
    poj 2728 Desert King
    uva 439 Knight Moves
    hdu 1875 畅通工程再续
    scau实验题 8600 骑士周游问题(有障碍物)
    scau实验题 8596 Longest Ordered Subsequence
    poj 1679 The Unique MST
    uva 527 Oil Deposits
    poj 2533 Longest Ordered Subsequence
    .net 程序员 java 开发入门
    Collation conflict occur at operation on User define funtion & table's column
  • 原文地址:https://www.cnblogs.com/dearplain/p/2869914.html
Copyright © 2011-2022 走看看