将 BMP 图片转换为 WBMP 格式






2.38/5 (5投票s)
此程序将 BMP 图片转换为无线设备中使用的 WBMP 格式。
引言
此代码将加载一张图片并将其转换为 WBMP 格式。 该程序的第一个版本仅支持宽度和高度 < 127 的单色 BMP。 目前,您也可以加载彩色图片,以及宽度和高度 > 127 的图片。
背景
WBMP 是一种用于无线设备的图像格式。 WBMP 格式的图片以位格式保存。 也就是说,图像的每个像素都保存为 1 位。 因此,一个 8 x 8 像素的图像只需要 64 位(8 个字节)。 这种格式的限制是它只能保存黑白图像(不支持彩色或灰度)。 因此,如果您加载任何非单色图片,它将使用抖动算法(为此目的使用 AForge 库)在内部转换为单色。
使用代码
此程序的主要部分涉及从黑白 BMP 图片中读取像素,检查每个像素是黑色还是白色,然后将 '0' 或 '1' 写入输出 WBMP。 因此,输入 BMP 的每 8 个像素将被压缩成一个字节 (8 位),然后写入 WBMP 文件。
例如,如果 BMP 中的第一个像素是黑色,则将 '0' 写入输出字节的第一个位置。 如果 BMP 中的第二个像素是白色,则将 '1' 写入输出字节的第二个位置。 如果第三个像素是白色,则将 '1' 写入输出字节的第三个位置...
上述过程会重复进行,直到整个输出字节被写入(这对应于输入 BMP 中的 8 个像素)。 然后,将该输出字节写入 WBMP 文件。 然后,整个过程会重复进行,直到输入 BMP 中的所有像素都被“压缩”并写入输出 WBMP 文件中。
用于将单色图像转换为 WBMP 的原始代码如下所示
for (int y = 0; y < inputBmp.Height; y++)
{
byteLocation = 0;
data = 0;
for (int x = 0; x < inputBmp.Width; x++)
{
Color color = inputBmp.GetPixel(x, y);
byte BW = (byte)((color.R + color.G + color.B) / 3);
//reset byteLocation every 8 bits
if (byteLocation > 7) byteLocation = 0;
bool black = false;
if(BW > 125)
{
black = true;
}
switch (byteLocation)
{
case 0:
if (black)
{
data |= (byte)128;
}
break;
case 1:
if (black)
{
data |= (byte)64;
}
break;
case 2:
if (black)
{
data |= (byte)32;
}
break;
:
:
case 7:
if (black)
{
data |= (byte)1;
}
// every 8 bits write the data to the output file
bw.Write(data);
data = 0;
break;
}
byteLocation++;
}
// if at end of a line we have some remaining bits to be written, write it here
// this will happen if bmp width is not a multiple of 8.
if (byteLocation != byteLength + 1)
{
bw.Write(data);
}
}
在收到来自“Willi Deutschmann”的一些反馈后,上述代码被简化为以下内容。 现在,我们没有使用 switch
结构,而是使用这行代码:data |= (byte)(128 >> byteLocation);
.
for (int y = 0; y < inputBmp.Height; y++)
{
byteLocation = 0;
data = 0;
for (int x = 0; x < inputBmp.Width; x++)
{
Color color = inputBmp.GetPixel(x, y);
byte BW = (byte)((color.R + color.G + color.B) / 3);
//reset byteLocation every 8 bits
if (byteLocation > 7) byteLocation = 0;
if(BW > 0)
{
data |= (byte)(128 >> byteLocation);
}
// every 8 bits write the data to the output file
if (byteLocation == 7)
{
bw.Write(data);
data = 0;
}
byteLocation++;
}
// if at end of a line we have some remaining bits to be written, write it here
// this will happen if bmp width is not a multiple of 8.
if (byteLocation != byteLength + 1)
{
bw.Write(data);
}
}
关注点
我不确定在 C# 中将位写入字节的正确方法是什么。 我想,在 C 语言中,例如,有一个选项可以在结构中指定位域,然后分别写入每个位。 因此,我上面所做的是在 C# 中使用按位或运算写入字节的单独位。 在早期版本中,这通过以下方式完成: 要将 '1' 写入字节的第 8 位,我使用了类似 data |= (byte)128;
的代码。 要将 '1' 写入字节的第 7 位: data |= (byte)64;
等等。 在新代码中,这已被修改为 data |= (byte)(128 >> byteLocation);
.
要将彩色图像转换为单色图像,请使用 AForge 库,此处提供了示例程序 @ https://codeproject.org.cn/cs/media/Image_Processing_Lab.asp。
您可以使用任何在线模拟器检查创建的 WBMP 图像是否正确。 首先,使用 WBMP 图像创建一个 .wml 文件。 将 WML 文件和 WBMP 图像上传到网站,并将 .wml 文件的 URL 提供给模拟器。 可以访问使用此应用程序创建的几个示例 WBMP 图片 @ http://sajjitha.atspace.com/lake2.wml 和 http://sajjitha.atspace.com/forest.wml.
限制 / 修改...
该程序已针对单色和彩色图像进行了测试。 此应用程序生成的几个 WBMP 文件被上传到 WAP 模拟器,它们显示正常...
历史
- 2007 年 7 月 29 日:支持彩色图像以及宽度、高度 > 127 的图像。
- 2007 年 7 月 31 日:更正了一个错误,当图像宽度、高度 > 127 时,该错误会产生错误的输出。
希望该程序现在运行正常... :)