我想将24位bmp文件转换为RGB565格式以写入串行TFT彩色显示器。
24位bmp的大小总是320x240像素,因为我的TFT显示器是320x240
有没有人有这方面的经验?它可能是C / C ++,Shell,Python,Java Script等等......
答案 0 :(得分:1)
我会使用 NetPBM (小得多,重量更轻)或 ImageMagick (更大的安装)将BMP
转换为格式解析起来很简单,然后使用 Perl 将其转换为RGB565格式。
我假设您计划将RGB565数据写入帧缓冲区,因此您可以执行以下操作:
./bmp2rgb565 image.bmp > /dev/fb1
因此,将以下内容保存为bmp2rgb565
:
#!/bin/bash
################################################################################
# bmp2rgb565
# Mark Setchell
################################################################################
if [ $# -ne 1 ]; then
echo Usage: $0 image.bmp
exit 1
fi
file=$1
# Use NetPBM's "bmptopnm" to convert BMP to PNM for easy reading
# You could use ImageMagick: convert "$file" PNM: | perl ...
bmptopnm "$file" 2> /dev/null |
perl -e '
my $debug=0; # Change to 1 for debugging
# Discard first 3 lines of PNM header:
# P3
# 320 240
# 255
my $line=<STDIN>; $line=<STDIN>; $line=<STDIN>;
# Read file, 3 RGB bytes at a time
{
local $/ = \3;
while(my $pixel=<STDIN>){
# Extract 8-bit R,G and B from pixel
my ($r,$g,$b)=unpack("CCC",$pixel);
printf("R/G/B: %d/%d/%d\n",$r,$g,$b) if $debug;
# Convert to RGB565
my $r5=$r>>3;
my $g6=$g>>2;
my $b5=$b>>3;
my $rgb565 = ($r5<<11) | ($g6<<5) | $b5;
# Convert to little-endian 16-bit (VAX order) and write 2 bytes
my $v=pack("v",$rgb565);
syswrite(STDOUT,$v,2);
}
}
'
我没有方便测试的帧缓冲区,但它应该非常接近。
请注意,您可以通过以下方式使代码更加健壮:
convert "$file" -depth 8 -resize 320x240\! PNM: | perl ...
这将确保图像始终与帧缓冲区大小匹配,并且它是8位而不是16位。如果-flip
图片是颠倒的或从前到后,您可能还需要-flop
或BMP
。
请注意,如果您使用 ImageMagick convert
,该代码将适用于GIF,TIFF,JPEG,PNG以及约150种其他格式以及BMP。
请注意,如果您要测试代码,可以使用 ImageMagick 生成黑色图像,如下所示:
convert -size 320x240 xc:black BMP3:black.bmp
然后在运行时在输出中查找一堆零:
./bmp2rgb565 black.bmp | xxd -g2
同样,您可以生成白色图像并查找一堆ff
s:
convert -size 320x240 xc:red BMP3:white.bmp
依旧是红色,绿色和蓝色:
convert -size 320x240 xc:red BMP3:red.bmp
convert -size 320x240 xc:lime BMP3:green.bmp
convert -size 320x240 xc:blue BMP3:blue.bmp
# Or make a cyan-magenta gradient image
convert -size 320x240 gradient:cyan-magenta cyan-magenta-gradient.bmp
示例:强>
./RGB565 red.bmp | xxd -g2 | more
00000000: 00f8 00f8 00f8 00f8 00f8 00f8 00f8 00f8 ................
00000010: 00f8 00f8 00f8 00f8 00f8 00f8 00f8 00f8 ................
示例:强>
./RGB565 blue.bmp | xxd -g2 | more
00000000: 1f00 1f00 1f00 1f00 1f00 1f00 1f00 1f00 ................
00000010: 1f00 1f00 1f00 1f00 1f00 1f00 1f00 1f00 ................
关键字: RGB565,rgb565,帧缓冲,帧缓冲,打包,解包,Perl,BMP,PGM,图像,Raspberry Pi,RASPI
答案 1 :(得分:0)
要转换为RGB565,您可以使用ImageMagick:
convert test.png -resize 320x200 -ordered-dither threshold,32,64,32 test2.png
您需要以什么格式输出?
答案 2 :(得分:0)
我假设您只想流出没有任何标题或其他数据的像素数据。
问题的核心已经被描述为here。
如果您想自己实施,以下方法可能有所帮助:
打开文件后,你需要通过读取bfOffBits
值来跳过BMP标题(参见this BMP format description),最简单的方法可能就是通过读入一个结构来实现它。匹配BMP标题。
(注意:这只能起作用,因为图像的尺寸可以被4整除!查看格式说明以获取更多细节)
然后通过bfOffBits
向前搜索并且在文件尚未结束时,使用问题中的方法将三个连续字节(uint8_t
)转换为一个16位值(uint16_t
)我上面提到过。您需要的基本C文件操作是fopen, fclose, fread, fwrite, fgetc/fgetwc, fputc/fputwc
和fseek