注意:这是一个有点旧的代码.对于最新的,请查看github上的项目页面.

JNI / Android.mk

LOCAL_PATH := $(call my-dir)

#bitmap operations module

include $(CLEAR_VARS)

LOCAL_MODULE := JniBitmapOperations

LOCAL_SRC_FILES := JniBitmapOperations.cpp

LOCAL_LDLIBS := -llog

LOCAL_LDFLAGS += -ljnigraphics

include $(BUILD_SHARED_LIBRARY)

APP_OPTIM := debug

LOCAL_CFLAGS := -g

#if you need to add more module, do the same as the one we started with (the one with the CLEAR_VARS)

JNI / JniBitmapOperations.cpp

#include

#include

#include

#include

#include

#include

#include

#define LOG_TAG "DEBUG"

#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,LOG_TAG,__VA_ARGS__)

#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__)

extern "C"

{

JNIEXPORT jobject JNICALL Java_com_jni_bitmap_1operations_JniBitmapHolder_jniStoreBitmapData(JNIEnv * env, jobject obj, jobject bitmap);

JNIEXPORT jobject JNICALL Java_com_jni_bitmap_1operations_JniBitmapHolder_jniGetBitmapFromStoredBitmapData(JNIEnv * env, jobject obj, jobject handle);

JNIEXPORT void JNICALL Java_com_jni_bitmap_1operations_JniBitmapHolder_jniFreeBitmapData(JNIEnv * env, jobject obj, jobject handle);

JNIEXPORT void JNICALL Java_com_jni_bitmap_1operations_JniBitmapHolder_jniRotateBitmapCcw90(JNIEnv * env, jobject obj, jobject handle);

JNIEXPORT void JNICALL Java_com_jni_bitmap_1operations_JniBitmapHolder_jniCropBitmap(JNIEnv * env, jobject obj, jobject handle, uint32_t left, uint32_t top, uint32_t right, uint32_t bottom);

}

class JniBitmap

{

public:

uint32_t* _storedBitmapPixels;

AndroidBitmapInfo _bitmapInfo;

JniBitmap()

{

_storedBitmapPixels = NULL;

}

};

/**crops the bitmap within to be smaller. note that no validations are done*/ //

JNIEXPORT void JNICALL Java_com_jni_bitmap_1operations_JniBitmapHolder_jniCropBitmap(JNIEnv * env, jobject obj, jobject handle, uint32_t left, uint32_t top, uint32_t right, uint32_t bottom)

{

JniBitmap* jniBitmap = (JniBitmap*) env->GetDirectBufferAddress(handle);

if (jniBitmap->_storedBitmapPixels == NULL)

return;

uint32_t* previousData = jniBitmap->_storedBitmapPixels;

uint32_t oldWidth = jniBitmap->_bitmapInfo.width;

uint32_t newWidth = right - left, newHeight = bottom - top;

uint32_t* newBitmapPixels = new uint32_t[newWidth * newHeight];

uint32_t* whereToGet = previousData + left + top * oldWidth;

uint32_t* whereToPut = newBitmapPixels;

for (int y = top; y < bottom; ++y)

{

memcpy(whereToPut, whereToGet, sizeof(uint32_t) * newWidth);

whereToGet += oldWidth;

whereToPut += newWidth;

}

//done copying , so replace old data with new one

delete[] previousData;

jniBitmap->_storedBitmapPixels = newBitmapPixels;

jniBitmap->_bitmapInfo.width = newWidth;

jniBitmap->_bitmapInfo.height = newHeight;

}

/**rotates the inner bitmap data by 90 degress counter clock wise*/ //

JNIEXPORT void JNICALL Java_com_jni_bitmap_1operations_JniBitmapHolder_jniRotateBitmapCcw90(JNIEnv * env, jobject obj, jobject handle)

