Android_skia学习

源码位置:android/external/skia

 

Android Java 2D作图主要通过JNI调用skia图形库完成。Canvas是个2D的概念,在skia中可以把这个canvas理解成系统提供给我们的一块内存区域,但实际上它只是一套绘图API,真正的内存是下面的Bitmap,skia 提供一个bitmap对象。在surface上绘制UI,通过lock来获取surface对应的数据buffer,并当做skia bitmap的内存,unlockandpost来通知Surfaceflinger来输出显示。

SkBitmap用来设置像素。SkCanvas执行写入操作。SkPaint相当于画笔,用来设置颜色(color), 字体(typeface), 文字大小(textSize), 文字粗细(strokeWidth), 渐变(gradients, patterns)等。

int main(int argc, char **argv)
{
	// create a client to surfaceflinger  
	sp<SurfaceComposerClient> client = new SurfaceComposerClient();
	sp<IBinder> dtoken(SurfaceComposerClient::getBuiltInDisplay(
						ISurfaceComposer::eDisplayIdMain));

	DisplayInfo dinfo;  
	status_t status = SurfaceComposerClient::getDisplayInfo(dtoken, &dinfo);
	printf("w=%d,h=%d,xdpi=%f,ydpi=%f,fps=%f,ds=%f\n",
				dinfo.w, dinfo.h, dinfo.xdpi, dinfo.ydpi, dinfo.fps, dinfo.density);

	sp<SurfaceControl> surfaceControl = 
			client->createSurface(String8("debugview"),
			dinfo.w, dinfo.h, 
			PIXEL_FORMAT_RGBA_8888, 
			0/*ISurfaceComposerClient::eHidden*/);

	surfaceControl;
	
	SurfaceComposerClient::openGlobalTransaction();
	surfaceControl->setLayer(100000);
	surfaceControl->setPosition(20, 20);
	//surfaceControl->setAlpha(0.3f);
	//surfaceControl->setSize(800, 800);
	//surfaceControl->setSize(1500, 1000);
	//Rect rect(900,900,900,900);
	//Region region(rect);
	//surfaceControl->setTransparentRegionHint(region);
	SurfaceComposerClient::closeGlobalTransaction(); 
	surfaceControl->show();
	sp<Surface> surface = surfaceControl->getSurface();

	ANativeWindow_Buffer outBuffer;  
	//Surface::SurfaceoutBuffer outBuffer;
	//surface->lock(&outBuffer,NULL);//
	//ssize_t bpr = outBuffer.stride * bytesPerPixel(outBuffer.format);
	//android_memset16((uint16_t*)outBuffer.bits, 0xF800, bpr*outBuffer.height);
	//surface->unlockAndPost();
	//sleep(1);  

	ssize_t bpr;
	SkBitmap bitmap;
	
	//SkImageInfo info = SkImageInfo::MakeN32Premul(512, 512)
	//SkImageInfo info = SkImageInfo::Make(512, 512, 
	//           kN32_SkColorType, 
	//           kOpaque_SkAlphaType);
	SkImageInfo info = SkImageInfo::Make(512, 512, 
						kN32_SkColorType, 
						kPremul_SkAlphaType);
		
	surface->lock(&outBuffer, NULL);
	bpr = outBuffer.stride * bytesPerPixel(outBuffer.format);
	bitmap.installPixels(info, outBuffer.bits, bpr);
	SkCanvas canvas(bitmap);
	canvas.clear(SK_ColorTRANSPARENT);
	SkPaint paint;
	paint.setTextSize(28);
	paint.setColor(SK_ColorBLACK);
	//canvas.drawColor(SK_ColorRED);
	const char *str = "aaaaaaaaaaaaaaaaaaE";
	canvas.drawText(str, strlen(str), 8, 28, paint);
	surface->unlockAndPost();
	sleep(3);

#if 0
	SurfaceComposerClient::openGlobalTransaction();
	surfaceControl->setLayer(100000);
	surfaceControl->setPosition(0, 0);
	SurfaceComposerClient::closeGlobalTransaction();
	surfaceControl->show();

	sp<Surface> surface = surfaceControl->getSurface();

	ANativeWindow_Buffer outBuffer;
	surface->lock(&outBuffer,NULL);
	ssize_t bpr = outBuffer.stride * bytesPerPixel(outBuffer.format);
	android_memset16((uint16_t*)outBuffer.bits, 0xF800, bpr*outBuffer.height);
	surface->unlockAndPost();
	sleep(3);

	SurfaceComposerClient::openGlobalTransaction();
	surfaceControl->setSize(480, 272);
	surfaceControl->setPosition(100, 100);
 	SurfaceComposerClient::closeGlobalTransaction();
	surfaceControl->show();
	FILE *fp = fopen("/tmp/rgb565.rgb","rb");
	if(fp != NULL){
		unsigned char *rgb565Data = new unsigned char[480*272*2];
		memset(rgb565Data,0x00,480*272*2);
		fread(rgb565Data,1,480*272*2,fp);
		surface->lock(&outBuffer,NULL);
		memcpy(outBuffer.bits,rgb565Data,480*272*2);
		delete[] rgb565Data;
		surface->unlockAndPost();
	}
	fclose(fp);
	sleep(3);

	SurfaceComposerClient::openGlobalTransaction();
	surfaceControl->setSize(320, 420);
	surfaceControl->setPosition(100, 100);
	SurfaceComposerClient::closeGlobalTransaction();
	surfaceControl->show();
	SkPaint paint;
	paint.setColor(SK_ColorBLUE);
	Rect rect(0, 0, 320, 240);
	Region dirtyRegion(rect);
	surface->lock(&outBuffer, &rect);
	bpr = outBuffer.stride * bytesPerPixel(outBuffer.format);
	SkBitmap bitmap;
	bitmap.setConfig(convertPixelFormat(outBuffer.format), 320, 240, bpr);
	bitmap.setPixels(outBuffer.bits);
	SkCanvas canvas;
	SkRegion clipReg;
	const Rect b(dirtyRegion.getBounds());
	clipReg.setRect(b.left, b.top, b.right, b.bottom);
	canvas.clipRegion(clipReg);
	canvas.drawARGB(0, 0xFF, 0x00, 0xFF);
	canvas.drawCircle(200, 200, 100, paint);
	bitmap.notifyPixelsChanged();
	surface->unlockAndPost();
	sleep(3);

	SkFILEStream stream("/tmp/test.jpg");
	SkImageDecoder* codec = SkImageDecoder::Factory(&stream);
	if(codec){
		SkBitmap bmp;
		stream.rewind();
		codec->decode(&stream, &bmp, 
				SkBitmap::kRGB_565_Config, 
				SkImageDecoder::kDecodePixels_Mode);
		surface->lock(&outBuffer,NULL);
		bpr = outBuffer.stride * bytesPerPixel(outBuffer.format);
		bitmap.setConfig(convertPixelFormat(outBuffer.format), 320, 240, bpr);
		bitmap.setPixels(outBuffer.bits);
		canvas.drawBitmap(bmp, SkIntToScalar(200), SkIntToScalar(300));
		surface->unlockAndPost();
		sleep(3);
	}	
#endif

	return 0;
} 

设置字体

SkTypeface *font = SkTypeface::CreateFromFile("xxx.otf");
if(font){
    paint.setARGB(255, 255, 0, 0);
    paint.setTypeface(font);
    paint.setTextSize(25);
    canvas.drawText("abc", 3, 20, 20, paint);
}

还可以使用SkTypeface::CreateFromName创建face,skia会遍历SK_FONT_FILE_PREFIX宏所指示的目录下所有*.ttf字库文件,并将其加载内存的。

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值