Skip to content

Commit

Permalink
Merge pull request kikoso#6 from Dr-Emann/support-renderscript
Browse files Browse the repository at this point in the history
Support renderscript
  • Loading branch information
kikoso committed Jan 10, 2014
2 parents 1df170d + 468ed60 commit b447b87
Show file tree
Hide file tree
Showing 23 changed files with 508 additions and 303 deletions.
16 changes: 15 additions & 1 deletion StackBlur/build.gradle
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@ apply plugin: 'android-library'

dependencies {
compile fileTree(dir: 'libs', include: '*.jar')
compile fileTree(dir: "$buildDir/native-libs", include: 'native-libs.jar')
}

android {
compileSdkVersion 17
buildToolsVersion "18.0.1"
buildToolsVersion '18.1.1'

sourceSets {
main {
Expand All @@ -32,3 +33,16 @@ android {
release.setRoot('build-types/release')
}
}

task nativeLibsToJar(type: Zip, description: 'create a jar archive of the native libs') {
destinationDir file("$buildDir/native-libs")
baseName 'native-libs'
extension 'jar'
from fileTree(dir: 'libs', include: '**/*.so')
from fileTree(dir: 'renderscript', include: '**/*.so')
into 'lib/'
}

tasks.withType(JavaCompile) {
compileTask -> compileTask.dependsOn(nativeLibsToJar)
}
20 changes: 19 additions & 1 deletion StackBlur/jni/Android.mk
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,22 @@ LOCAL_SRC_FILES := blur.c

LOCAL_CFLAGS = -ffast-math -O3 -funroll-loops

include $(BUILD_SHARED_LIBRARY)
include $(BUILD_SHARED_LIBRARY)

# Renderscript support library is not available for ARM before v7a currently
ifneq ($(TARGET_ARCH_ABI),armeabi)
# Add prebuilts for Renderscript Support
include $(CLEAR_VARS)

LOCAL_MODULE := librsjni
LOCAL_SRC_FILES := $(TARGET_ARCH_ABI)/librsjni.so

include $(PREBUILT_SHARED_LIBRARY)

include $(CLEAR_VARS)

LOCAL_MODULE := libRSSupport
LOCAL_SRC_FILES := $(TARGET_ARCH_ABI)/libRSSupport.so
include $(PREBUILT_SHARED_LIBRARY)
endif

1 change: 1 addition & 0 deletions StackBlur/jni/Application.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
APP_ABI := all
Binary file added StackBlur/jni/armeabi-v7a/libRSSupport.so
Binary file not shown.
Binary file added StackBlur/jni/armeabi-v7a/librsjni.so
Binary file not shown.
2 changes: 1 addition & 1 deletion StackBlur/jni/blur.c
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ typedef struct {
uint8_t alpha;
} rgba;

JNIEXPORT void JNICALL Java_com_enrique_stackblur_StackBlurManager_functionToBlur(JNIEnv* env, jobject obj, jobject bitmapIn, jobject bitmapOut, jint radius) {
JNIEXPORT void JNICALL Java_com_enrique_stackblur_NativeBlurProcess_functionToBlur(JNIEnv* env, jobject obj, jobject bitmapIn, jobject bitmapOut, jint radius) {
LOGI("Blurring bitmap...");

// Properties
Expand Down
Binary file added StackBlur/jni/mips/libRSSupport.so
Binary file not shown.
Binary file added StackBlur/jni/mips/librsjni.so
Binary file not shown.
Binary file added StackBlur/jni/x86/libRSSupport.so
Binary file not shown.
Binary file added StackBlur/jni/x86/librsjni.so
Binary file not shown.
Binary file removed StackBlur/libs/android-support-v4.jar
Binary file not shown.
Binary file added StackBlur/libs/renderscript-v8.jar
Binary file not shown.
14 changes: 14 additions & 0 deletions StackBlur/src/com/enrique/stackblur/BlurProcess.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.enrique.stackblur;

import android.graphics.Bitmap;

interface BlurProcess {
/**
* Process the given image, blurring by the supplied radius.
* If radius is 0, this will return original
* @param original the bitmap to be blurred
* @param radius the radius in pixels to blur the image
* @return the blurred version of the image.
*/
public Bitmap blur(Bitmap original, float radius);
}
233 changes: 233 additions & 0 deletions StackBlur/src/com/enrique/stackblur/JavaBlurProcess.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,233 @@
package com.enrique.stackblur;

import android.graphics.Bitmap;
import android.graphics.Color;

/**
* Blur using Java code.
*
* This is a compromise between Gaussian Blur and Box blur
* It creates much better looking blurs than Box Blur, but is
* 7x faster than my Gaussian Blur implementation.
* I called it Stack Blur because this describes best how this
* filter works internally: it creates a kind of moving stack
* of colors whilst scanning through the image. Thereby it
* just has to add one new block of color to the right side
* of the stack and remove the leftmost color. The remaining
* colors on the topmost layer of the stack are either added on
* or reduced by one, depending on if they are on the right or
* on the left side of the stack.
*
* @author Enrique López Mañas <[email protected]>
* http://www.neo-tech.es
*
* Author of the original algorithm: Mario Klingemann <mario.quasimondo.com>
*
* @copyright: Enrique López Mañas
* @license: Apache License 2.0
*/
class JavaBlurProcess implements BlurProcess {
@Override
public Bitmap blur(Bitmap original, float rad) {
int radius = (int) rad;
if (radius < 1)
radius = 1;

long time = System.currentTimeMillis();
int _width = original.getWidth();
int _height = original.getHeight();
boolean alpha = false;

int[] currentPixels = new int[_width * _height];
original.getPixels(currentPixels, 0, _width, 0, 0, _width, _height);
int wm = _width - 1;
int hm = _height - 1;
int wh = _width * _height;
int div = radius + radius + 1;

int r[] = new int[wh];
int g[] = new int[wh];
int b[] = new int[wh];
int rsum, gsum, bsum, x, y, i, p, yp, yi, yw;
int vmin[] = new int[Math.max(_width, _height)];

int divsum = (div + 1) >> 1;
divsum *= divsum;
int dv[] = new int[256 * divsum];
for (i = 0; i < 256 * divsum; i++) {
dv[i] = (i / divsum);
}

yw = yi = 0;

int[][] stack = new int[div][3];
int stackpointer;
int stackstart;
int[] sir;
int rbs;
int r1 = radius + 1;
int routsum, goutsum, boutsum;
int rinsum, ginsum, binsum;

for (y = 0; y < _height; y++) {
rinsum = ginsum = binsum = routsum = goutsum = boutsum = rsum = gsum = bsum = 0;
for (i = -radius; i <= radius; i++) {
p = currentPixels[yi + Math.min(wm, Math.max(i, 0))];
sir = stack[i + radius];
sir[0] = (p & 0xff0000) >> 16;
sir[1] = (p & 0x00ff00) >> 8;
sir[2] = (p & 0x0000ff);
rbs = r1 - Math.abs(i);
rsum += sir[0] * rbs;
gsum += sir[1] * rbs;
bsum += sir[2] * rbs;
if (i > 0) {
rinsum += sir[0];
ginsum += sir[1];
binsum += sir[2];
} else {
routsum += sir[0];
goutsum += sir[1];
boutsum += sir[2];
}
}
stackpointer = radius;

for (x = 0; x < _width; x++) {
if (!alpha)
alpha = Color.alpha(original.getPixel(x, y)) != 255;

r[yi] = dv[rsum];
g[yi] = dv[gsum];
b[yi] = dv[bsum];

rsum -= routsum;
gsum -= goutsum;
bsum -= boutsum;

stackstart = stackpointer - radius + div;
sir = stack[stackstart % div];

routsum -= sir[0];
goutsum -= sir[1];
boutsum -= sir[2];

if (y == 0) {
vmin[x] = Math.min(x + radius + 1, wm);
}
p = currentPixels[yw + vmin[x]];

sir[0] = (p & 0xff0000) >> 16;
sir[1] = (p & 0x00ff00) >> 8;
sir[2] = (p & 0x0000ff);

rinsum += sir[0];
ginsum += sir[1];
binsum += sir[2];

rsum += rinsum;
gsum += ginsum;
bsum += binsum;

stackpointer = (stackpointer + 1) % div;
sir = stack[(stackpointer) % div];

routsum += sir[0];
goutsum += sir[1];
boutsum += sir[2];

rinsum -= sir[0];
ginsum -= sir[1];
binsum -= sir[2];

yi++;
}
yw += _width;
}
for (x = 0; x < _width; x++) {
rinsum = ginsum = binsum = routsum = goutsum = boutsum = rsum = gsum = bsum = 0;
yp = -radius * _width;
for (i = -radius; i <= radius; i++) {
yi = Math.max(0, yp) + x;

sir = stack[i + radius];

sir[0] = r[yi];
sir[1] = g[yi];
sir[2] = b[yi];

rbs = r1 - Math.abs(i);

rsum += r[yi] * rbs;
gsum += g[yi] * rbs;
bsum += b[yi] * rbs;

if (i > 0) {
rinsum += sir[0];
ginsum += sir[1];
binsum += sir[2];
} else {
routsum += sir[0];
goutsum += sir[1];
boutsum += sir[2];
}

if (i < hm) {
yp += _width;
}
}
yi = x;
stackpointer = radius;
for (y = 0; y < _height; y++) {
// Preserve alpha channel: ( 0xff000000 & pix[yi] )
if (alpha)
currentPixels[yi] = (0xff000000 & currentPixels[yi]) | (dv[rsum] << 16) | (dv[gsum] << 8) | dv[bsum];
else
currentPixels[yi] = 0xff000000 | (dv[rsum] << 16) | (dv[gsum] << 8) | dv[bsum];

rsum -= routsum;
gsum -= goutsum;
bsum -= boutsum;

stackstart = stackpointer - radius + div;
sir = stack[stackstart % div];

routsum -= sir[0];
goutsum -= sir[1];
boutsum -= sir[2];

if (x == 0) {
vmin[y] = Math.min(y + r1, hm) * _width;
}
p = x + vmin[y];

sir[0] = r[p];
sir[1] = g[p];
sir[2] = b[p];

rinsum += sir[0];
ginsum += sir[1];
binsum += sir[2];

rsum += rinsum;
gsum += ginsum;
bsum += binsum;

stackpointer = (stackpointer + 1) % div;
sir = stack[stackpointer];

routsum += sir[0];
goutsum += sir[1];
boutsum += sir[2];

rinsum -= sir[0];
ginsum -= sir[1];
binsum -= sir[2];

yi += _width;
}
}
return Bitmap.createBitmap(currentPixels, _width, _height, original.getConfig());
}
}
25 changes: 25 additions & 0 deletions StackBlur/src/com/enrique/stackblur/NativeBlurProcess.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package com.enrique.stackblur;

import android.graphics.Bitmap;

/**
* @see JavaBlurProcess
* Blur using the NDK and native code.
*/
class NativeBlurProcess implements BlurProcess {
private native void functionToBlur(Bitmap bitmapIn, Bitmap bitmapOut, int radius) ;

static {
System.loadLibrary("blur");
}

@Override
public Bitmap blur(Bitmap original, float radius) {
Bitmap bitmapIn = original.copy(Bitmap.Config.ARGB_8888, true);
//Create a copy
Bitmap bitmapOut = original.copy(Bitmap.Config.ARGB_8888, true);
//BlurProcess the copy
functionToBlur(bitmapIn, bitmapOut, (int)radius);
return bitmapOut;
}
}
Loading

0 comments on commit b447b87

Please sign in to comment.