{

JniBitmap* jniBitmap = (JniBitmap*) env->GetDirectBufferAddress(handle);

if (jniBitmap->_storedBitmapPixels == NULL)

return;

uint32_t* previousData = jniBitmap->_storedBitmapPixels;

AndroidBitmapInfo bitmapInfo = jniBitmap->_bitmapInfo;

uint32_t* newBitmapPixels = new uint32_t[bitmapInfo.height * bitmapInfo.width];

int whereToPut = 0;

// A.D D.C

// ...>...

// B.C A.B

for (int x = bitmapInfo.width - 1; x >= 0; --x)

for (int y = 0; y < bitmapInfo.height; ++y)

{

uint32_t pixel = previousData[bitmapInfo.width * y + x];

newBitmapPixels[whereToPut++] = pixel;

}

delete[] previousData;

jniBitmap->_storedBitmapPixels = newBitmapPixels;

uint32_t temp = bitmapInfo.width;

bitmapInfo.width = bitmapInfo.height;

bitmapInfo.height = temp;

}

/**free bitmap*/ //

JNIEXPORT void JNICALL Java_com_jni_bitmap_1operations_JniBitmapHolder_jniFreeBitmapData(JNIEnv * env, jobject obj, jobject handle)

{

JniBitmap* jniBitmap = (JniBitmap*) env->GetDirectBufferAddress(handle);

if (jniBitmap->_storedBitmapPixels == NULL)

return;

delete[] jniBitmap->_storedBitmapPixels;

jniBitmap->_storedBitmapPixels = NULL;

delete jniBitmap;

}

/**restore java bitmap (from JNI data)*/ //

JNIEXPORT jobject JNICALL Java_com_jni_bitmap_1operations_JniBitmapHolder_jniGetBitmapFromStoredBitmapData(JNIEnv * env, jobject obj, jobject handle)

{

JniBitmap* jniBitmap = (JniBitmap*) env->GetDirectBufferAddress(handle);

if (jniBitmap->_storedBitmapPixels == NULL)

{

LOGD("no bitmap data was stored. returning null...");

return NULL;

}

//

//creating a new bitmap to put the pixels into it - using Bitmap Bitmap.createBitmap (int width, int height, Bitmap.Config config) :

//

//LOGD("creating new bitmap...");

jclass bitmapCls = env->FindClass("android/graphics/Bitmap");

jmethodID createBitmapFunction = env->GetStaticMethodID(bitmapCls, "createBitmap", "(IILandroid/graphics/Bitmap$Config;)Landroid/graphics/Bitmap;");

jstring configName = env->NewStringUTF("ARGB_8888");

jclass bitmapConfigClass = env->FindClass("android/graphics/Bitmap$Config");

jmethodID valueOfBitmapConfigFunction = env->GetStaticMethodID(bitmapConfigClass, "valueOf", "(Ljava/lang/String;)Landroid/graphics/Bitmap$Config;");

jobject bitmapConfig = env->CallStaticObjectMethod(bitmapConfigClass, valueOfBitmapConfigFunction, configName);

jobject newBitmap = env->CallStaticObjectMethod(bitmapCls, createBitmapFunction, jniBitmap->_bitmapInfo.width, jniBitmap->_bitmapInfo.height, bitmapConfig);

//

// putting the pixels into the new bitmap:

//

int ret;

void* bitmapPixels;

if ((ret = AndroidBitmap_lockPixels(env, newBitmap, &bitmapPixels)) < 0)

{

LOGE("AndroidBitmap_lockPixels() failed ! error=%d", ret);

return NULL;

}

uint32_t* newBitmapPixels = (uint32_t*) bitmapPixels;

int pixelsCount = jniBitmap->_bitmapInfo.height * jniBitmap->_bitmapInfo.width;

memcpy(newBitmapPixels, jniBitmap->_storedBitmapPixels, sizeof(uint32_t) * pixelsCount);

AndroidBitmap_unlockPixels(env, newBitmap);

//LOGD("returning the new bitmap");

return newBitmap;

}

/**store java bitmap as JNI data*/ //

JNIEXPORT jobject JNICALL Java_com_jni_bitmap_1operations_JniBitmapHolder_jniStoreBitmapData(JNIEnv * env, jobject obj, jobject bitmap)

