JNIEXPORT void JNICALL Java_net_qiujuer_genius_app_BlurNative_fastBlurBitmap (JNIEnv *env, jclass obj, jobject bitmapIn, jint r) { AndroidBitmapInfo infoIn; void* pixelsIn; int ret; // Get image info if ((ret = AndroidBitmap_getInfo(env, bitmapIn, &infoIn)) < 0) return; // Check image if (infoIn.format != ANDROID_BITMAP_FORMAT_RGBA_8888) return; // Lock all images if ((ret = AndroidBitmap_lockPixels(env, bitmapIn, &pixelsIn)) < 0) { //AndroidBitmap_lockPixels failed! } // height width int h = infoIn.height; int w = infoIn.width; // Start pixelsIn = stackBlur((int*)pixelsIn, w, h, r); // End // Unlocks everything AndroidBitmap_unlockPixels(env, bitmapIn); }
JNIEXPORT void JNICALL Java_net_qiujuer_genius_app_BlurNative_fastBlurArray (JNIEnv *env, jclass obj, jintArray arrIn, jint w, jint h, jint r) { jint *pix; // cpp: // pix = (env)->GetIntArrayElements(arrIn, 0); pix = (*env)->GetIntArrayElements(env, arrIn, 0); if (pix == NULL) return; // Start pix = stackBlur(pix, w, h, r); // End // if return: // int size = w * h; // jintArray result = env->NewIntArray(size); // env->SetIntArrayRegion(result, 0, size, pix); // cpp: // (env)->ReleaseIntArrayElements(arrIn, pix, 0); (*env)->ReleaseIntArrayElements(env, arrIn, pix, 0); // return result; }
//TODO memory usage may be reduced by using component based blur int applyHDR(Bitmap* bitmap) { //Cache to local variables unsigned char* red = (*bitmap).red; unsigned char* green = (*bitmap).green; unsigned char* blue = (*bitmap).blue; unsigned char* blurRed; unsigned char* blurGreen; unsigned char* blurBlue; int length = (*bitmap).width * (*bitmap).height; int resultCode = newUnsignedCharArray(length, &blurRed); if (resultCode != MEMORY_OK) { return resultCode; } resultCode = newUnsignedCharArray(length, &blurGreen); if (resultCode != MEMORY_OK) { freeUnsignedCharArray(&blurRed); return resultCode; } resultCode = newUnsignedCharArray(length, &blurBlue); if (resultCode != MEMORY_OK) { freeUnsignedCharArray(&blurRed); freeUnsignedCharArray(&blurGreen); return resultCode; } float blurRadius = 9.0f; resultCode = stackBlur(&blurRadius, red, green, blue, &((*bitmap).width), &((*bitmap).height), blurRed, blurGreen, blurBlue); if (resultCode != MEMORY_OK) { freeUnsignedCharArray(&blurRed); freeUnsignedCharArray(&blurGreen); freeUnsignedCharArray(&blurBlue); return resultCode; } unsigned int i, j; unsigned char r1, g1, b1, r2, g2, b2; float matrix[4][4]; identMatrix(matrix); float saturation = 1.3f; saturateMatrix(matrix, &saturation); for (i = length; i--;) { // invert the blurred pixel r1 = 255 - blurRed[i]; g1 = 255 - blurGreen[i]; b1 = 255 - blurBlue[i]; // Grain merge the inverted blurred pixel with the original r1 = grainMergePixelsComponent(r1, red[i]); g1 = grainMergePixelsComponent(g1, green[i]); b1 = grainMergePixelsComponent(b1, blue[i]); // boost the saturation of the original pixel //HSBColour hsb; //rgbToHsb(red[i], green[i], blue[i], &hsb); //hsb.s = min(1.0f, hsb.s * 1.3f); r2 = red[i]; g2 = green[i]; b2 = blue[i]; applyMatrixToPixel(&r2, &g2, &b2, matrix); //hsbToRgb(&hsb, &r2, &g2, &b2); // grain merge the saturated pixel with the inverted grain merged pixel red[i] = grainMergePixelsComponent(r2, r1); green[i] = grainMergePixelsComponent(g2, g1); blue[i] = grainMergePixelsComponent(b2, g1); } applyMatrix(bitmap, matrix); freeUnsignedCharArray(&blurRed); freeUnsignedCharArray(&blurGreen); freeUnsignedCharArray(&blurBlue); return MEMORY_OK; }
int applySahara(Bitmap* bitmap) { int length = (*bitmap).width * (*bitmap).height; int i; unsigned char r, g, b; //HSBColour hsb; unsigned char* red = (*bitmap).red; unsigned char* green = (*bitmap).green; unsigned char* blue = (*bitmap).blue; unsigned char brightnessLut[256]; unsigned char contrastLut[256]; for (i = 0; i < 256; i++) { float pixelf = i/255.0f; //brightnessLut[i] = 255*applyBrightnessToPixelComponent(pixelf, 0.35433f); //contrastLut[i] = 255*applyContrastToPixelComponent(pixelf, 0.1496f); brightnessLut[i] = 255*applyBrightnessToPixelComponent(pixelf, 0.45f); contrastLut[i] = 255*applyContrastToPixelComponent(pixelf, 0.1f); } for (i = length; i--; ) { r = brightnessLut[red[i]]; g = brightnessLut[green[i]]; b = brightnessLut[blue[i]]; r = contrastLut[r]; green[i] = contrastLut[g]; b = contrastLut[b]; red[i] = (r*0.8431f/*215*/)+40; //compress the red channel between 18 - 237 blue[i] = (b*0.8823f/*225*/)+30; //compress the blue channel between 50 - 205 //rgbToHsb(red[i], green[i], blue[i], &hsb); //hsb.s = hsb.s * 0.55f; //hsbToRgb(&hsb, &red[i], &green[i], &blue[i]); } float matrix[4][4]; identMatrix(matrix); float saturation = 0.65f; saturateMatrix(matrix, &saturation); applyMatrix(bitmap, matrix); unsigned char* blurRed; unsigned char* blurGreen; unsigned char* blurBlue; int resultCode = newUnsignedCharArray(length, &blurRed); if (resultCode != MEMORY_OK) { return resultCode; } resultCode = newUnsignedCharArray(length, &blurGreen); if (resultCode != MEMORY_OK) { freeUnsignedCharArray(&blurRed); return resultCode; } resultCode = newUnsignedCharArray(length, &blurBlue); if (resultCode != MEMORY_OK) { freeUnsignedCharArray(&blurRed); freeUnsignedCharArray(&blurGreen); return resultCode; } float blurRadius = 1.0f; resultCode = stackBlur(&blurRadius, (*bitmap).red, (*bitmap).green, (*bitmap).blue, &((*bitmap).width), &((*bitmap).height), blurRed, blurGreen, blurBlue); if (resultCode != MEMORY_OK) { freeUnsignedCharArray(&blurRed); freeUnsignedCharArray(&blurGreen); freeUnsignedCharArray(&blurBlue); return resultCode; } short int overlayLut[256][256]; unsigned char multiplyLut255[256]; unsigned char multiplyLut227[256]; unsigned char multiplyLut187[256]; unsigned int j; for (i = 0; i < 256; i++) { for (j = 0; j < 256; j++) { overlayLut[i][j] = -1;//overlayPixelComponents(i, j, 1.0f); } multiplyLut255[i] = multiplyPixelComponents(255, i); multiplyLut227[i] = multiplyPixelComponents(227, i); multiplyLut187[i] = multiplyPixelComponents(187, i); } for (i = length; i--; ) { if (overlayLut[blurRed[i]][red[i]] == -1) { overlayLut[blurRed[i]][red[i]] = overlayPixelComponents(blurRed[i], red[i], 1.0f); } red[i] = overlayLut[blurRed[i]][red[i]];//overlayPixelComponents(blurRed[i], red[i], 1.0f); if (overlayLut[blurGreen[i]][green[i]] == -1) { overlayLut[blurGreen[i]][green[i]] = overlayPixelComponents(blurGreen[i], green[i], 1.0f); } green[i] = overlayLut[blurGreen[i]][green[i]];//overlayPixelComponents(blurGreen[i], green[i], 1.0f); if (overlayLut[blurBlue[i]][blue[i]] == -1) { overlayLut[blurBlue[i]][blue[i]] = overlayPixelComponents(blurBlue[i], blue[i], 1.0f); } blue[i] = overlayLut[blurBlue[i]][blue[i]];//overlayPixelComponents(blurBlue[i], blue[i], 1.0f); // Multiply by a wheat colour rgb(255, 227, 187) red[i] = multiplyLut255[red[i]];//multiplyPixelComponents(255, red[i]); green[i] = multiplyLut227[green[i]];//multiplyPixelComponents(227, green[i]); blue[i] = multiplyLut187[blue[i]];//multiplyPixelComponents(187, blue[i]); } freeUnsignedCharArray(&blurRed); freeUnsignedCharArray(&blurGreen); freeUnsignedCharArray(&blurBlue); return MEMORY_OK; }
// amount is 0.0 to 1.0 // threshold is 0 to 255 int unsharpMask(Bitmap* bitmap, int radius, float amount, int threshold) { unsigned char* red = (*bitmap).red; unsigned char* green = (*bitmap).green; unsigned char* blue = (*bitmap).blue; unsigned int length = (*bitmap).width * (*bitmap).height; // Create blur unsigned char* blurRed; unsigned char* blurGreen; unsigned char* blurBlue; int resultCode = newUnsignedCharArray(length, &blurRed); if (resultCode != MEMORY_OK) { return resultCode; } resultCode = newUnsignedCharArray(length, &blurGreen); if (resultCode != MEMORY_OK) { freeUnsignedCharArray(&blurRed); return resultCode; } resultCode = newUnsignedCharArray(length, &blurBlue); if (resultCode != MEMORY_OK) { freeUnsignedCharArray(&blurRed); freeUnsignedCharArray(&blurGreen); return resultCode; } float blurRadius = radius/3.0f; resultCode = stackBlur(&blurRadius, (*bitmap).red, (*bitmap).green, (*bitmap).blue, &((*bitmap).width), &((*bitmap).height), blurRed, blurGreen, blurBlue); if (resultCode != MEMORY_OK) { freeUnsignedCharArray(&blurRed); freeUnsignedCharArray(&blurGreen); freeUnsignedCharArray(&blurBlue); return resultCode; } int i, j; short int lut[256][256]; float a = (4 * amount) + 1; for (i = 0; i < 256; i++) { for (j = 0; j < 256; j++) { lut[i][j] = -1;//clampComponent((int) (a * (i - j) + j)); } } for (i = length; i--;) { int r1 = red[i]; int g1 = green[i]; int b1 = blue[i]; int r2 = blurRed[i]; int g2 = blurGreen[i]; int b2 = blurBlue[i]; if (fabs(r1 - r2) >= threshold) { if (lut[r1][r2] == -1) { lut[r1][r2] = clampComponent((int) ((a + 1) * (r1 - r2) + r2)); } r1 = lut[r1][r2]; //clampComponent((int) ((a + 1) * (r1 - r2) + r2)); } if (fabs(g1 - g2) >= threshold) { if (lut[g1][g2] == -1) { lut[g1][g2] = clampComponent((int) ((a + 1) * (g1 - g2) + g2)); } g1 = lut[g1][g2]; //clampComponent((int) ((a + 1) * (g1 - g2) + g2)); } if (fabs(b1 - b2) >= threshold) { if (lut[b1][b2] == -1) { lut[b1][b2] = clampComponent((int) ((a + 1) * (b1 - b2) + b2)); } b1 = lut[b1][b2]; //clampComponent((int) ((a + 1) * (b1 - b2) + b2)); } red[i] = r1; green[i] = g1; blue[i] = b1; } freeUnsignedCharArray(&blurRed); freeUnsignedCharArray(&blurGreen); freeUnsignedCharArray(&blurBlue); }
JNIEXPORT jintArray JNICALL Java_com_yjn_text_JniClient_getFasetBlurPix (JNIEnv *env, jclass ara, jintArray pixs, jint w, jint h, jint radius){ return stackBlur(pixs , w , h , radius); }