经过查阅资料以及自己尝试,终于实现了在Android NDK 画图和打开并显示图片。现将自己的测试代码以及使用过程中的心得写下,希望与大家交流一下。
首先,测试程序的运行结果如下图所示:
调用DrawJpg打开模拟器中的一张Jpg格式的图片并显示
调用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 *, jobject, jobject);
JNIEXPORT jint JNICALL Java_com_example_test1_NativeMethods_DrawJpg
(JNIEnv *, jobject, jobject);
#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);
}