1、使用ImageMagick自带的convert命令,进行raw格式转换(convert -depth 8 logo.png rgb:slogo.raw)logo.png是源文件,slogo.raw是转换完成的文件
注:imgageMagick安装包,Ubuntu执行sudo apt-get installimagemagick
2、编译一下android自带的rgb2565工具,其路径在$ANDROID_HOME/build/tools/rgb2565上(gcc -O2 -Wall-Wno-unused-parameter -o rgb2565 to565.c)
注:这个工具在\out\host\linux-x86\bin这个目录下已经是编译出来了的。
3、对raw文件进行rle565格式转换(rgb2565 -rle < slogo.raw >initlogo.rle) 这个地方的<>是必须有的,slogo.raw就是第一步转换出来的文件,initlogo.rle就是转换完成的文件。
上面的步骤是标准的准换过程,我们在网上很容易搜索到。但在显示的时候,有时还是会遇到问题,我们再接着来分析相关的部分。首先是rle文件,下面是某个rle图片文件用UE打开的16进制的数据:
这里的数据以4个字节一组,后两位用rgb565表示的颜色,前面两位表示的当前颜色的像素点,也就是后面紧接着有多少个这样颜色的像素点。注意他们是后一字节是高位,前面字节是低位。所以我们可以通过它知道一幅图片有多少个像素点,就是把所有的个数相加就对了。当我们用第三步来转换的时候,这个程序也会打印出来一个数据,这个就是整幅图片的像素个数了。
那么我们分析rle的目的是什么呢,因为我们现在的LCD基本上都是24位色,也就是RGB888,而我们这里用的是RGB565,这个自然是需要我们把相应的数据填充成为RGB888了。内核里面显示的函数是load_565rle_image(),我们需要对其进行修改:
int load_565rle_image(char *filename, bool bf_supported)
{
struct fb_info *info;
int fd, count, err = 0;
unsigned max;
unsigned short *data, *bits, *ptr;
unsigned int rgb32, red, green, blue, alpha;
info = registered_fb[0];
if (!info) {
printk(KERN_WARNING "%s: Can not access framebuffer\n",
__func__);
return -ENODEV;
}
fd = sys_open(filename, O_RDONLY, 0);
if (fd < 0) {
printk(KERN_WARNING "%s: Can not open %s\n",
__func__, filename);
return -ENOENT;
}
count = sys_lseek(fd, (off_t)0, 2);
if (count <= 0) {
err = -EIO;
goto err_logo_close_file;
}
sys_lseek(fd, (off_t)0, 0);
data = kmalloc(count, GFP_KERNEL);
if (!data) {
printk(KERN_WARNING "%s: Can not alloc data\n", __func__);
err = -ENOMEM;
goto err_logo_close_file;
}
if (sys_read(fd, (char *)data, count) != count) {
err = -EIO;
goto err_logo_free_data;
}
max = fb_width(info) * fb_height(info);
ptr = data;
if (bf_supported && (info->node == 1 || info->node == 2)) {
err = -EPERM;
pr_err("%s:%d no info->creen_base on fb%d!\n",
__func__, __LINE__, info->node);
goto err_logo_free_data;
}
bits = (unsigned short *)(info->screen_base);
while (count > 3) {
unsigned n = ptr[0];
if (n > max)
break;
if (fb_bpp(info) == 16) {
memset16(bits, ptr[1], n << 1);
bits += n;
} else if (fb_bpp(info) == 32) { //add for RGB888 display
/* convert 16 bits to 32 bits */
rgb32 = ((ptr[1] >> 11) & 0x1F);
red = (rgb32 << 3) | (rgb32 >> 2);
rgb32 = ((ptr[1] >> 5) & 0x3F);
green = (rgb32 << 2) | (rgb32 >> 4);
rgb32 = ((ptr[1]) & 0x1F);
blue = (rgb32 << 3) | (rgb32 >> 2);
alpha = 0xff;
rgb32 = (alpha << 24) | (blue << 16) | (green << 8) | (red);
memset32(bits, rgb32, n << 2);
bits += (n * 2);
}
max -= n;
ptr += 2;
count -= 4;
}
err_logo_free_data:
kfree(data);
err_logo_close_file:
sys_close(fd);
return err;
}
这里主要就是对上面图片里面展示的RGB扩充到8位,然后显示就可以了。
我么可以采用纯色图片,条纹图片进行显示,根据显示的效果来分析。我自己遇到个显示错位了,后面发现是图像的大小不对应,既然这里是32位,那么图像的宽度应该是32的倍数,我们1080的LCD,这个地方需要1088像素的图片。
如果后面还需要什么问题,继续补充...