android jni bitmap,android – 如何使用JNI位图操作来帮助避免...
注意:这是一个有点旧的代码.对于最新的,请查看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位图操作来帮助避免...相关推荐
- android layerlist bitmap,android – 在LayerListDrawable中更改Bitmap Drawable
这是我的LayerList的简化版本.它在项目中有一个位图以防止缩放.我想以编程方式更改此位图的drawable.有没有办法做到这一点? android:id="@+id/item" ...
- android layerlist bitmap,android shape类似的 另一个 高端用法:layer-list
android shape类似的 另一个 高端用法:layer-list : 简介: 将多个图片或上面两种效果按照顺序层叠起来 " <?xml version="1.0&qu ...
- Android NDK开发——Android studio使用JNI调用OpenCV处理图像
前言 这里要演示的是使用Android studio 做APP开发,使用JNI与C++交互的demo. 一.创建工程 1.创建一个Native C++工程. 2.命令工程和指定交互语言. 3.指定C+ ...
- [chatGPT] 如何通过JNI在Android上显示实时视频流
目录 背景 正文 layout xml java C++ java 总结一: 追问: C++ C++ 总结二: 答疑解惑 C++ 画蛇添足 视频不显示黑屏 最后感叹科技的更新速度,真的程序员都可能会被 ...
- 【Android】Eclipse自动编译NDK/JNI的三种方法
[Android]Eclipse自动编译NDK/JNI的三种方法 SkySeraph Sep. 18th 2014 Email:skyseraph00@163.com 更多精彩请直接访问SkySer ...
- Android studio 使用NDK工具实现JNI编程
前言: Android开发中常常会使用到第三方的.so库.在使用.so库的时候就要用到JNI编程.JNI是Java Native Interface的缩写.它提供了若干的API实现了Java和其它语言 ...
- Android之SDK、NDK、JNI和so文件
Android之SDK.NDK.JNI和so文件 1. SDK Android SDK(AndroidSoftware Development Kit),即Android软件开发工具包,And ...
- jni 入门 android的C编程之旅 ---环境搭建helloworld
需要进行jni的开发有一下几个条件: 1:能初步使用C/C++如果不会,请参读 谭浩强的 C编程语言 2:android应用开发已经基本入门,如果没有,请先行学习 这两个条件基本满足后,我们开始了: ...
- Android 4.4.2 动态添加JNI库方法记录 (二 app应用层)
欢迎转载,务必注明出处:http://blog.csdn.net/wang_shuai_ww/article/details/44458553 源码下载地址:http://download.csdn. ...
最新文章
- 全国大学生智能汽车竞赛 --智慧物流创意组
- 3月28日云栖精选夜读:小程序,会是下一个创业风口吗?
- Java Nashorn--Part 3
- 4.1.6 OS之文件的基本操作原理(创建、删除、打开、关闭、读-写)
- 众唱点歌机会显示无法连接服务器,目前众多厂商唱多的服务器附加存储缺点分析...
- gromacs 安装_带你入门带你飞 gromacs材料计算模拟系列
- QuartZ.net 常用配置说明
- git 版本控制(一)
- 怎么用python爬豆瓣_python爬虫16 | 你,快去试试用多进程的方式重新去爬取豆瓣上的电影...
- 下载silverlight官网的全部视频教程
- 获取URL参数JS函数
- python3菜鸟教程
- 树莓派测试USB摄像头是否可用
- 【前端面试题】02—59道CSS面试题(附答案)
- 土地利用转移矩阵图怎么做_如何用Arcgis做土地利用转移矩阵?求教各位..._土地估价师_帮考网...
- oracle 数据库备份脚本
- 识人 用人 激人 留人 斩人
- 设计模式-6-建造者模式
- ln(1+x)和ln(1-x)的麦克劳林级数
- (CSA 共识评估调查问卷)CSA Consensus Assessments Initiative Questionnaire