diff --git a/.gitignore b/.gitignore
index c3740ad..74e3654 100644
--- a/.gitignore
+++ b/.gitignore
@@ -9,6 +9,7 @@ gradle.properties
*.apk
*.ap_
*.jar
+.externalNativeBuild
# files for the dex VM
*.dex
diff --git a/JniBitmapOperationsLibrary/AndroidManifest.xml b/JniBitmapOperationsLibrary/AndroidManifest.xml
index 7536854..02e8b88 100644
--- a/JniBitmapOperationsLibrary/AndroidManifest.xml
+++ b/JniBitmapOperationsLibrary/AndroidManifest.xml
@@ -1,11 +1,4 @@
-
-
-
-
-
+ android:versionName="1.0" />
diff --git a/JniBitmapOperationsLibrary/build.gradle b/JniBitmapOperationsLibrary/build.gradle
index f22ed27..f3c931a 100644
--- a/JniBitmapOperationsLibrary/build.gradle
+++ b/JniBitmapOperationsLibrary/build.gradle
@@ -14,7 +14,7 @@ android {
resources.srcDirs = ['src']
aidl.srcDirs = ['src']
renderscript.srcDirs = ['src']
- jni.srcDirs = []
+ jni.srcDirs = ['jni']
}
}
@@ -22,9 +22,20 @@ android {
ndk {
moduleName "JniBitmapOperationsLibrary"
ldLibs "log", "jnigraphics"
+ cFlags "-DANDROID_NDK_HOME"
+ stl "stlport_shared"
}
+ minSdkVersion 8
+ targetSdkVersion 23
}
+ externalNativeBuild {
+ ndkBuild {
+ path 'jni/Android.mk'
+ }
+ }
+
+/*
task buildNative(type: Exec, description: 'Compile JNI source via NDK') {
def ndkDir = android.plugin.ndkFolder
commandLine "$ndkDir/ndk-build",
@@ -46,4 +57,5 @@ android {
tasks.withType(JavaCompile) {
compileTask -> compileTask.dependsOn buildNative
}
+ */
}
diff --git a/JniBitmapOperationsLibrary/jni/JniBitmapOperationsLibrary.cpp b/JniBitmapOperationsLibrary/jni/JniBitmapOperationsLibrary.cpp
index f6aef1e..723a375 100644
--- a/JniBitmapOperationsLibrary/jni/JniBitmapOperationsLibrary.cpp
+++ b/JniBitmapOperationsLibrary/jni/JniBitmapOperationsLibrary.cpp
@@ -87,7 +87,7 @@ JNIEXPORT void JNICALL Java_com_jni_bitmap_1operations_JniBitmapHolder_jniCropBi
uint32_t right, uint32_t bottom)
{
JniBitmap* jniBitmap = (JniBitmap*) env->GetDirectBufferAddress(handle);
- if (jniBitmap->_storedBitmapPixels == NULL)
+ if (jniBitmap == NULL || jniBitmap->_storedBitmapPixels == NULL)
return;
uint32_t* previousData = jniBitmap->_storedBitmapPixels;
uint32_t oldWidth = jniBitmap->_bitmapInfo.width;
@@ -113,7 +113,7 @@ JNIEXPORT void JNICALL Java_com_jni_bitmap_1operations_JniBitmapHolder_jniRotate
JNIEnv * env, jobject obj, jobject handle)
{
JniBitmap* jniBitmap = (JniBitmap*) env->GetDirectBufferAddress(handle);
- if (jniBitmap->_storedBitmapPixels == NULL)
+ if (jniBitmap == NULL || jniBitmap->_storedBitmapPixels == NULL)
return;
uint32_t* previousData = jniBitmap->_storedBitmapPixels;
uint32_t newWidth = jniBitmap->_bitmapInfo.height;
@@ -141,7 +141,7 @@ JNIEXPORT void JNICALL Java_com_jni_bitmap_1operations_JniBitmapHolder_jniRotate
JNIEnv * env, jobject obj, jobject handle)
{
JniBitmap* jniBitmap = (JniBitmap*) env->GetDirectBufferAddress(handle);
- if (jniBitmap->_storedBitmapPixels == NULL)
+ if (jniBitmap == NULL || jniBitmap->_storedBitmapPixels == NULL)
return;
uint32_t* previousData = jniBitmap->_storedBitmapPixels;
uint32_t newWidth = jniBitmap->_bitmapInfo.height;
@@ -169,7 +169,7 @@ JNIEXPORT void JNICALL Java_com_jni_bitmap_1operations_JniBitmapHolder_jniRotate
JNIEnv * env, jobject obj, jobject handle)
{
JniBitmap* jniBitmap = (JniBitmap*) env->GetDirectBufferAddress(handle);
- if (jniBitmap->_storedBitmapPixels == NULL)
+ if (jniBitmap == NULL || jniBitmap->_storedBitmapPixels == NULL)
return;
uint32_t* pixels = jniBitmap->_storedBitmapPixels;
uint32_t* pixels2 = jniBitmap->_storedBitmapPixels;
@@ -211,7 +211,7 @@ JNIEXPORT void JNICALL Java_com_jni_bitmap_1operations_JniBitmapHolder_jniFreeBi
JNIEnv * env, jobject obj, jobject handle)
{
JniBitmap* jniBitmap = (JniBitmap*) env->GetDirectBufferAddress(handle);
- if (jniBitmap->_storedBitmapPixels == NULL)
+ if (jniBitmap == NULL || jniBitmap->_storedBitmapPixels == NULL)
return;
delete[] jniBitmap->_storedBitmapPixels;
jniBitmap->_storedBitmapPixels = NULL;
@@ -223,7 +223,7 @@ JNIEXPORT jobject JNICALL Java_com_jni_bitmap_1operations_JniBitmapHolder_jniGet
JNIEnv * env, jobject obj, jobject handle)
{
JniBitmap* jniBitmap = (JniBitmap*) env->GetDirectBufferAddress(handle);
- if (jniBitmap->_storedBitmapPixels == NULL)
+ if (jniBitmap == NULL || jniBitmap->_storedBitmapPixels == NULL)
{
LOGD("no bitmap data was stored. returning null...");
return NULL;
@@ -311,7 +311,7 @@ JNIEXPORT void JNICALL Java_com_jni_bitmap_1operations_JniBitmapHolder_jniScaleN
uint32_t newHeight)
{
JniBitmap* jniBitmap = (JniBitmap*) env->GetDirectBufferAddress(handle);
- if (jniBitmap->_storedBitmapPixels == NULL)
+ if (jniBitmap == NULL || jniBitmap->_storedBitmapPixels == NULL)
return;
uint32_t oldWidth = jniBitmap->_bitmapInfo.width;
uint32_t oldHeight = jniBitmap->_bitmapInfo.height;
@@ -353,7 +353,7 @@ JNIEXPORT void JNICALL Java_com_jni_bitmap_1operations_JniBitmapHolder_jniScaleB
{
JniBitmap* jniBitmap = (JniBitmap*) env->GetDirectBufferAddress(handle);
- if (jniBitmap->_storedBitmapPixels == NULL)
+ if (jniBitmap == NULL || jniBitmap->_storedBitmapPixels == NULL)
return;
uint32_t oldWidth = jniBitmap->_bitmapInfo.width;
uint32_t oldHeight = jniBitmap->_bitmapInfo.height;
@@ -422,7 +422,7 @@ JNIEXPORT void JNICALL Java_com_jni_bitmap_1operations_JniBitmapHolder_jniScaleB
&rgbTopLeft);
//rgbTopRight=startingImageData[xTopLeft+1][yTopLeft];
convertIntToArgb(
- previousData[((yTopLeft + 1) * oldWidth) + xTopLeft],
+ previousData[(yTopLeft* oldWidth) + xTopLeft + 1],
&rgbTopRight);
rgbTopMiddle.alpha = rgbTopLeft.alpha * xcRatio2
+ rgbTopRight.alpha * xcratio1;
@@ -486,7 +486,7 @@ JNIEXPORT void JNICALL Java_com_jni_bitmap_1operations_JniBitmapHolder_jniFlipBi
JNIEnv * env, jobject obj, jobject handle)
{
JniBitmap* jniBitmap = (JniBitmap*) env->GetDirectBufferAddress(handle);
- if (jniBitmap->_storedBitmapPixels == NULL)
+ if (jniBitmap == NULL || jniBitmap->_storedBitmapPixels == NULL)
return;
uint32_t* previousData = jniBitmap->_storedBitmapPixels;
int width = jniBitmap->_bitmapInfo.width, middle = width / 2, height =
@@ -518,7 +518,7 @@ JNIEXPORT void JNICALL Java_com_jni_bitmap_1operations_JniBitmapHolder_jniFlipBi
JNIEnv * env, jobject obj, jobject handle)
{
JniBitmap* jniBitmap = (JniBitmap*) env->GetDirectBufferAddress(handle);
- if (jniBitmap->_storedBitmapPixels == NULL)
+ if (jniBitmap == NULL || jniBitmap->_storedBitmapPixels == NULL)
return;
uint32_t* previousData = jniBitmap->_storedBitmapPixels;
int width = jniBitmap->_bitmapInfo.width, height =
diff --git a/README.md b/README.md
index 0625987..242e270 100644
--- a/README.md
+++ b/README.md
@@ -20,13 +20,16 @@ This library was first introduced via StackOverflow, and many of the notes writt
Please read it here:
http://stackoverflow.com/questions/18250951/jni-bitmap-operations-for-helping-to-avoid-oom-when-using-large-images/18250952?noredirect=1
+Starting from Android 11 (R - API 30), it seems to be possible to also decode the bitmaps right in JNI, so this might be handy to perform operations on it right away (though not sure how to do it) :
+https://developer.android.com/ndk/guides/image-decoder
+
## Screenshot
Here's a sample of what can be done:

## Known issues
-It's very annoying to import the library. I personally haven't succeeded doing so on Android-Studio, but on Eclipse it has issues, and on some cases, when you open the C/C++ file, it shows errors (even if it succeeded building a moment before). If this happens, try to close and open the library project and don't open the C/C++ file unless you wish to edit it.
+Android-Studio still doesn't support C/C++ code well. It's easy to import the project and try it, but I think it's quite hard to do it for your own project.
## Missing features (TODO)
@@ -80,6 +83,29 @@ Just import the whole cloned project and run the sample.
#### Further configuring and using as the library
+#### Option 1
+ 1. Add this repository as a git submodule. For these instructions we added in a folder named `AndroidJniBitmapOperations`
+ 2. Add the following lines to your `settings.gradle` file
+
+ ```
+ include ':JniBitmapOperationsLibrary'
+ project(':JniBitmapOperationsLibrary').projectDir = new File(rootProject.getProjectDir(), 'AndroidJniBitmapOperations/JniBitmapOperationsLibrary')
+ ```
+ 3. Add the following lines to your top level `build.gradle` file inside the `buildscript` section. Replace the versions with whatever your project is using as needed.
+
+ ```
+ // Variables for JniBitmapOperationsLibrary
+ ext.propCompileSdkVersion = 23
+ ext.propBuildToolsVersion = "27.0.3"
+ ```
+ 4. Add the following lines to your app `build.gradle` file inside the `dependancies` section
+
+ ```
+ implementation project(':JniBitmapOperationsLibrary')
+ ```
+
+#### Option 2
+
1. Copy `JniBitmapOperationsLibrary.cpp` into `src/main/jni` directory:

@@ -104,7 +130,15 @@ Just import the whole cloned project and run the sample.
You now should be able to use `JniBitmapHolder` to process images on NDK side.
-
+## Similar libraries
+
+If you are interested in more features, and don't want to modify the code of this library, you could try out those similar libraries:
+
+ - https://github.com/suckgamony/RapidDecoder
+ - https://github.com/facebook/fresco
+ - https://android-arsenal.com/tag/63
+
+
[1]: http://stackoverflow.com/questions/22263253/how-to-correctly-import-an-android-library-with-jni-code/22956790?noredirect=1#comment35057887_22956790
[2]: https://developer.android.com/tools/sdk/ndk/index.html
diff --git a/build.gradle b/build.gradle
index fe77dfc..9c44237 100644
--- a/build.gradle
+++ b/build.gradle
@@ -1,15 +1,16 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
-task wrapper(type: Wrapper) {
- gradleVersion = '2.2'
-}
+//task wrapper(type: Wrapper) {
+// gradleVersion = '2.2'
+//}
buildscript {
repositories {
mavenCentral()
+ google()
}
dependencies {
- classpath 'com.android.tools.build:gradle:1.0.0'
+ classpath 'com.android.tools.build:gradle:3.2.0'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
@@ -23,6 +24,6 @@ allprojects {
}
ext {
- propBuildToolsVersion = '21.1.2'
- propCompileSdkVersion = 21
+ propBuildToolsVersion = '23.0.2'
+ propCompileSdkVersion = 23
}
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index a966c02..b85ddd2 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,6 @@
-#Fri Jan 16 11:30:20 CET 2015
+#Wed May 13 00:33:24 EEST 2015
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-2.2-bin.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-2.4-all.zip
diff --git a/sample/AndroidManifest.xml b/sample/AndroidManifest.xml
index 6aa3af8..c839a6d 100644
--- a/sample/AndroidManifest.xml
+++ b/sample/AndroidManifest.xml
@@ -6,7 +6,7 @@
+ android:targetSdkVersion="23" />