一、Skia介紹
Skia是一個(ge)2D圖(tu)形庫,主(zhu)要用于繪制(zhi)文本、幾何圖(tu)形和圖(tu)像(xiang),android中的(de)2d圖(tu)像(xiang)也使用了skia。
二、Android中使用Skia繪制代碼(ma)實現
Skia的(de)繪制和平時使用Canvas 會話類似。也涉及到畫(hua)布、畫(hua)筆等。aosp中(zhong)的(de)代碼位于"external/skia/"中(zhong),在Android9中(zhong)skia被編(bian)譯成一(yi)個(ge)靜(jing)態的(de)庫。"external/skia/samplecode/"目錄(lu)下會有一(yi)些(xie)示例代碼。
下面在andorid中使(shi)用skia繪制(zhi)一個hello + 數字的簡單測試程序。
頭文件:
#ifndef SKIA_TEST_H
#define SKIA_TEST_H
#include <SkBitmap.h>
#include <SkCanvas.h>
#include <SkTypeface.h>
#include <android/log.h>
#include <binder/ProcessState.h>
#include <binder/IPCThreadState.h>
#include <system/window.h>
#include <ui/GraphicBuffer.h>
#include <ui/Fence.h>
#include <utils/Log.h>
#include <utils/RefBase.h>
#include <gui/SurfaceControl.h>
#include <gui/SurfaceComposerClient.h>
#include <binder/IBinder.h>
#include <ui/DisplayInfo.h>
#include <gui/Surface.h>
#include <SkBitmap.h>
#include <SkCanvas.h>
#include <SkTypeface.h>
/**
 * 參考:
 * frameworks/native/opengl/tests/lib/WindowSurface.cpp
*/
#ifndef ANDROID_LOG_TAG
#define ANDROID_LOG_TAG "test"
#endif
#define LD(...) __android_log_print(ANDROID_LOG_DEBUG, ANDROID_LOG_TAG, __VA_ARGS__)
using namespace android;
class SkiaTest
{
public:
    SkiaTest();
    ~SkiaTest();
    void showText();
};
#endif主文件:
#include<SkiaTest.h>
SkiaTest::SkiaTest()
{
    LD("construct SkiaTest.");
}
SkiaTest::~SkiaTest()
{
    LD("destroy SkiaTest.");
}
void SkiaTest::showText()
{
    sp<SurfaceComposerClient> mSurfaceComposerClient = new SurfaceComposerClient();
    sp<IBinder> dtoken(SurfaceComposerClient::getBuiltInDisplay(0));
    DisplayInfo dinfo;
    status_t status = SurfaceComposerClient::getDisplayInfo(dtoken, &dinfo);
    if (status != NO_ERROR)
    {
        LD("Get Display info error status %d ", status);
        return;
    }
    sp<SurfaceControl> mSurfaceControl =
        mSurfaceComposerClient->createSurface(String8("test"),
                                              dinfo.w / 2, dinfo.h / 2,
                                              PIXEL_FORMAT_RGBA_8888,
                                              0 /*ISurfaceComposerClient::eHidden*/);
    if (mSurfaceControl == NULL || !mSurfaceControl->isValid())
    {
        LD("get SurfaceControl err....");
        return;
    }
    SurfaceComposerClient::Transaction{}
        .setLayer(mSurfaceControl, 0x7FFFFFFF)
        .setPosition(mSurfaceControl,  0,  0)
        .show(mSurfaceControl)
        .apply();
    SkPaint paint;
    paint.setTextSize(28);
    paint.setColor(SK_ColorRED);
    if (mSurfaceControl == nullptr)
    {
        LD("Surface control not construct successful.");
        return;
    }
    sp<Surface> surface = mSurfaceControl->getSurface();
    ANativeWindow_Buffer outBuffer;
    SkImageInfo info = SkImageInfo::Make(dinfo.w/2, dinfo.h/2, kN32_SkColorType,
                                         kPremul_SkAlphaType);
    ssize_t bpr;
    for (int i = 0; i < 10; i++)
    {
        surface->lock(&outBuffer, NULL);
        bpr = outBuffer.stride * bytesPerPixel(outBuffer.format);
        SkBitmap bitmap;
        bitmap.installPixels(info, outBuffer.bits, bpr);
        SkCanvas canvas(bitmap);
        std::string tmp = "hello " + std::to_string(i);
        canvas.clear(SK_ColorTRANSPARENT);
        canvas.drawColor(SK_ColorWHITE);
        canvas.drawText(tmp.c_str(), tmp.length(), 0, dinfo.h / 4, paint);
        surface->unlockAndPost();
        LD("finnish");
        sleep(2);
    }
    return;
}三、運行(xing)&截圖
adb push skiatest /data/local/tmp
 ./skiatest
