android 2D skia庫 簡單應用

來源:互聯網
上載者:User

1 Skia 繪圖概述

 

Skia 是 Google 一個底層的圖形、文本、映像、動畫等多方面的圖形庫,是 Android 中圖形系統的引擎。 Skia 作為第三方軟體放在 external 目錄下: external/skia/ 。 skia 的源檔案及部分標頭檔都在 src 目錄下,匯出的標頭檔在 include 目錄下。

使用 Skia 的 API 進行圖形繪製時主要會用到一下幾個類:

SkBitmap 、 SkCanvas 、 SkPaint 和 SkRect ,其中 SkBitmap 用來設定像素, SkCanvas 寫入位元影像, SkPaint 設定顏色和樣式, SkRect 用來繪製矩形。其實現代碼主要在 src/core 目錄下。

 

2 使用 Skia 繪圖的步驟

 

a) 定義一個位元影像 32 位像素並初始化
SkBitmap bitmap;

bitmap.setConfig(SkBitmap::kARGB_8888_Config, 200, 200);

其中 setConfig 為設定位元影像的格式,原型為 void setConfig(Config, int width, int height, int rowBytes = 0)

Config 為一個資料結構
enum Config {
kNo_Config, // 不確定的位元影像格式
kA1_Config, //1 位 ( 黑 , 白 ) 位元影像
kA8_Config, //8 位 ( 黑 , 白 ) 位元影像
kIndex8_Config, // 類似 windows 下的色彩索引表,具體請查看 SkColorTable 類結構
kRGB_565_Config, //16 位象素 565 格式位元影像,詳情請查看 SkColorPriv.h 檔案
kARGB_4444_Config, //16 位象素 4444 格式位元影像,詳情請查看 SkColorPriv.h 檔案
kARGB_8888_Config, //32 位象素 8888 格式位元影像,詳情請查看 SkColorPriv.h 檔案
kRLE_Index8_Config,
kConfigCount
};

b) 分配位元影像所佔的空間

bitmap.allocPixels()
其實 allocPixels 為重載函數,原型為 bool allocPixels(SkColorTable* ctable = NULL)
參數 ctable 為色彩索引表,一般情況下為 NULL 。

c) 指定輸出裝置

SkCanvas canvas(new SkDevice(bitmap));
其中 canvas 為一個多建構函式,原型為

explicit SkCanvas(const SkBitmap& bitmap) ,

explicit SkCanvas(SkDevice* device = NULL)
explicit 關健字的意思為:不允許類型轉換
輸出裝置可以為一個上下文 Device, 也可以指定為一張位元影像。

d) 裝置繪製的風格
Paint paint;
SkRect r;
paint.setARGB(255, 255, 0, 0);
r.set(25, 25, 145, 145);
canvas.drawRect(r, paint);
paint 可以指定繪圖的顏色,文本的大小及對齊,編碼格式等等,因為以前位元影像的格式設定為 kARGB_8888_Config ,所以這裡要設定繪製的顏色 setARGB(255, 255, 0, 0) ,第一位參數為透明色彩通道,其它三位分別為 R 、 G 、 B 。 r 設定要繪製的範圍,最後通過 drawRect 繪製出指定地區的一個方形。

這樣,一個紅色的矩形就繪製成功了。

SkCanvas 主要完成三種繪製功能:

a 基本圖形繪製 ( 如 drawARGB,drawLine 函數 )

b 影像檔繪製( drawBitmap 函數)

c 文本繪製( drawText 函數)

相關 API 有:

canvas.drawRect(rect, paint);
         canvas.drawOval(oval, paint);
         canvas.drawCircle(x, y, radius, paint);
         canvas.drawRoundRect(rect, rx, ry, paint);
         canvas.drawPath(path, paint);
         canvas.drawBitmap(bitmap, x, y, &paint);
         canvas.drawBitmapRect(bitmap, &srcRect, dstRect, &paint);
         canvas.drawBitmapMatrix(bitmap, matrix, &paint);
         canvas.drawText(text, length, x, y, paint);
         canvas.drawPosText(text, length, pos[], paint);
         canvas.drawTextOnPath(text, length, path, paint);

e)

常式

 

i )畫點、線、圓、文字

#include "SkBitmap.h"

#include "SkDevice.h"

#include "SkPaint.h"

#include "SkRect.h"

#include "SkImageEncoder.h"

#include "SkTypeface.h"

 

using namespace std;

 

int main()

{

SkBitmap bitmap;

bitmap.setConfig(SkBitmap::kARGB_8888_Config,320,240);

bitmap.allocPixels();

SkCanvas canvas(new SkDevice(bitmap));

SkPaint paint;

// draw points with red.

paint.setARGB(255, 255, 0, 0);

paint.setStrokeWidth(4);

canvas.drawPoint(40,30, paint);

canvas.drawPoint(80,60, paint);

canvas.drawPoint(120,90, paint);

//draw a line with green.

paint.setARGB(255, 0, 255, 0);

paint.setStrokeWidth(4);

canvas.drawLine(160,10,320,110,paint);

//draw a circle with bule.

paint.setARGB(255, 0, 0, 255);

canvas.drawCircle(80,180,50,paint);

//draw text with red

SkTypeface *font = SkTypeface::CreateFromFile("simkai.ttf");

if ( font )

{

paint.setARGB(255, 255, 0, 0);

paint.setTypeface( font );

paint.setTextSize(24);

canvas.drawText("HELLO!:)", 8, 200, 180, paint);

}

SkImageEncoder::EncodeFile("snapshot.png", bitmap,SkImageEncoder::kPNG_Type,100);

return 0;

}

