如何将位图字体从 C 标头格式转换为原始位
How to convert a bitmap font from C header format to raw bits
我有一个 C 头文件,其中包含 10x12 像素位图字体字符,位于 2x12 数组中(用于单色 LCD)。 这浪费了每隔一个字节的较低 6 位,更不用说由于必须跳过填充而更难渲染了。
将其转换为没有填充位的简单序列化位的最简单方法是什么?
我看到的解决方案有很多复杂的位敲击。 有没有一种简单的方法来执行此操作?
0x00,0x00, /* ................ */
0x30,0x00, /* ..@@............ */
0x78,0x00, /* .@@@@........... */
0x48,0x00, /* .@..@........... */
0xCC,0x00, /* @@..@@.......... */
0xCC,0x00, /* @@..@@.......... */
0xCC,0x00, /* @@..@@.......... */
0xFC,0x00, /* @@@@@@.......... */
0xCC,0x00, /* @@..@@.......... */
0xCC,0x00, /* @@..@@.......... */
0x00,0x00, /* ................ */
0x00,0x00 /* ................ */
好吧,10 × 12 = 120,你可以准确地在 15 字节中存储 120 个像素。每 5 个字节编码 4 行像素。
你得到的本质上是一个 8x15 的稀疏矩阵。
有一个提升库 - uBLAS - 来帮助你处理稀疏矩阵。例如,如果您的字体尺寸发生变化,这将有所帮助。
这个问题也可能有所帮助。
至于"复杂的位敲击"... 是的,这很复杂,但是如果您将打包的字节和索引写到它们来自的解压缩数组中,那么很容易弄清楚如何构造每个值......
|........|........|........|........|........|
|00000000|11222222|22334444|44445566|66666677|
上述循环重复3次。
char a[24] = {
0x00,0x00, /* ................ */
0x30,0x00, /* ..@@............ */
0x78,0x00, /* .@@@@........... */
0x48,0x00, /* .@..@........... */
0xCC,0x00, /* @@..@@.......... */
0xCC,0x00, /* @@..@@.......... */
0xCC,0x00, /* @@..@@.......... */
0xFC,0x00, /* @@@@@@.......... */
0xCC,0x00, /* @@..@@.......... */
0xCC,0x00, /* @@..@@.......... */
0x00,0x00, /* ................ */
0x00,0x00 /* ................ */
};
void pack( char ap[15], const char a[24] )
{
ap[0] = a[0];
ap[1] = a[1] | (a[2] >> 2 );
ap[2] = (a[2] << 6) | (a[3] >> 2 ) | (a[4] >> 4);
ap[3] = (a[4] << 4) | (a[5] >> 4) | (a[6] >> 6);
ap[4] = (a[6] << 2) | (a[7] >> 6);
ap[5] = a[8];
ap[6] = a[9] | (a[10] >> 2 );
ap[7] = (a[10] << 6) | (a[11] >> 2 ) | (a[12] >> 4);
ap[8] = (a[12] << 4) | (a[13] >> 4) | (a[14] >> 6);
ap[9] = (a[14] << 2) | (a[15] >> 6);
ap[10] = a[16];
ap[11] = a[17] | (a[18] >> 2 );
ap[12] = (a[18] << 6) | (a[19] >> 2 ) | (a[20] >> 4);
ap[13] = (a[20] << 4) | (a[21] >> 4) | (a[22] >> 6);
ap[14] = (a[22] << 2) | (a[23] >> 6);
}
如果你愿意,你可以在一个小循环中做上述操作,以减少犯错的范围...... 只需从 0 循环到 2,并相应地推进数组。 你知道,有点像这样(除了你需要适当的指针):
for( int i = 0; i < 3; i++ ) {
ap[0] = a[0];
ap[1] = a[1] | (a[2] >> 2 );
ap[2] = (a[2] << 6) | (a[3] >> 2 ) | (a[4] >> 4);
ap[3] = (a[4] << 4) | (a[5] >> 4) | (a[6] >> 6);
ap[4] = (a[6] << 2) | (a[7] >> 6);
ap += 5;
a += 8;
}
我希望我把所有这些转变都做对了=)
当然,
这正是JBIG CODEC旨在处理的问题 - 但会涉及大量的位敲击。
使用字典编码算法处理0
的运行长度,您可能还会获得不错的结果。
简化版本可以创建一个生产者消费者,一次一个位,使位爆炸保持在理智的水平。 这是我最终做的事情:
#define CHAR_W 10
#define CHAR_H 12
#define NUM_CHARS 100
#define CEILING(x,y) (((x) + (y) - 1) / (y))
#define BYTES CEILING(CHAR_W, 8)
#define BIT(x, n) ( ((1 << n) & x) >> n )
#define COPYBIT(b,x,n) (((0x1 & b) << n) | x)
#define CHAR_BYTES CEILING(CHAR_H * CHAR_W, 8)
#define OUTBYTES NUM_CHARS * CHAR_BYTES
int main()
{
int totinbit = 0;
int locinbit = 0;
int locoutbit = 7; // start with msb
int totoutbit = 0;
int bytes = BYTES;
unsigned char c = 0;
unsigned char o = 0;
unsigned char buf[OUTBYTES];
while (totoutbit < NUM_CHARS * CHAR_H * CHAR_W)
{
c = fontArray[totinbit / 8];
locinbit = 7 - totinbit % 8;
o = COPYBIT(BIT(c,locinbit),o,locoutbit);
// reset out counter, full byte produced
if (--locoutbit < 0)
{
locoutbit = 7;
buf[totoutbit / 8] = o;
o = 0;
}
// skip over the padding bits
if ((totoutbit % CHAR_W) == (CHAR_W - 1))
totinbit = CEILING(totinbit,8) * 8 - 1;
totinbit++;
// character boundary
if ( (totinbit % (bytes * 8 * CHAR_H)) == 0 && totinbit > 0)
{
// pad the last byte in the character if necessary
if (locoutbit != 7)
locoutbit = 7;
}
totoutbit++;
}
// at this point buf contains the converted bitmap array
}
相关文章:
- 将"打开的CV图像"中的"颜色"转换为整数格式
- 检查不带转换的扫描格式
- 当我尝试使用 sstream 和分面将 Boost Time_duration转换为字符串时,我没有得到所需的格式
- 将CHW格式的浮点向量转换为cv::Mat
- 将复杂的非基元C++数据类型转换为 Erlang/Elixir 格式,以使用 NIF 导出方法
- 如何在C++中将 chrono::秒转换为 HH:MM:SS 格式的字符串?
- 以C++格式将字符串转换为数字
- 将 BGR 图像转换为 jpeg 格式的 base64 字符串
- 将'\x00\x00\x00'格式的字符串转换为无符号字符数组
- 如何在C++中将"%Y%m%d"格式字符串转换为time_t变量?
- 如何将 Openh264 解码帧无延迟输出格式转换为 OpenCV 矩阵
- 一直在尝试在 c++ 中将 12 小时制格式转换为 24 小时制格式
- FFMpeg与OpenCV的格式转换/简单转换
- 格式转换在OpenGL图像中
- 如何将位图字体从 C 标头格式转换为原始位
- 如何在黑莓10中将日期格式转换为字符串
- 将opencv图像cv::Mat格式转换为c# BitmapImage
- 如何将QImage格式转换为OpenGL支持的格式
- 如何从"STL"格式转换为"3DS"
- 图像格式转换opencv