一、Skia介绍
Skia是一个2D图形库,主要用于绘制文本、几何图形和图像,android中的2d图像也使用了skia。
二、Android中使用Skia绘制代码实现
Skia的绘制和平时使用Canvas 会话类似。也涉及到画布、画笔等。aosp中的代码位于"external/skia/"中,在Android9中skia被编译成一个静态的库。"external/skia/samplecode/"目录下会有一些示例代码。
下面在andorid中使用skia绘制一个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;
}
三、运行&截图
adb push skiatest /data/local/tmp
./skiatest