{

AndroidBitmapInfo bitmapInfo;

uint32_t* storedBitmapPixels = NULL;

//LOGD("reading bitmap info...");

int ret;

if ((ret = AndroidBitmap_getInfo(env, bitmap, &bitmapInfo)) < 0)

{

LOGE("AndroidBitmap_getInfo() failed ! error=%d", ret);

return NULL;

}

LOGD("width:%d height:%d stride:%d", bitmapInfo.width, bitmapInfo.height, bitmapInfo.stride);

if (bitmapInfo.format != ANDROID_BITMAP_FORMAT_RGBA_8888)

{

LOGE("Bitmap format is not RGBA_8888!");

return NULL;

}

//

//read pixels of bitmap into native memory :

//

//LOGD("reading bitmap pixels...");

void* bitmapPixels;

if ((ret = AndroidBitmap_lockPixels(env, bitmap, &bitmapPixels)) < 0)

{

LOGE("AndroidBitmap_lockPixels() failed ! error=%d", ret);

return NULL;

}

uint32_t* src = (uint32_t*) bitmapPixels;

storedBitmapPixels = new uint32_t[bitmapInfo.height * bitmapInfo.width];

int pixelsCount = bitmapInfo.height * bitmapInfo.width;

memcpy(storedBitmapPixels, src, sizeof(uint32_t) * pixelsCount);

AndroidBitmap_unlockPixels(env, bitmap);

JniBitmap *jniBitmap = new JniBitmap();

jniBitmap->_bitmapInfo = bitmapInfo;

jniBitmap->_storedBitmapPixels = storedBitmapPixels;

return env->NewDirectByteBuffer(jniBitmap, 0);

}

SRC/C++OM / JNI / bitmap_operations / JniBitmapHolder.java

package com.jni.bitmap_operations;

import java.nio.ByteBuffer;

import android.graphics.Bitmap;

import android.util.Log;

public class JniBitmapHolder

{

ByteBuffer _handler =null;

static

{

System.loadLibrary("JniBitmapOperations");

}

private native ByteBuffer jniStoreBitmapData(Bitmap bitmap);

private native Bitmap jniGetBitmapFromStoredBitmapData(ByteBuffer handler);

private native void jniFreeBitmapData(ByteBuffer handler);

private native void jniRotateBitmapCcw90(ByteBuffer handler);

private native void jniCropBitmap(ByteBuffer handler,final int left,final int top,final int right,final int bottom);

public JniBitmapHolder()

{}

public JniBitmapHolder(final Bitmap bitmap)

{

storeBitmap(bitmap);

}

public void storeBitmap(final Bitmap bitmap)

{

if(_handler!=null)

freeBitmap();

_handler=jniStoreBitmapData(bitmap);

}

public void rotateBitmapCcw90()

{

if(_handler==null)

return;

jniRotateBitmapCcw90(_handler);

}

public void cropBitmap(final int left,final int top,final int right,final int bottom)

{

if(_handler==null)

return;

jniCropBitmap(_handler,left,top,right,bottom);

}

public Bitmap getBitmap()

{

if(_handler==null)

return null;

return jniGetBitmapFromStoredBitmapData(_handler);

}

public Bitmap getBitmapAndFree()

{

final Bitmap bitmap=getBitmap();

freeBitmap();

return bitmap;

}

public void freeBitmap()

{

if(_handler==null)

return;

jniFreeBitmapData(_handler);

_handler=null;

}

@Override

protected void finalize() throws Throwable

{

super.finalize();

if(_handler==null)

return;

Log.w("DEBUG","JNI bitmap wasn't freed nicely.please rememeber to free the bitmap as soon as you can");

freeBitmap();

}

}

