由BMP位图到各种图片格式的来源

这篇博客的内容是记录好久前所学习的知识的。

说下BMP的来源

BMP,也可以成为位图,位图所使用的颜色空间是RGB的,就是使用三原色来表示所有的颜色。

计算机无法真实的显示现实世界里面的所有颜色,所以需要模拟,而这个模拟就是将真实的图片细分一个一个点,细分的越多,就越接近真实的图片。

这点和微积分有点相似。而这一个个点,我们就称之为像素,既然引入了像素这个概念,我们就需要用一些颜色来描述这个像素,常见的有RGB颜色空间,除此之外还有YUV等颜色空间。


根据描述像素所使用的bit位数,又把所描述的位图成为单色位图,16色位图,256色位图,24位位图。

具体差异可见:http://blog.csdn.net/gwwgle/article/details/4879676


这里重点讲下24位位图,24位位图就是图片中每个像素点由24bit来描述,也就是一个像素点需要3个字节。

那么一个4 x 6的位图,所需要的内存就为 (4 * 6) * 3 = 72 byte,但是将该位图保存到文件中,还需要其他的一些描述信息,所以在windows上,我的测试结果为126byte.

具体的位图例子可在这里下载,如下图:



为了测试我使用了如下的代码:

在windows需要将该BMP图片里面像素数据取出来,可用如下方法:

void CTest48_Bitmap::OnPaint()
{
    CPaintDC dc(this);

    // Create a Bitmap object from a BMP file.
    Bitmap bitmap(_T("res/111.bmp"));

    PixelFormat bmpPixelFmt = bitmap.GetPixelFormat();
    if( bmpPixelFmt == PixelFormat24bppRGB ) {
        int a=2;
        int b=a;
    }

    // BD
    Color clr;
    bitmap.GetPixel(0, 0, &clr);
    
    BYTE byR = clr.GetR(); // 255
    BYTE byG = clr.GetG(); // 0
    BYTE byB = clr.GetB(); // 0
    COLORREF clrRef = clr.ToCOLORREF();
    // ED

    BitmapData bmpData;
    Rect rect(0, 0, bitmap.GetWidth(), bitmap.GetHeight());

    bitmap.LockBits(
        &rect,
        ImageLockModeWrite,
        bmpPixelFmt,
        &bmpData);

    // Write to the temporary buffer provided by LockBits.
    UINT* pixels = (UINT*)bmpData.Scan0;

    int byteCount = bmpData.Stride * bmpData.Height; // Stride为12;Height为6
    BYTE* pBuffer = new BYTE[byteCount];
    memcpy(pBuffer, pixels, byteCount);

    // BD
    BYTE by00[3];
    memcpy(by00, pixels, 3);
    // by00 结果为by00[0] = 0; by00[1] = 0; by00[2] = 255;
    
    // ED

    Bitmap bitmap22(
        bmpData.Width,
        bmpData.Height,
        bmpData.Stride,
        bmpData.PixelFormat,
        (BYTE*)bmpData.Scan0);
    
    delete []pBuffer;

    bitmap.UnlockBits(&bmpData);
}
其中Stride代表一行所占用的字节数,

一般情况下为12字节 == 4 × 3;4代表一行有4个像素,3代表每个像素占3个字节。



图片压缩

因为BMP图片几乎是以原始方式存放像素的,那么1024 * 768的一个24位纯色位图占用空间将是2.25M,而1024 × 768的纯色PNG占用空间仅为8KB。

不论是磁盘存储,还是网络传送。经过压缩的图片格式都比BMP尺寸,对同一个BMP具体能压缩到多小,除了跟压缩算法有关还和该图片的内容有一定的关系。


在压缩图片的时候,有的时候为了压缩率极大的提升,可能会是图片内容有些损失,因此叫有损压缩;相反还有无损压缩。

常见的图片格式有:bmp, png, jpg, gif, tiff等。

具体参见:http://blog.chinaunix.net/uid-22308080-id-1775280.html



题外话

不知道大家想过没有,视频其实也就是一副一副图片构成的,相邻2副图片之间可能只有小部分内容有变化,所有对于视频格式,又有了N多的视频编码标准。

但是大部分都是I, P, B帧来界定的。

I帧在我的概念里面就是一个全屏帧,是一个完整的图片,包括图片的各个细节。

后面的P, B就不一样,是和前后图片的内容相关的。


具体有什么区别,后面讲到视频编码格式的时候再说。







你可能感兴趣的:(由BMP位图到各种图片格式的来源)