【发布时间】:2016-05-01 04:16:43
【问题描述】:
我了解使用 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;
}
【问题讨论】:
-
要求我们推荐或查找书籍、工具、软件库、教程或其他场外资源的问题对于 Stack Overflow 来说是无关紧要的,因为它们往往会吸引固执己见的答案和垃圾邮件。相反,请描述问题以及迄今为止为解决该问题所做的工作。
-
使用zlib,压缩位图,随心所欲。用 zlib 压缩是无损的。
-
我也将研究 zlib。我第一次遇到 rle,即使在 VHDL 中也很简单。
-
我刚刚添加了应该生成 24 位 RLE 图像的程序代码。我从 Pakhira Malay K 的“数字图像处理和模式识别”中找到了如何做 24 位 RLE 位图。
标签: c++ bitmap image-compression