Android NDK 使用skia 画图及显示图片的例子

时间:2023-02-10 20:48:27

  经过查阅资料以及自己尝试,终于实现了在Android NDK 画图和打开并显示图片。现将自己的测试代码以及使用过程中的心得写下,希望与大家交流一下。

  首先,测试程序的运行结果如下图所示:

Android NDK 使用skia 画图及显示图片的例子

调用DrawJpg打开模拟器中的一张Jpg格式的图片并显示

 

Android NDK 使用skia 画图及显示图片的例子

调用DrawFlag函数画出来的旗帜

 

下面是具体的代码实现。其中,传递到JNI端的是Canvas。运行的模拟器是Android4.0。Android源码的下载是使用git工具,采用如下命令下载的。

git clone https://android.googlesource.com/platform/external/skia -b android-4.0.1_r1

git clone https://android.googlesource.com/platform/frameworks/base -b android-4.0.1_r1

git clone https://android.googlesource.com/platform/system/core -b android-4.0.1_r1

libskia.so等均是通过DDMS从Android4.0的模拟机上Pull下来的。注意,Android源码和使用的so库的版本必须是一致的。否则,会出现编译出错,只能画线不能画字等错误。

显示的图片是使用DDMS push到Android模拟机上的,放在sdcard目录下。

 

//com_Test1.h

//JNI 端的头文件,两个函数

/* DO NOT EDIT THIS FILE - it is machine generated */

#include <jni.h>

/* Header for class com_Test1 */

#ifndef _Included_com_example_test_MainActivity

#define _Included_com_example_test_MainActivity

#ifdef __cplusplus

extern "C" {

#endif

JNIEXPORT jint JNICALL Java_com_example_test1_NativeMethods_DrawFlag

    (JNIEnv *, jobjectjobject);

JNIEXPORT jint JNICALL Java_com_example_test1_NativeMethods_DrawJpg

    (JNIEnv *, jobjectjobject);

#ifdef __cplusplus

}

#endif

#endif

 

//Test1.cpp

//JNI端的实现

#include <stdio.h>

#include <stdlib.h>

#include "com_Test1.h"

#include <jni.h>

#include <SkBitmap.h>

#include <SkDevice.h>

#include <SkPaint.h>

#include <SkRect.h>

#include <SkImageEncoder.h>

#include <SkTypeface.h>

#include <SkCanvas.h>

#include <SkDevice.h>

#include <GraphicsJNI.h>

#include <SkStream.h>

#include <cutils/properties.h>

#include <cutils/log.h>

jint Java_com_example_test1_NativeMethods_DrawJpg(JNIEnv * env, jobject  obj, jobject canvas)

{

 SkCanvas* canv = GraphicsJNI::getNativeCanvas(env, canvas);//获得画布

 if (!canv)

 {

  return 0;

 }

 SkBitmap bp;

 SkPaint paint;

 SkImageDecoder::Format fmt;

    bool result = SkImageDecoder::DecodeFile("/sdcard/1.jpg",&bp,SkBitmap::kARGB_8888_Config,SkImageDecoder::kDecodePixels_Mode,&fmt);//解析图片

    if(!result)

    {

      LOGI("decoder file fail!");

      return -1;

    }

    else

    {

   if(fmt!= SkImageDecoder::kJPEG_Format)//判断图片的格式

   {

    LOGI("not the JPEG type!");

    return -2;

   }

   else

   {

   canv->drawBitmap(bp,0,0,&paint);//画图片

   }

    }

return 1;

}

jint Java_com_example_test1_NativeMethods_DrawFlag(JNIEnv * env, jobject  obj, jobject canvas)

{

     SkCanvas* canv = GraphicsJNI::getNativeCanvas(env, canvas);

     if (!canv)

       {

            return 0;

       }

     SkPaint paint;

  paint.setFlags(paint.kAntiAlias_Flag);

  SkRect rect;

     rect.set(100, 100, 300, 200);

     paint.setColor(SK_ColorRED);

  canv->drawRect(rect, paint);//画矩形

  paint.setColor(SK_ColorGRAY);

     paint.setStrokeWidth(10);

  canv->drawLine(95, 100, 95, 400, paint);//画旗杆

  paint.setTextSize(30);

  paint.setColor(SK_ColorBLUE);

  paint.setTextAlign(paint.kCenter_Align);

  canv->drawText("Hello",5*sizeof(char), 200, 160, paint);    //画字

 return 1;

}

//Android.mk

MY_LOCAL_PATH :=$(call my-dir)

LOCAL_PATH :=$(MY_LOCAL_PATH)

MY_LOCAL_ANDSRC :=E:/AndrSrc

include $(CLEAR_VARS)

LOCAL_C_INCLUDES :=$(MY_LOCAL_ANDSRC)/frameworks/base/core/jni/android/graphics \

$(MY_LOCAL_ANDSRC)/external/skia/include/core \

$(MY_LOCAL_ANDSRC)/external/skia/include/config \

$(MY_LOCAL_ANDSRC)/external/skia/include/images \

$(MY_LOCAL_ANDSRC)/external/skia/include/effects \

$(MY_LOCAL_ANDSRC)/external/skia/include \

$(MY_LOCAL_ANDSRC)/frameworks/base/include \

$(MY_LOCAL_ANDSRC)/system/core/include

LOCAL_MODULE    := Test

LOCAL_SRC_FILES := Test1.cpp

LOCAL_LDLIBS :=-llog -lcutils -lskia -ljnigraphics -landroid_runtime

include $(BUILD_SHARED_LIBRARY)

 

// MainActivity.java

//Java调用端

package com.example.test1;

import android.os.Bundle;

import android.app.Activity;

import android.content.Context;

import android.graphics.Canvas;

import android.util.Log;

import android.view.View;

public class MainActivity extends Activity {

 static

 {

  System.loadLibrary("Test");

 }

 @Override

 protected void onCreate(Bundle savedInstanceState) {

  super.onCreate(savedInstanceState);

      MyView view;  

   view=new MyView(this);  

   setContentView(view);

 }

}

class MyView extends View  

{  

    public MyView(Context context) {  

    super(context);  

}  

protected void onDraw(Canvas canvas) {  

    super.onDraw(canvas);  

    NativeMethods method=new NativeMethods();  

  // method.DrawFlag(canvas);

    method.DrawJpg(canvas);

    }  

      

}  

class NativeMethods  

{  

public native int DrawFlag(Canvas bmp);

public native int DrawJpg(Canvas bmp);

}