程式執行後,得到如下輸出結果:

 

 

 

ii) 映像的編解碼

該常式目前測試只支援 .png 格式的圖片, .jpg 還不支援,還未找到原因。

#include "SkBitmap.h"

#include "SkDevice.h"

#include "SkPaint.h"

 

#include "SkRect.h"

#include "SkImageEncoder.h"

#include "SkImageDecoder.h"

#include <iostream>

 

using namespace std;

 

int main()

{

int ret = -1;

SkBitmap bitmap;

 

//SkImageDecoder

ret = SkImageDecoder::DecodeFile("./old.png", &bitmap);

cout<< "get the decode type = "<< bitmap.config() << endl;

 

//SkImageEncoder

ret = SkImageEncoder::EncodeFile("new1.png",bitmap,SkImageEncoder::kPNG_Type,100);

cout<< "encode data to png result = "<< ret<< endl;

 

return 0;

}

SkImageDecoder::DecodeFile("./old.png", &bitmap);

將 png 轉換成位元影像格式,並將資料放到 bitmap 變數中
SkImageEncoder::EncodeFile("snapshot.png", bitmap,SkImageEncoder::kPNG_Type,/* Quality ranges from 0..100 */ 100);

將 bitmap 中的資料編碼輸出為 .png 格式,第一位參數為 png 檔案路徑,第二位為指定的輸出位元影像,第三位為檔案的類型,第四位參數指定了輸出位元影像的品質,範圍為 0..100 ,預設為 80 。

 

3 圖形映像特效

src/effects 目錄的檔案主要實現一些圖形映像的特效,包括 遮罩、浮雕、模糊、濾鏡、漸層色、離散、透明以及 PATH 的各種特效等。

 

4 動畫

src/animator 目錄的檔案主要實現了 Skia 的動畫效果,Android不支援。

 

5 介面 UI 庫

src/view 目錄 構建了一套介面 UI 庫。
組件包括 Window,Menu, TextBox, ListView, ProgressBar, Widget, ScrollBar,TagList,Image 等。

 

6 其它

a) src/gl 目錄: 這部分是 skia 調用 OpenGL 或 OpenGL ES 來實現 3D 效果。
如果定義了 MAC ,則使用 OpenGL ,如果定義了 Android ,則使用嵌入式 系統 上的 esgl 三維圖形庫。

b)src/images 目錄: 主要是 SkImageDecoder 和 SkImageEncoder 以及 SkMovie 。主要是用來處理 images 的,能處理的映像類型包括: BMP 、

JPEG/PVJPEG 、 PNG 、 ICO ,而 SkMovie 是用來處理 gif 動畫的。

c) src/opts 目錄:效能最佳化的代碼。

d) src/pdf 目錄: 處理 PDF 文檔,用了一個 fpdfemb 庫。

e) src/ports 目錄: 這部分是 skia 的一些介面在不同系統上的實現,平台相關的代碼,比如字型、線程、時間等, 主要包括幾個部分: Font , Event , File , Thread , Time , XMLParser

這些與 Skia 的介面,需要針對不同的 作業系統 實現。

f) src/svg 目錄:   向量映像,Android不支援。
SkSVGPath, SkSVGPolyline, SkSVGRect, SkSVGText, SkSVGLine, SkSVGImage, SkSVGEllipse 等等。

g) src/text 目錄:???

h) src/utils 目錄: 是一些協助工具輔助類。
SkCamera, SkColorMatrix,SkOSFile,SkProxyCanvas,SkInterpolator 等檔案。

i) src/xml : 這是處理 xml 資料的部分, skia 在這裡只是對 xml 解析器做了一層封裝,具體的 xml 解析器的實現需要根據不同的作業系統及宿主程式來實現。

j) Third-party library

除了自身的所有檔案外, skia 還使用了一些 third-party library 以及包含了不少 linux 上的標頭檔。

通過分析 skia 來源程式,發現 skia 主要使用以下幾個第三方庫:
Zlib ,處理資料的壓縮和解壓縮
Jpeglib ,處理 jpeg 映像的編碼解碼
Pnglib ,處理 png 映像的編碼解碼
giflib ,處理 gif 映像
fpdfemb ,處理 pdf 文檔

skia 還需要一些 linux/unix 下的標頭檔(可能還需要更多):
stdint.h
unistd.h
features.h
cdefs.h
stubs.h
posix_opt.h
types.h
wordsize.h
typesizes.h
confname.h
getopt.h
mman.h

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

Tags Index: