gpt4 book ai didi

c++ - 我在哪里可以找到 24 位位图图像 RLE 的示例

转载 作者:行者123 更新时间:2023-11-30 03:45:12 25 4
gpt4 key购买 nike

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

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

(2)此外,以下是互联网上随处可见的 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 元文件)RLE 格式进行编码。 WMF 允许使用以下额外类型的帧,所有这些类型都必须使用 00 引入。控制代码:

  • 01 - 数据流结束
  • 02 <x> <y> - 相对移动
  • 03 <raw uncompressed data stream follows> 00 - 原始未压缩数据将以空值终止。

这解释了为什么您会看到 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 个字节使用基本框架;
  • 但 13 个字节使用 00 03 <data> 00框架

关于c++ - 我在哪里可以找到 24 位位图图像 RLE 的示例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34982705/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com