天天看點

LittlevGL圖形架構擴充 - JPEG圖檔的支援JPEG圖像的解壓縮操作過程為JPEG對象配置設定空間并初始化開發者支援

轉自HaaS技術社群

在輕量級RTOS GUI圖形庫中,LittlevGL是一個使用C語言開發,開源免費的GUI,支援觸摸屏,滑鼠,鍵盤多種操作,移植簡單友善,在豐富的控件基礎上還可以自定義控件,開發者一直在不斷完善更新,相對于其他GUI,LittlevGL在硬體資源不足(RAM < 100kbytes)的情況下存在較大的優勢,在240*240的顯示屏上顯示一張圖檔,RAM緩沖區設定為2Kbytes即可。

AliOS Things 目前最新版本已經內建LittlevGL,并且在智能穿戴裝置項目上已商用。

LittlevGL圖形架構擴充 - JPEG圖檔的支援JPEG圖像的解壓縮操作過程為JPEG對象配置設定空間并初始化開發者支援

LittlevGL對于圖檔跟字型的使用是預先要使用外部工具,對圖檔跟字型轉成二進制檔案,然後直接使用,在一些簡單固定顯示的應用場景是可以滿足的,而且對記憶體消耗會比較少。但是在一些複雜的應用場景就無法滿足了,比如相機應用中拍照生成的圖檔格式大多為JPEG的,相冊中顯示圖檔就無法提前進行轉換,或者遇到服務端下發JEPG圖檔情況,是以需要對LittlevGL進行擴充。

開源libJPEG庫是用于編碼資料為JPEG格式或者解碼JPEG格式圖檔的常用庫,而libJPEG-turbo則效率更高。考慮到未來除了需要解碼JPEG可能還會遇到需要壓縮JPEG圖檔的場景,是以最終使用libJPEG-turbo來豐富LittlevGL對圖檔支援。

JPEG圖像的解壓縮操作過程

1.為JPEG對象配置設定空間并初始化

2.指定解壓縮資料源

3.擷取檔案資訊

4.為解壓縮設定參數,包括圖像大小,顔色空間

5.開始解壓縮

6.取出資料

7.解壓縮完畢

8.釋放資源

為JPEG對象配置設定空間并初始化

解壓縮過程中使用的JPEG對象是一個jpeg_decompress_struct的結構體。同時還需要定義一個用于錯誤處理的結構體對象,标準的錯誤結構體是jpeg_error_mgr。

#if !USE_LV_DRAW_IMG_JPEG_DECODER_HW_MODE
 
static struct jpeg_decompress_struct jpeg_info;
 
static struct jpeg_error_mgr jpeg_error_mgr;
 
#endif           

初始化jpeg_info結構,并将錯誤處理結構對象綁定在JPEG對象上,這個标準的錯誤處理結構将使程式在出現error時調用exit退出程式,如果不希望使用标準的錯誤處理方式,則可以通過自定義退出函數的方法自定義錯誤處理結構。

jpeg_create_decompress(&jpeg_info);
 
    jpeg_info.err = jpeg_std_error(&jpeg_error_mgr);
 
    jpeg_error_mgr.error_exit = jpeg_error_exit;           

對jpeg_info配置設定記憶體并将圖檔的預設資訊填充到jpeg_info。

jpeg_mem_src(&jpeg_info, data_buf, img_dsc->data_size);
 
 
    if(jpeg_read_header(&jpeg_info, TRUE) == -1) {
 
        LOGE("lv_img_decoder_open_jpeg: read header err !!\n");
 
        if(from_file == 1) {
 
            jpeg_free(data_buf);
 
            data_buf = NULL;
 
        }
 
        return LV_IMG_DECODER_OPEN_FAIL;
 
    }           

此時,常見的可用資訊包括圖像的寬jpeg_info.image_width,高jpeg_info.image_height,色彩空間jpeg_info.jpeg_color_space,顔色通道數jpeg_info.num_components等。在完成jpeg_read_header調用後,開始解壓縮之前就可以進行解壓縮參數的設定,也就是為jpeg_info結構的成員指派。

