日本黄色一级经典视频|伊人久久精品视频|亚洲黄色色周成人视频九九九|av免费网址黄色小短片|黄色Av无码亚洲成年人|亚洲1区2区3区无码|真人黄片免费观看|无码一级小说欧美日免费三级|日韩中文字幕91在线看|精品久久久无码中文字幕边打电话

當前位置:首頁 > 嵌入式 > 嵌入式云IOT技術(shù)圈
[導讀]點擊上方嵌入式開發(fā)圈 記得關注我們哦! ??在上一篇文章中,我們大致的介紹了recovery的啟動流程,那么,recovery升級或者做雙清的時候,那些圖形動畫又是如何實現(xiàn)的呢?我們來看看代碼。 ?? ? 以下這段代碼位于recovery/screen_ui.cpp 1void?ScreenRecoveryU

點擊上方嵌入式開發(fā)圈 記得關注我們哦!

  在上一篇文章中,我們大致的介紹了recovery的啟動流程,那么,recovery升級或者做雙清的時候,那些圖形動畫又是如何實現(xiàn)的呢?我們來看看代碼。   

  以下這段代碼位于recovery/screen_ui.cpp

1void ScreenRecoveryUI::Init()
2{
3    gr_init();
4
5    gr_font_size(&char_width, &char_height);
6
7    text_col = text_row = 0;
8    text_rows = gr_fb_height() / char_height;
9    if (text_rows > kMaxRows) text_rows = kMaxRows;
10    text_top = 1;
11
12    text_cols = gr_fb_width() / char_width;
13    if (text_cols > kMaxCols - 1) text_cols = kMaxCols - 1;
14
15    backgroundIcon[NONE] = NULL;
16    LoadBitmapArray("icon_installing", &installing_frames, &installation);
17    backgroundIcon[INSTALLING_UPDATE] = installing_frames ? installation[0] : NULL;
18    backgroundIcon[ERASING] = backgroundIcon[INSTALLING_UPDATE];
19    LoadBitmap("icon_error", &backgroundIcon[ERROR]);
20    backgroundIcon[NO_COMMAND] = backgroundIcon[ERROR];
21
22    LoadBitmap("progress_empty", &progressBarEmpty);
23    LoadBitmap("progress_fill", &progressBarFill);
24    LoadBitmap("stage_empty", &stageMarkerEmpty);
25    LoadBitmap("stage_fill", &stageMarkerFill);
26
27    LoadLocalizedBitmap("installing_text", &backgroundText[INSTALLING_UPDATE]);
28    LoadLocalizedBitmap("erasing_text", &backgroundText[ERASING]);
29    LoadLocalizedBitmap("no_command_text", &backgroundText[NO_COMMAND]);
30    LoadLocalizedBitmap("error_text", &backgroundText[ERROR]);
31
32    pthread_create(&progress_tNULL, progress_thread, NULL);
33
34    RecoveryUI::Init();
35}

這段代碼都做了哪些事情呢?這些recovery初始化圖形顯示最開始的部分:(1)調(diào)用了miniui中的gr_init初始化顯示圖形相關的步驟,因為recovery是基于framebuffer機制顯示的。

(2)調(diào)用gr_font_size設置字體顯示的大小,然后計算文本顯示行列。

(3)接下來就是裝載圖片了,會調(diào)用到LoadBitmapArray和LoadBitmap這兩個函數(shù)。其中,我們會看到這些函數(shù)里圖片的名稱:

將上面的字符串與下面的圖片一一對應:

    那么這些分別是怎么顯示的?其中erasing_text是用來顯示做清除的時候顯示的文字,放大后如下:

    這上面有許許多多的語言版本,我們可以根據(jù)需要來選擇,這些主要要看接下來初始化文字的代碼邏輯。

    其余的圖片中,后綴帶text的,也和這些是類似的,有出現(xiàn)錯誤顯示的字體error_text,更新系統(tǒng)顯示的字體installing_text,沒有命令的時候顯示的字體no_command_text。

    除了文字顯示,我們最關心的就是icon_installing這張圖片了,在做系統(tǒng)更新的時候,這個機器人會轉(zhuǎn)動。這不是動畫嗎?怎么只有一張圖片呢?我們找到Android官方網(wǎng)站看看是為什么?原因如下:

 1# Copyright (C) 2014 The Android Open Source Project
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7#      http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14"""Script to take a set of frames (PNG files) for a recovery animation
15and turn it into a single output image which contains the input frames
16interlaced by row.  Run with the names of all the input frames on the
17command line, in order, followed by the name of the output file."""

18import sys
19try:
20  import Image
21  import PngImagePlugin
22except ImportError:
23  print "This script requires the Python Imaging Library to be installed."
24  sys.exit(1)
25frames = [Image.open(fn).convert("RGB"for fn in sys.argv[1:-1]]
26assert len(frames) > 0"Must have at least one input frame."
27sizes = set()
28for fr in frames:
29  sizes.add(fr.size)
30assert len(sizes) == 1"All input images must have the same size."
31w, h = sizes.pop()
32N = len(frames)
33out = Image.new("RGB", (w, h*N))
34for j in range(h):
35  for i in range(w):
36    for fn, f in enumerate(frames):
37      out.putpixel((i, j*N+fn), f.getpixel((i, j)))
38# When loading this image, the graphics library expects to find a text
39# chunk that specifies how many frames this animation represents.  If
40# you post-process the output of this script with some kind of
41# optimizer tool (eg pngcrush or zopflipng) make sure that your
42# optimizer preserves this text chunk.
43meta = PngImagePlugin.PngInfo()
44meta.add_text("Frames", str(N))
45out.save(sys.argv[-1], pnginfo=meta)

    這也就是為什么,調(diào)用這張圖片需要用到LoadBitmapArray這個函數(shù)的原因。

1void ScreenRecoveryUI::LoadBitmapArray(const char* filename, int* frames, gr_surface** surface) {
2    int result = res_create_multi_display_surface(filename, frames, surface);
3    if (result < 0) {
4        LOGE("missing bitmap %s\n(Code %d)\n", filename, result);
5    }
6}

調(diào)完這個函數(shù)后會調(diào)用

resources.cpp中的res_create_multi_display_surface函數(shù)用于顯示,源碼如下:

1int res_create_multi_display_surface(const char* name, int* frames, GRSurface*** pSurface) {
2    GRSurface** surface = NULL;
3    int result = 0;
4    png_structp png_ptr = NULL;
5    png_infop info_ptr = NULL;
6    png_uint_32 width, height;
7    png_byte channels;
8    int i;
9    png_textp text;
10    int num_text;
11    unsigned char* p_row;
12    unsigned int y;
13
14    *pSurface = NULL;
15    *frames = -1;
16
17    result = open_png(name, &png_ptr, &info_ptr, &width, &height, &channels);
18    if (result < 0return result;
19
20    *frames = 1;
21    if (png_get_text(png_ptr, info_ptr, &text, &num_text)) {
22        for (i = 0; i < num_text; ++i) {
23            if (text[i].key && strcmp(text[i].key, "Frames") == 0 && text[i].text) {
24                *frames = atoi(text[i].text);
25                break;
26            }
27        }
28        printf("  found frames = %d\n", *frames);
29    }
30
31    if (height % *frames != 0) {
32        printf("bad height (%d) for frame count (%d)\n", height, *frames);
33        result = -9;
34        goto exit;
35    }
36
37    surface = reinterpret_cast<GRSurface**>(malloc(*frames * sizeof(GRSurface*)));
38    if (surface == NULL) {
39        result = -8;
40        goto exit;
41    }
42    for (i = 0; i < *frames; ++i) {
43        surface[i] = init_display_surface(width, height / *frames);
44        if (surface[i] == NULL) {
45            result = -8;
46            goto exit;
47        }
48    }
49
50#if defined(RECOVERY_ABGR) || defined(RECOVERY_BGRA)
51    png_set_bgr(png_ptr);
52#endif
53
54    p_row = reinterpret_cast<unsigned char*>(malloc(width * 4));
55    for (y = 0; y < height; ++y) {
56        png_read_row(png_ptr, p_row, NULL);
57        int frame = y % *frames;
58        unsigned char* out_row = surface[frame]->data +
59            (y / *frames) * surface[frame]->row_bytes;
60        transform_rgb_to_draw(p_row, out_row, channels, width);
61    }
62    free(p_row);
63
64    *pSurface = reinterpret_cast<GRSurface**>(surface);
65
66exit:
67    png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
68
69    if (result < 0) {
70        if (surface) {
71            for (i = 0; i < *frames; ++i) {
72                if (surface[i]) free(surface[i]);
73            }
74            free(surface);
75        }
76    }
77    return result;
78}

其余的和text無關圖片,會用到LoadBitmap這個函數(shù):

1void ScreenRecoveryUI::LoadBitmapArray(const char* filename, int* frames, gr_surface** surface) {
2    int result = res_create_multi_display_surface(filename, frames, surface);
3    if (result < 0) {
4        LOGE("missing bitmap %s\n(Code %d)\n", filename, result);
5    }
6}

同樣調(diào)用到以下函數(shù):

1int res_create_multi_display_surface(const char* name, int* frames, GRSurface*** pSurface) {
2    GRSurface** surface = NULL;
3    int result = 0;
4    png_structp png_ptr = NULL;
5    png_infop info_ptr = NULL;
6    png_uint_32 width, height;
7    png_byte channels;
8    int i;
9    png_textp text;
10    int num_text;
11    unsigned char* p_row;
12    unsigned int y;
13
14    *pSurface = NULL;
15    *frames = -1;
16
17    result = open_png(name, &png_ptr, &info_ptr, &width, &height, &channels);
18    if (result < 0return result;
19
20    *frames = 1;
21    if (png_get_text(png_ptr, info_ptr, &text, &num_text)) {
22        for (i = 0; i < num_text; ++i) {
23            if (text[i].key && strcmp(text[i].key, "Frames") == 0 && text[i].text) {
24                *frames = atoi(text[i].text);
25                break;
26            }
27        }
28        printf("  found frames = %d\n", *frames);
29    }
30
31    if (height % *frames != 0) {
32        printf("bad height (%d) for frame count (%d)\n", height, *frames);
33        result = -9;
34        goto exit;
35    }
36
37    surface = reinterpret_cast<GRSurface**>(malloc(*frames * sizeof(GRSurface*)));
38    if (surface == NULL) {
39        result = -8;
40        goto exit;
41    }
42    for (i = 0; i < *frames; ++i) {
43        surface[i] = init_display_surface(width, height / *frames);
44        if (surface[i] == NULL) {
45            result = -8;
46            goto exit;
47        }
48    }
49
50#if defined(RECOVERY_ABGR) || defined(RECOVERY_BGRA)
51    png_set_bgr(png_ptr);
52#endif
53
54    p_row = reinterpret_cast<unsigned char*>(malloc(width * 4));
55    for (y = 0; y < height; ++y) {
56        png_read_row(png_ptr, p_row, NULL);
57        int frame = y % *frames;
58        unsigned char* out_row = surface[frame]->data +
59            (y / *frames) * surface[frame]->row_bytes;
60        transform_rgb_to_draw(p_row, out_row, channels, width);
61    }
62    free(p_row);
63
64    *pSurface = reinterpret_cast<GRSurface**>(surface);
65
66exit:
67    png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
68
69    if (result < 0) {
70        if (surface) {
71            for (i = 0; i < *frames; ++i) {
72                if (surface[i]) free(surface[i]);
73            }
74            free(surface);
75        }
76    }
77    return result;
78}

    關于圖片我們大概都知道怎么來顯示的了,所以,現(xiàn)在我們可以替換Android原生態(tài)中的圖片,換成我們自己的圖片,當然,也不是什么圖都可以的,在recovery中,所有的png圖片必須是RGB且不帶且不能帶alhpa通道信息。關于這一點,我們可以看open_png這個函數(shù):

 1static int open_png(const char* name, png_structp* png_ptr, png_infop* info_ptr,
2                    png_uint_32* width, png_uint_32* height, png_byte* channels)
 
{
3    char resPath[256];
4    unsigned char header[8];
5    int result = 0;
6    int color_type, bit_depth;
7    size_t bytesRead;
8
9    snprintf(resPath, sizeof(resPath)-1"/res/images/%s.png", name);
10    resPath[sizeof(resPath)-1] = '\0';
11    FILE* fp = fopen(resPath, "rb");
12    if (fp == NULL) {
13        result = -1;
14        goto exit;
15    }
16
17    bytesRead = fread(header, 1sizeof(header), fp);
18    if (bytesRead != sizeof(header)) {
19        result = -2;
20        goto exit;
21    }
22
23    if (png_sig_cmp(header, 0sizeof(header))) {
24        result = -3;
25        goto exit;
26    }
27
28    *png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULLNULLNULL);
29    if (!*png_ptr) {
30        result = -4;
31        goto exit;
32    }
33
34    *info_ptr = png_create_info_struct(*png_ptr);
35    if (!*info_ptr) {
36        result = -5;
37        goto exit;
38    }
39
40    if (setjmp(png_jmpbuf(*png_ptr))) {
41        result = -6;
42        goto exit;
43    }
44
45    png_init_io(*png_ptr, fp);
46    png_set_sig_bytes(*png_ptr, sizeof(header));
47    png_read_info(*png_ptr, *info_ptr);
48
49    png_get_IHDR(*png_ptr, *info_ptr, width, height, &bit_depth,
50            &color_type, NULLNULLNULL);
51
52    *channels = png_get_channels(*png_ptr, *info_ptr);
53
54    if (bit_depth == 8 && *channels == 3 && color_type == PNG_COLOR_TYPE_RGB) {
55        // 8-bit RGB images: great, nothing to do.
56    } else if (bit_depth <= 8 && *channels == 1 && color_type == PNG_COLOR_TYPE_GRAY) {
57        // 1-, 2-, 4-, or 8-bit gray images: expand to 8-bit gray.
58        png_set_expand_gray_1_2_4_to_8(*png_ptr);
59    } else if (bit_depth <= 8 && *channels == 1 && color_type == PNG_COLOR_TYPE_PALETTE) {
60        // paletted images: expand to 8-bit RGB.  Note that we DON'T
61        // currently expand the tRNS chunk (if any) to an alpha
62        // channel, because minui doesn't support alpha channels in
63        // general.
64        png_set_palette_to_rgb(*png_ptr);
65        *channels = 3;
66    } else {
67        fprintf(stderr"minui doesn't support PNG depth %d channels %d color_type %d\n",
68                bit_depth, *channels, color_type);
69        result = -7;
70        goto exit;
71    }
72
73    return result;
74
75  exit:
76    if (result < 0) {
77        png_destroy_read_struct(png_ptr, info_ptr, NULL);
78    }
79    if (fp != NULL) {
80        fclose(fp);
81    }
82
83    return result;
84}

在代碼中,我們可以看到如下:

1 if (bit_depth == 8 && *channels == 3 && color_type == PNG_COLOR_TYPE_RGB) {
2        // 8-bit RGB images: great, nothing to do.
3    } else if (bit_depth <= 8 && *channels == 1 && color_type == PNG_COLOR_TYPE_GRAY) {
4        // 1-, 2-, 4-, or 8-bit gray images: expand to 8-bit gray.
5        png_set_expand_gray_1_2_4_to_8(*png_ptr);
6    } else if (bit_depth <= 8 && *channels == 1 && color_type == PNG_COLOR_TYPE_PALETTE) {
7        // paletted images: expand to 8-bit RGB.  Note that we DON'T
8        // currently expand the tRNS chunk (if any) to an alpha
9        // channel, because minui doesn't support alpha channels in
10        // general.
11        png_set_palette_to_rgb(*png_ptr);
12        *channels = 3;
13    } else {
14        fprintf(stderr"minui doesn't support PNG depth %d channels %d color_type %d\n",
15                bit_depth, *channels, color_type);
16        result = -7;
17        goto exit;
18    }

以下參考一位網(wǎng)友給出的解決方案。

    這個函數(shù)將圖片文件的數(shù)據(jù)讀取到內(nèi)存,我在其中輸出了一些調(diào)試信息,輸出圖片的 color_type, channels 等信息。查看LOG發(fā)現(xiàn),android原生的圖片 channels == 3,channels 即色彩通道個數(shù),等于 3 的話,意味著只有 R,G,B 三個通道的信息,沒有 ALPHA 通道信息!這段代碼的邏輯是如果channels 不等于3, 則按channels = 1 來處理,即灰度圖。美工給的圖片是帶 alpha通道信息的,即channels = 4,被當成灰度圖像來處理了,怪不得顯示的效果是灰度圖像。我一直以為 png 圖像就只有一種格式,都是帶有 alpha通道的。。。使用圖像處理工具(photoshop 或者 gimp),將美工給的圖片去掉 alpha 通道信息,再替換recovery 的圖片,編譯,替換recovery.img ,reboot -r 。圖片終于正常顯示啦。

韋東山老師課程推薦








商務合作

支持我請給我在看!


免責聲明:本文內(nèi)容由21ic獲得授權(quán)后發(fā)布,版權(quán)歸原作者所有,本平臺僅提供信息存儲服務。文章僅代表作者個人觀點,不代表本平臺立場,如有問題,請聯(lián)系我們,謝謝!

本站聲明: 本文章由作者或相關機構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點,本站亦不保證或承諾內(nèi)容真實性等。需要轉(zhuǎn)載請聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請及時聯(lián)系本站刪除。
換一批
延伸閱讀

LED驅(qū)動電源的輸入包括高壓工頻交流(即市電)、低壓直流、高壓直流、低壓高頻交流(如電子變壓器的輸出)等。

關鍵字: 驅(qū)動電源

在工業(yè)自動化蓬勃發(fā)展的當下,工業(yè)電機作為核心動力設備,其驅(qū)動電源的性能直接關系到整個系統(tǒng)的穩(wěn)定性和可靠性。其中,反電動勢抑制與過流保護是驅(qū)動電源設計中至關重要的兩個環(huán)節(jié),集成化方案的設計成為提升電機驅(qū)動性能的關鍵。

關鍵字: 工業(yè)電機 驅(qū)動電源

LED 驅(qū)動電源作為 LED 照明系統(tǒng)的 “心臟”,其穩(wěn)定性直接決定了整個照明設備的使用壽命。然而,在實際應用中,LED 驅(qū)動電源易損壞的問題卻十分常見,不僅增加了維護成本,還影響了用戶體驗。要解決這一問題,需從設計、生...

關鍵字: 驅(qū)動電源 照明系統(tǒng) 散熱

根據(jù)LED驅(qū)動電源的公式,電感內(nèi)電流波動大小和電感值成反比,輸出紋波和輸出電容值成反比。所以加大電感值和輸出電容值可以減小紋波。

關鍵字: LED 設計 驅(qū)動電源

電動汽車(EV)作為新能源汽車的重要代表,正逐漸成為全球汽車產(chǎn)業(yè)的重要發(fā)展方向。電動汽車的核心技術(shù)之一是電機驅(qū)動控制系統(tǒng),而絕緣柵雙極型晶體管(IGBT)作為電機驅(qū)動系統(tǒng)中的關鍵元件,其性能直接影響到電動汽車的動力性能和...

關鍵字: 電動汽車 新能源 驅(qū)動電源

在現(xiàn)代城市建設中,街道及停車場照明作為基礎設施的重要組成部分,其質(zhì)量和效率直接關系到城市的公共安全、居民生活質(zhì)量和能源利用效率。隨著科技的進步,高亮度白光發(fā)光二極管(LED)因其獨特的優(yōu)勢逐漸取代傳統(tǒng)光源,成為大功率區(qū)域...

關鍵字: 發(fā)光二極管 驅(qū)動電源 LED

LED通用照明設計工程師會遇到許多挑戰(zhàn),如功率密度、功率因數(shù)校正(PFC)、空間受限和可靠性等。

關鍵字: LED 驅(qū)動電源 功率因數(shù)校正

在LED照明技術(shù)日益普及的今天,LED驅(qū)動電源的電磁干擾(EMI)問題成為了一個不可忽視的挑戰(zhàn)。電磁干擾不僅會影響LED燈具的正常工作,還可能對周圍電子設備造成不利影響,甚至引發(fā)系統(tǒng)故障。因此,采取有效的硬件措施來解決L...

關鍵字: LED照明技術(shù) 電磁干擾 驅(qū)動電源

開關電源具有效率高的特性,而且開關電源的變壓器體積比串聯(lián)穩(wěn)壓型電源的要小得多,電源電路比較整潔,整機重量也有所下降,所以,現(xiàn)在的LED驅(qū)動電源

關鍵字: LED 驅(qū)動電源 開關電源

LED驅(qū)動電源是把電源供應轉(zhuǎn)換為特定的電壓電流以驅(qū)動LED發(fā)光的電壓轉(zhuǎn)換器,通常情況下:LED驅(qū)動電源的輸入包括高壓工頻交流(即市電)、低壓直流、高壓直流、低壓高頻交流(如電子變壓器的輸出)等。

關鍵字: LED 隧道燈 驅(qū)動電源
關閉