[Android] Boot Animation 開機動畫
Android系統開機動畫包括三部分:
fastboot/main.c
fastboot/logo_h
看source code,可以得知他是把bmp當成raw data儲存。
但是我找不到合適的轉檔程式,於是我自己寫了一隻,有些bug,只能輸入正方形的圖,而且因為little-endian之類的問題,輸入的圖會顛倒,但是我懶得修了:
convert -depth 8 logo.png rgb:logo.raw
android自帶的rgb2565工具,對raw文件進行rle565格式轉換
$(SRC_HOME)/out/host/linux-x86/bin/l
刪除中間文件
rm -f logo.raw logo.png
然後將initlogo.rle拷貝到android系統根目錄,也就是root目錄底下
cp initlogo.rle system/core/rootdir/
system/core/init/init.h
184 #define INIT_IMAGE_FILE "/initlogo.rle"
system/core/init/init.c
901 if( load_565rle_image(INIT_IMAGE_FILE) ) {
system/core/rootdir/Android.mk
#++ Vincent
PRODUCT_COPY_FILES += \
$(LOCAL_PATH)/initlogo.rle:/root/initlogo.rle
#-- Vincent
2. create a new splash.png file (using gimp or whatever)
3. convert it to "pnm" by using "pngtopnm" as in
pngtopnm splash.png > splash.pnm
4. convert it to "rle" by using "ppmtolss16" as in
ppmtolss16 "#000000=0" "#ffffff=7" < splash.pnm > splash.rle
frameworks/base/core/res/assets/images/android-logo-mask.png
自製動畫檔
frameworks/base/cmds/bootanimation/bootanimation.zip
我們可以使用任意的文字編輯器來打開該 desc.txt 檔,打開後其內容為:
320 480 15
p 1 30 eris
p 1 0 peeking
設定檔中第一行說明了即將使用 320x480 大小的圖檔,並以每秒鐘顯示一個 圖檔的方式(fps)來播放動畫。
第二行到第六行都是由 p 帶頭,它們代表 即將播放的規則:
p之後的第一個數字代表播放次數,如果該數字為 0,即代表 不限次數的播放;
第二個數字代表播放後所需要暫停(pause)的時間,以第二行的 30 為例,由於每秒播放 15 個 frame(圖檔),所以暫停約兩秒;
最後一個代表撥放的圖檔目錄名稱。
請在"壓縮方式"的下拉式選單中選取"僅儲存",否則產生的 bootanimation.zip 是無法正常顯示動畫的。
zip -r -Z store bootanimation.zip ./*
http://www.cnmsdn.com/html/201005/1274840322ID5052.html
http://anemospring.blogspot.com/2010/11/kernel-uboot-logo.html
http://web.nchu.edu.tw/~jlu/cyut/android/animation.shtml
bootloader部份
bootloader
bootloader在開機階段會show一個小機器人的圖片fastboot/main.c
BootMenuImagesLOGO[0] = (Icon *)&s_logo; BootMenu_LOGO = FastbootCreateRadioMenu(1, 0, 3, NVIDIA_GREEN, BootMenuImagesLOGO); FastbootDrawRadioMenu(&s_Frontbuffer, s_FrontbufferPixels, BootMenu_LOGO); |
fastboot/logo_h
#ifndef logo_h #define logo_h typedef struct _logo { NvU16 width; NvU16 height; NvS32 stride; NvU8 bpp; NvU32 data[65536]; } logo_t; static const logo_t s_logo = { 256, 256, 768, 24, { 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, ... 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, } }; const logo_t *logo = &s_logo; #endif |
看source code,可以得知他是把bmp當成raw data儲存。
但是我找不到合適的轉檔程式,於是我自己寫了一隻,有些bug,只能輸入正方形的圖,而且因為little-endian之類的問題,輸入的圖會顛倒,但是我懶得修了:
#include <stdio.h> #include <string.h> #include <stdlib.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #define DIGISIZE 6 #define HEADERSIZE 28 int main(int argc, const char *argv[]) { int fd_in, fd_out; int k=0, i=0, j=0, ret; unsigned char result[2*DIGISIZE+4]; unsigned char d1, d2; unsigned char header[HEADERSIZE]; unsigned int filesize = 0, offset = 0, heigh = 0, width = 0, datasize = 0; unsigned char *data; char *header_name; char *tmp_name; char *delim="."; tmp_name = malloc(sizeof(argv[2])+1); memcpy(tmp_name, argv[2], sizeof(argv[2])+1); header_name = strtok(tmp_name, delim); fd_in = open(argv[1], O_RDWR, S_IRWXU | S_IRWXG | S_IRWXO); fd_out = open(argv[2], O_RDWR| O_CREAT, S_IRWXU | S_IRWXG | S_IRWXO); //fd_in = fopen(argv[1], "wb+"); //fd_out = fopen(header_name, "wb+"); ret = read(fd_in, header, HEADERSIZE); filesize = header[2] + (header[3] << 8) + (header[4] << 16) + (header[5] << 24); offset = header[10] + (header[11] << 8) + (header[12] << 16) + (header[13] << 24); width = header[18] + (header[19] << 8) + (header[20] << 16) + (header[21] << 24); heigh = header[22] + (header[23] << 8) + (header[24] << 16) + (header[25] << 24); datasize = filesize - offset; printf("\n===========\nfilename: %s\n", header_name); printf("filesize: %d\n", filesize); printf("offset: %d\n", offset); printf("datasize: %d\n", datasize); printf("width: %d\n", width); printf("heigh: %d\n", heigh); char buf1[2048]; sprintf(buf1, "#ifndef %s_h\n#define %s_h\ntypedef struct _%s\n{\n NvU16 width;\n NvU16 height;\n NvS32 stride;\n NvU8 bpp;\n NvU32 data[ %d ];\n} %s_t;\n\nstatic const %s_t s_%s = \n{\n", header_name, header_name, header_name, filesize, header_name, header_name, header_name); char buf2[1024]; sprintf(buf2," %d,\n %d,\n %d,\n 24,\n {\n", width, heigh, width*3); write(fd_out, buf1, strlen(buf1)); lseek(fd_out, 0, SEEK_END); write(fd_out, buf2, strlen(buf2)); lseek(fd_out, 0, SEEK_END); result[0]='0'; result[1]='x'; result[DIGISIZE+2]=','; result[DIGISIZE+3]=' '; data = (unsigned char *) malloc(datasize+1); lseek(fd_in, offset, SEEK_SET); read(fd_in, data, datasize); data[datasize]='\0'; for (i = 1; i <= datasize; i++) { //while(ret = read(fd_in, buf1, DIGISIZE)) { //for (j = 0; j < DIGISIZE; j++) { d1 = (*(data + datasize - i)) / 0x10; d2 = (*(data + datasize - i)) % 0x10; if(d1<0xa){ d1 += 0x30; }else{ d1 += 0x57; } if(d2<0xa){ d2 += 0x30; }else{ d2 += 0x57; } result[j+2]=d1; result[j+3]=d2; //} j+=2; if(j==6){ write(fd_out, result, DIGISIZE+4); j=0; } k++; if(!(k%18)) write(fd_out, "\n", 1); } char buf3[1024]; sprintf(buf3,"\n }\n};\n\nconst %s_t *%s = &s_%s;\n\n#endif\n", header_name, header_name, header_name); lseek(fd_out, 0, SEEK_END); write(fd_out, buf3, strlen(buf3)); free(data); close(fd_in); close(fd_out); return 0; } |
android system部份
ANDROID文字
RLE製作方法一
#使用ubuntu ImageMagick自帶的convert命令,進行raw格式轉換 (註:好像只支持png-24,其他格式生成的rle文件顯示不正常,有興趣大家可以再驗證一下。)convert -depth 8 logo.png rgb:logo.raw
android自帶的rgb2565工具,對raw文件進行rle565格式轉換
$(SRC_HOME)/out/host/linux-x86/bin/l
刪除中間文件
rm -f logo.raw logo.png
然後將initlogo.rle拷貝到android系統根目錄,也就是root目錄底下
cp initlogo.rle system/core/rootdir/
system/core/init/init.h
184 #define INIT_IMAGE_FILE "/initlogo.rle"
system/core/init/init.c
901 if( load_565rle_image(INIT_IMAGE_FILE) ) {
system/core/rootdir/Android.mk
#++ Vincent
PRODUCT_COPY_FILES += \
$(LOCAL_PATH)/initlogo.rle:/root/initlogo.rle
#-- Vincent
RLE製作方法二
1. sudo apt-get install netpbm2. create a new splash.png file (using gimp or whatever)
3. convert it to "pnm" by using "pngtopnm" as in
pngtopnm splash.png > splash.pnm
4. convert it to "rle" by using "ppmtolss16" as in
ppmtolss16 "#000000=0" "#ffffff=7" < splash.pnm > splash.rle
ANDROID閃爍動畫
android預設frameworks/base/core/res/assets/images/android-logo-mask.png
自製動畫檔
frameworks/base/cmds/bootanimation/bootanimation.zip
我們可以使用任意的文字編輯器來打開該 desc.txt 檔,打開後其內容為:
320 480 15
p 1 30 eris
p 1 0 peeking
設定檔中第一行說明了即將使用 320x480 大小的圖檔,並以每秒鐘顯示一個 圖檔的方式(fps)來播放動畫。
第二行到第六行都是由 p 帶頭,它們代表 即將播放的規則:
p之後的第一個數字代表播放次數,如果該數字為 0,即代表 不限次數的播放;
第二個數字代表播放後所需要暫停(pause)的時間,以第二行的 30 為例,由於每秒播放 15 個 frame(圖檔),所以暫停約兩秒;
最後一個代表撥放的圖檔目錄名稱。
請在"壓縮方式"的下拉式選單中選取"僅儲存",否則產生的 bootanimation.zip 是無法正常顯示動畫的。
zip -r -Z store bootanimation.zip ./*
Reference
http://www.xn--yeto30a.com/?p=302http://www.cnmsdn.com/html/201005/1274840322ID5052.html
http://anemospring.blogspot.com/2010/11/kernel-uboot-logo.html
http://web.nchu.edu.tw/~jlu/cyut/android/animation.shtml
留言
張貼留言