可以設定解出來的圖像與原圖的比例,也可以設定輸出圖像的色彩空間,即cinfo.out_color_space。原圖比例是使用scale_num和scale_denom兩個參數,解出來的圖像大小就是scale_num/scale_denom,目前僅支援1/1, 1/2, 1/4,和1/8這幾種縮小比例,如果沒有額外要求,以上參數使用預設即可。

比如要取得1/2原圖的圖像,把一個原本彩色的圖像由真彩色JCS_RGB變為灰階JCS_GRAYSCALE。需要如下設定:

jpeg_info.scale_num=1;
 
    jpeg_info.scale_denom=2;
 
    jpeg_info.out_color_space=JCS_GRAYSCALE;           

根據設定的解壓縮參數進行圖像解壓縮操作。

if((jpeg_start_decompress(&jpeg_info) == false) || (jpeg_err == 1)) {
 
        LOGE("lv_img_decoder_open_jpeg: decompress failed !!\n");
 
        if(from_file == 1) {
 
            jpeg_free(data_buf);
 
            data_buf = NULL;
 
        }
 
        return LV_IMG_DECODER_OPEN_FAIL;
 
    }           

在完成解壓縮操作後,要開始為取走資料做準備,将解壓後的圖像資訊填充至jpeg_info結構中。比如,輸出圖像寬度jpeg_info.output_width,輸出圖像高度jpeg_info.output_height,每個像素中的顔色通道數jpeg_info.output_components(比如灰階為1,全彩色為3)等。一般情況下,這些參數是在jpeg_start_decompress執行後才被填充到jpeg_info中的,如果希望在調用jpeg_start_decompress之前就獲得這些參數,可以通過調用jpeg_calc_output_dimensions()的方法來實作。

uint8_t *rgb888_buf = NULL;
 
    uint32_t out_buffer_size = jpeg_info.image_width*jpeg_info.image_height*jpeg_info.num_components;
 
    rgb888_buf = jpeg_malloc(out_buffer_size, 0);
 
    if(rgb888_buf == NULL) {
 
        LOGI("lv_img_decoder_open_jpeg: no enough memory!!\n");
 
        goto err;
 
    }           

解壓縮的資料是按照行取出的,資料像素按照scanline來存儲,scanline是從左到右,從上到下的順序,每個像素對應的各顔色或灰階通道資料是依次存儲,比如一個24-bitRGB真彩色的圖像中,一個scanline中的資料存儲模式是R,G,B,R,G,B,R,G,B,...,每條scanline是一個JSAMPLE類型的數組,一般來說就是unsigned char,定義于jmorecfg.h中。除了JSAMPLE,IJG還定義了JSAMPROW和JSAMPARRAY,分别表示一行JSAMPLE和一個2D的JSAMPLE數組。

jpeg_info.output_scanline表示目前已經讀取的行數,如此即可依次讀出圖像的所有資料,并填充到緩沖區中。

while (jpeg_info.output_scanline<jpeg_info.output_height)
 
    {
 
        JSAMPROW out_str  = (JSAMPROW)(rgb888_buf +
 
                     jpeg_info.output_scanline*jpeg_info.image_width*jpeg_info.num_components);
 
        if((jpeg_read_scanlines(&jpeg_info, &out_str, 1) != 1) || (jpeg_err == 1)) {
 
            LOGE("lv_img_decoder_open_jpeg: scan line failed!!\n");
 
            jpeg_free((void *)rgb888_buf);
 
            goto err;
 
        }
 
    }           

解壓縮完畢調用jpeg_finish_decompress,然後釋放jpeg_destroy_decompress

jpeg_finish_decompress(&jpeg_info);
 
        jpeg_destroy_decompress(&jpeg_info);           

開發者支援

如需更多技術支援,可加入釘釘開發者群,或者關注微信公衆号。

LittlevGL圖形架構擴充 - JPEG圖檔的支援JPEG圖像的解壓縮操作過程為JPEG對象配置設定空間并初始化開發者支援

更多技術與解決方案介紹,請通路HaaS官方網站

https://haas.iot.aliyun.com

繼續閱讀