android jni bitmap,android – 如何使用JNI位图操作来帮助避免...相关推荐

  1. android layerlist bitmap,android – 在LayerListDrawable中更改Bitmap Drawable

    这是我的LayerList的简化版本.它在项目中有一个位图以防止缩放.我想以编程方式更改此位图的drawable.有没有办法做到这一点? android:id="@+id/item" ...

  2. android layerlist bitmap,android shape类似的 另一个 高端用法:layer-list

    android shape类似的 另一个 高端用法:layer-list : 简介: 将多个图片或上面两种效果按照顺序层叠起来 " <?xml version="1.0&qu ...

  3. Android NDK开发——Android studio使用JNI调用OpenCV处理图像

    前言 这里要演示的是使用Android studio 做APP开发,使用JNI与C++交互的demo. 一.创建工程 1.创建一个Native C++工程. 2.命令工程和指定交互语言. 3.指定C+ ...

  4. [chatGPT] 如何通过JNI在Android上显示实时视频流

    目录 背景 正文 layout xml java C++ java 总结一: 追问: C++ C++ 总结二: 答疑解惑 C++ 画蛇添足 视频不显示黑屏 最后感叹科技的更新速度,真的程序员都可能会被 ...

  5. 【Android】Eclipse自动编译NDK/JNI的三种方法

    [Android]Eclipse自动编译NDK/JNI的三种方法 SkySeraph Sep. 18th  2014 Email:skyseraph00@163.com 更多精彩请直接访问SkySer ...

  6. Android studio 使用NDK工具实现JNI编程

    前言: Android开发中常常会使用到第三方的.so库.在使用.so库的时候就要用到JNI编程.JNI是Java Native Interface的缩写.它提供了若干的API实现了Java和其它语言 ...

  7. Android之SDK、NDK、JNI和so文件

    Android之SDK.NDK.JNI和so文件 1.     SDK Android SDK(AndroidSoftware Development Kit),即Android软件开发工具包,And ...

  8. jni 入门 android的C编程之旅 ---环境搭建helloworld

    需要进行jni的开发有一下几个条件: 1:能初步使用C/C++如果不会,请参读 谭浩强的  C编程语言 2:android应用开发已经基本入门,如果没有,请先行学习 这两个条件基本满足后,我们开始了: ...

  9. Android 4.4.2 动态添加JNI库方法记录 (二 app应用层)

    欢迎转载,务必注明出处:http://blog.csdn.net/wang_shuai_ww/article/details/44458553 源码下载地址:http://download.csdn. ...

最新文章

  1. 全国大学生智能汽车竞赛 --智慧物流创意组
  2. 3月28日云栖精选夜读:小程序,会是下一个创业风口吗?
  3. Java Nashorn--Part 3
  4. 4.1.6 OS之文件的基本操作原理(创建、删除、打开、关闭、读-写)
  5. 众唱点歌机会显示无法连接服务器,目前众多厂商唱多的服务器附加存储缺点分析...
  6. gromacs 安装_带你入门带你飞 gromacs材料计算模拟系列
  7. QuartZ.net 常用配置说明
  8. git 版本控制(一)
  9. 怎么用python爬豆瓣_python爬虫16 | 你,快去试试用多进程的方式重新去爬取豆瓣上的电影...
  10. 下载silverlight官网的全部视频教程
  11. 获取URL参数JS函数
  12. python3菜鸟教程
  13. 树莓派测试USB摄像头是否可用
  14. 【前端面试题】02—59道CSS面试题(附答案)
  15. 土地利用转移矩阵图怎么做_如何用Arcgis做土地利用转移矩阵?求教各位..._土地估价师_帮考网...
  16. oracle 数据库备份脚本
  17. 识人 用人 激人 留人 斩人
  18. 设计模式-6-建造者模式
  19. ln(1+x)和ln(1-x)的麦克劳林级数
  20. (CSA 共识评估调查问卷)CSA Consensus Assessments Initiative Questionnaire

热门文章

  1. LeetCode(922)——按奇偶排序数组 II(JavaScript)
  2. c# 两个list比较_C# for Grasshopper Day 22 学习笔记
  3. 苹果x用了2年了,当前4G信号时有时无,大家有遇到过么?
  4. 为什么我发现自己照镜子觉得很好看,但是拍照就像变了一个人?
  5. 2021年,彩票店还开的下去吗?
  6. web安全这个行业的前景怎么样?
  7. LaTex ——P4 字体字号设置
  8. 蓝桥杯---特别数的和(C语言)
  9. 听力技巧-4大难点讲析
  10. 最小路径问题_Floyd