在哪里可以找到 24 位位图图像 RLE 的示例

Where can I find example of 24 bit bitmap image RLE

本文关键字:RLE 图像 位图 在哪里      更新时间:2023-10-16

我知道使用 RLE 可能无法很好地压缩 24 位位图图像。但是,我用VHDL编写了一个数字电路,将VGA信号发送到显示器。在测试平台中,我想写下图像数据,然后使用C程序将其转换为位图文件。由于每个图像的大小为 800x600,因此最好压缩文件,这将显着减少文件。位图格式支持运行长度编码压缩。

(1)我寻找过RLE的例子。但是,我找不到任何 24 位位图图像。你能举个例子吗?或者。是否有应用程序可以帮助我保存 24 位位图文件,以便我可以使用十六进制编辑器并了解如何保存格式?

(二)此外,互联网上随处可见的RLE的唯一示例如下:

03 04 05 06 00 03 45 56 67 00 02 78 00 02 05 01
02 78 00 00 09 1E 00 01

此位图将按如下方式展开(两位数值表示单个像素的颜色索引):

04 04 04
06 06 06 06 06
45 56 67
78 78
move current position 5 right and 1 down
78 78
end of line
1E 1E 1E 1E 1E 1E 1E 1E 1E
end of RLE bitmap

为什么 45 56 67 只扩展到同一件事?

好的,我了解如何编写 24 位 RLE。我已经编写了该程序,但是paint-it无法识别由它生成的文件。我不确定我的机器上的paint-it和其他应用程序是否无法识别24位RLE位图,或者我的程序生成的位图文件是错误的。因此:

#include <iostream>
#include <Windows.h>
#include <fstream>
#include <time.h>
using namespace std;
#pragma pack(push)
#pragma pack(1)
struct bitmap_file_header_struct {
    WORD    bfType;        // must be 'BM' 
    DWORD   bfSize;        // size of the whole .bmp file
    WORD    bfReserved1;   // must be 0
    WORD    bfReserved2;   // must be 0
    DWORD   bfOffBits;
} bitmap_file_header;
struct bitmap_file_info_struct {
    DWORD  biSize;            // size of the structure
    LONG   biWidth;           // image width
    LONG   biHeight;          // image height
    WORD   biPlanes;          // bitplanes
    WORD   biBitCount;        // resolution 
    DWORD  biCompression;     // compression
    DWORD  biSizeImage;       // size of the image
    LONG   biXPelsPerMeter;   // pixels per meter X
    LONG   biYPelsPerMeter;   // pixels per meter Y
    DWORD  biClrUsed;         // colors used
    DWORD  biClrImportant;    // important colors
} bitmap_file_info;
#pragma pack(pop)
int main()
{
    // image is 10 repeating pixels of value ff00ff followed by end of scaneline and end of rle
    unsigned char data[] = { 0x0A, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x01}; 
    bitmap_file_header.bfType = 0x4d42; // fixed for bitmap in windows
    bitmap_file_header.bfSize = sizeof(bitmap_file_header) + sizeof(bitmap_file_info) + sizeof(data); 
    bitmap_file_header.bfReserved1 = 0; // fixed 
    bitmap_file_header.bfReserved2 = 0; // fixed
    bitmap_file_header.bfOffBits = sizeof(bitmap_file_header) + sizeof(bitmap_file_info); //
    bitmap_file_info.biSize = sizeof(bitmap_file_info);
    bitmap_file_info.biWidth = 10;
    bitmap_file_info.biHeight = 1;
    bitmap_file_info.biPlanes = 1; // fixed
    bitmap_file_info.biBitCount = 24; // fixed for 24 bit image
    bitmap_file_info.biCompression = 4; // fixed, 4 used to set 24 bit run length encoding
    bitmap_file_info.biSizeImage = sizeof(data); // <-
    bitmap_file_info.biXPelsPerMeter = 0; // fixed
    bitmap_file_info.biYPelsPerMeter = 0; // fixed
    bitmap_file_info.biClrUsed = 0; // all colors used
    bitmap_file_info.biClrImportant = 0; // all colors are important
    std::ofstream myfile;
    myfile.open("output.bmp", ios::out | ios::binary);
    myfile.write((const char *)&bitmap_file_header, sizeof(bitmap_file_header));
    myfile.write((const char *)&bitmap_file_info, sizeof(bitmap_file_info));
    myfile.write((const char *)&data, sizeof(data));
    myfile.close(); 
    return 0;
}

RLE 的最基本形式由 <count> <value> 形式的字节对(或帧)组成。 显然,在这种形式中,您永远不会有一个零的<count>字节。

这允许使用零作为控制代码,在数据中发出不同类型的帧的信号。

您的特定示例已使用 WMF(Windows Meta File)RLE 格式进行编码。 WMF 允许以下额外类型的帧,所有这些帧都必须使用 00 控制代码引入:

  • 01 - 数据流结束
  • 02 <x> <y> - 相对移动
  • 03 <raw uncompressed data stream follows> 00 - 后面是原始未压缩数据,这些数据将以 null 终止。

这就解释了为什么您会在未压缩的输出中看到45 56 67

至于为什么格式使用这种方法?RLE 对于编码不重复的数据效率低下。 考虑45 56 67

  • 简单的方法将其呈现为01 45 01 56 01 67(6 字节);
  • 扩展方法会产生 00 03 45 56 67 00(也是 6 个字节)。

一个更好的例子是,如果您需要编码01 02 03 04 05 06 07 08 09 0A

  • 这将需要使用基本帧 20 个字节;
  • 但使用 00 03 <data> 00 帧的 13 个字节