今天翻了下墙,解决了一直以来的疑惑问题:
为什么Android5.0以及6.0的recovery版本,机器人动画怎么就只有一张图片?
这个问题,我百思不得其解,看了很多网文,也只是有了个概念。
请参考以下文档,这是我从谷歌Android开源网拉下来的原文:
https://source.android.com/devices/tech/ota/device_code
Recovery UI images
Android 5.x
The recovery user interface consists images. Ideally, users never interact with the UI: During a normal update, the phone boots into recovery, fills the installation progress bar, and boots back into the new system without input from the user. In the event of a system update problem, the only user action that can be taken is to call customer care.
An image-only interface obviates the need for localization. However, as of Android 5.x the update can display a string of text (e.g. "Installing system update...") along with the image. For details, see Localized recovery text.
bootable/recovery/interlace-frames.py
takes a set of input frames and combines them into the necessary composite image used by recovery.bootable/recovery/res$DENSITY/images
(e.g., bootable/recovery/res-hdpi/images
). To use a static image during installation, you need only provide the icon_installing.png image and set the number of frames in the animation to 0 (the error icon is not animated; it is always a static image).
The Android 4.x and earlier recovery UI uses the error image (shown above) and the installing animation plus several overlay images:
During installation, the on-screen display is constructed by drawing the icon_installing.png image, then drawing one of the overlay frames on top of it at the proper offset. Here, a red box is superimposed to highlight where the overlay is placed on top of the base image:
Subsequent frames are displayed by drawing only the next overlay image atop what's already there; the base image is not redrawn.
The number of frames in the animation, desired speed, and x- and y-offsets of the overlay relative to the base are set by member variables of the ScreenRecoveryUI class. When using custom images instead of default images, override the Init() method in your subclass to change these values for your custom images (for details, see ScreenRecoveryUI). The script bootable/recovery/make-overlay.py can assist in converting a set of image frames to the "base image + overlay images" form needed by recovery, including computing of the necessary offsets.
Default images are located in bootable/recovery/res/images. To use a static image during installation, you need only provide the icon_installing.png image and set the number of frames in the animation to 0 (the error icon is not animated; it is always a static image).
上面说了这么多,其实也是把这上面的图片通过make-overlay.py这个python脚本来对4.x以及早期版本的android recovery的图片进行合成,中间让我们看到的转转转那个overlay的效果就是上面这些组图合成的,合成最终的图片存放在bootable/recovery/res/images这个路径下。
根据以上参考官方的文档理解,顺便参考一个网友的更改方案:
转自 http://qiushao.net/2015/12/20/replace_android_recovery_picture/
替换recovery动画图片
最近在做一个项目是android 系统各部分动画的定制,有一个模块是recovery界面的定制,包括用户升级,重置系统时的动画效果修改。与recovery相关的代码在android4.4/bootable/recovery
目录下。
我大概看了一下与界面相关的代码,觉得应该只是替换几张图片,修改一下参数而已,没啥工作量,所以也就不细看具体实现了。但当美工把图交给我后,我把图片替换后,发现美工给的彩色的图片变成灰度图的效果了,而且图片被拉伸,显示不全。这咋回事啊,问同事,百度,google 一圈之后,也找不到原因。只能 read the fucking source code 了。
周末加班看了一下午的recovery代码,终于找到原因啦。原来是recovery的图片资源必须为png格式,且不能带alhpa通道信息
。真是个大坑。
相关代码在 android4.4/bootable/recovery/minui/resources.c
文件中:
int res_create_surface(const char* name, gr_surface* pSurface) { printf("qiushao: res_create_surface: /res/images/%s.png\n", name); ... int color_type = info_ptr->color_type; int bit_depth = info_ptr->bit_depth; int channels = info_ptr->channels; ... size_t width = info_ptr->width; size_t height = info_ptr->height; size_t stride = (color_type == PNG_COLOR_TYPE_GRAY ? 1 : 4) * width; size_t pixelSize = stride * height; ... printf("qiushao: color_type = %d\n", color_type); printf("qiushao: bit_depth = %d\n", bit_depth); printf("qiushao: channels = %d\n", channels); printf("qiushao: width = %lu\n", width); printf("qiushao: height = %lu\n", height); printf("qiushao: stride = %lu\n", stride); printf("qiushao: alpha = %d\n", alpha); unsigned int y; if (channels == 3 || (channels == 1 && !alpha)) { printf("qiushao: channels == 3 || (channels == 1 && !alpha)\n"); for (y = 0; y < height; ++y) { unsigned char* pRow = pData + y * stride; png_read_row(png_ptr, pRow, NULL); int x; for(x = width - 1; x >= 0; x--) { int sx = x * 3; int dx = x * 4; unsigned char r = pRow[sx]; unsigned char g = pRow[sx + 1]; unsigned char b = pRow[sx + 2]; unsigned char a = 0xff; pRow[dx ] = r; // r pRow[dx + 1] = g; // g pRow[dx + 2] = b; // b pRow[dx + 3] = a; } } } else { printf("qiushao: channels != 3 && (channels == 1 && !alpha)\n"); for (y = 0; y < height; ++y) { unsigned char* pRow = pData + y * stride; png_read_row(png_ptr, pRow, NULL); } } *pSurface = (gr_surface) surface;
转自 http://qiushao.net/2015/12/20/replace_android_recovery_picture/
替换recovery动画图片
最近在做一个项目是android 系统各部分动画的定制,有一个模块是recovery界面的定制,包括用户升级,重置系统时的动画效果修改。与recovery相关的代码在android4.4/bootable/recovery
目录下。
我大概看了一下与界面相关的代码,觉得应该只是替换几张图片,修改一下参数而已,没啥工作量,所以也就不细看具体实现了。但当美工把图交给我后,我把图片替换后,发现美工给的彩色的图片变成灰度图的效果了,而且图片被拉伸,显示不全。这咋回事啊,问同事,百度,google 一圈之后,也找不到原因。只能 read the fucking source code 了。
周末加班看了一下午的recovery代码,终于找到原因啦。原来是recovery的图片资源必须为png格式,且不能带alhpa通道信息
。真是个大坑。
相关代码在 android4.4/bootable/recovery/minui/resources.c
文件中:
这个函数将图片文件的数据读取到内存,我在其中输出了一些调试信息,输出图片的 color_type, channels 等信息。查看LOG发现,android原生的图片 channels == 3,channels 即色彩通道个数,等于 3 的话,意味着只有 R,G,B 三个通道的信息,没有 ALPHA 通道信息!这段代码的逻辑是如果channels 不等于3, 则按channels = 1 来处理,即灰度图。
美工给的图片是带 alpha通道信息的,即channels = 4,被当成灰度图像来处理了,怪不得显示的效果是灰度图像。我一直以为 png 图像就只有一种格式,都是带有 alpha通道的。。。
使用图像处理工具(photoshop 或者 gimp),将美工给的图片去掉 alpha 通道信息,再替换recovery 的图片,编译,替换recovery.img ,reboot -r 。图片终于正常显示啦。
转自 http://qiushao.net/2015/12/20/replace_android_recovery_picture/
替换recovery动画图片
最近在做一个项目是android 系统各部分动画的定制,有一个模块是recovery界面的定制,包括用户升级,重置系统时的动画效果修改。与recovery相关的代码在android4.4/bootable/recovery
目录下。
我大概看了一下与界面相关的代码,觉得应该只是替换几张图片,修改一下参数而已,没啥工作量,所以也就不细看具体实现了。但当美工把图交给我后,我把图片替换后,发现美工给的彩色的图片变成灰度图的效果了,而且图片被拉伸,显示不全。这咋回事啊,问同事,百度,google 一圈之后,也找不到原因。只能 read the fucking source code 了。
周末加班看了一下午的recovery代码,终于找到原因啦。原来是recovery的图片资源必须为png格式,且不能带alhpa通道信息
。真是个大坑。
相关代码在 android4.4/bootable/recovery/minui/resources.c
文件中: