private void verifyResultsNativeAcospiFloatFloat( Allocation inV, Allocation out, boolean relaxed) { float[] arrayInV = new float[INPUTSIZE * 1]; Arrays.fill(arrayInV, (float) 42); inV.copyTo(arrayInV); float[] arrayOut = new float[INPUTSIZE * 1]; Arrays.fill(arrayOut, (float) 42); out.copyTo(arrayOut); StringBuilder message = new StringBuilder(); boolean errorFound = false; for (int i = 0; i < INPUTSIZE; i++) { for (int j = 0; j < 1; j++) { // Extract the inputs. ArgumentsFloatFloat args = new ArgumentsFloatFloat(); args.inV = arrayInV[i]; // Figure out what the outputs should have been. Target target = new Target(relaxed); CoreMathVerifier.computeNativeAcospi(args, target); // Validate the outputs. boolean valid = true; if (!args.out.couldBe(arrayOut[i * 1 + j], 0.0005)) { valid = false; } if (!valid) { if (!errorFound) { errorFound = true; message.append("Input inV: "); appendVariableToMessage(message, args.inV); message.append("\n"); message.append("Expected output out: "); appendVariableToMessage(message, args.out); message.append("\n"); message.append("Actual output out: "); appendVariableToMessage(message, arrayOut[i * 1 + j]); if (!args.out.couldBe(arrayOut[i * 1 + j], 0.0005)) { message.append(" FAIL"); } message.append("\n"); message.append("Errors at"); } message.append(" ["); message.append(Integer.toString(i)); message.append(", "); message.append(Integer.toString(j)); message.append("]"); } } } assertFalse( "Incorrect output for checkNativeAcospiFloatFloat" + (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound); }
private void verifyResultsExpm1FloatFloat(Allocation in, Allocation out, boolean relaxed) { float[] arrayIn = new float[INPUTSIZE * 1]; in.copyTo(arrayIn); float[] arrayOut = new float[INPUTSIZE * 1]; out.copyTo(arrayOut); for (int i = 0; i < INPUTSIZE; i++) { for (int j = 0; j < 1; j++) { // Extract the inputs. ArgumentsFloatFloat args = new ArgumentsFloatFloat(); args.in = arrayIn[i]; // Figure out what the outputs should have been. Target target = new Target(relaxed); CoreMathVerifier.computeExpm1(args, target); // Validate the outputs. boolean valid = true; if (!args.out.couldBe(arrayOut[i * 1 + j])) { valid = false; } if (!valid) { StringBuilder message = new StringBuilder(); message.append("Input in: "); message.append( String.format( "%14.8g {%8x} %15a", args.in, Float.floatToRawIntBits(args.in), args.in)); message.append("\n"); message.append("Expected output out: "); message.append(args.out.toString()); message.append("\n"); message.append("Actual output out: "); message.append( String.format( "%14.8g {%8x} %15a", arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j])); if (!args.out.couldBe(arrayOut[i * 1 + j])) { message.append(" FAIL"); } message.append("\n"); assertTrue( "Incorrect output for checkExpm1FloatFloat" + (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid); } } } }
public void test_AllocationPadded_Byte3_3D() { Random random = new Random(0x172d8ab9); int w = random.nextInt(32); int h = random.nextInt(32); int d = random.nextInt(32); int arr_len = w * d * h * 3; byte[] inArray = new byte[arr_len]; byte[] outArray = new byte[arr_len]; random.nextBytes(inArray); Type.Builder typeBuilder = new Type.Builder(mRS, Element.I8_3(mRS)); typeBuilder.setX(w).setY(h).setZ(d); Allocation alloc = Allocation.createTyped(mRS, typeBuilder.create()); alloc.setAutoPadding(true); alloc.copyFrom(inArray); alloc.copyTo(outArray); boolean result = true; for (int i = 0; i < arr_len; i++) { if (inArray[i] != outArray[i]) { result = false; break; } } assertTrue( "test_AllocationCopyTo_3D_Padded_Byte Failed, output array does not match input", result); }
@SuppressLint("NewApi") public static void setAlbumBackground(ImageView albumBg, Bitmap buffer, Activity mActivity) { Bitmap buffer_output = null; if (buffer != null) { // TODO Auto-generated method stub int img_width = buffer.getHeight(); int img_height = buffer.getWidth(); float ratio = (float) img_width / img_height; if (ratio < 1) ratio = 1 / ratio; if (ratio > 2) albumBg.setVisibility(View.INVISIBLE); buffer_output = Bitmap.createBitmap(buffer); final RenderScript rs = RenderScript.create(mActivity); final Allocation input = Allocation.createFromBitmap( rs, buffer, Allocation.MipmapControl.MIPMAP_NONE, Allocation.USAGE_SCRIPT); final Allocation output = Allocation.createTyped(rs, input.getType()); final ScriptIntrinsicBlur script = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs)); script.setRadius(20.0f); script.setInput(input); script.forEach(output); output.copyTo(buffer_output); } if (buffer_output != null) { albumBg.setVisibility(View.VISIBLE); albumBg.setImageBitmap(buffer_output); } else { albumBg.setVisibility(View.INVISIBLE); } }
public void test_AllocationPadded_Long3_2D() { Random random = new Random(0x172d8ab9); int width = random.nextInt(128); int height = random.nextInt(128); int arr_len = width * height * 3; long[] inArray = new long[arr_len]; long[] outArray = new long[arr_len]; for (int i = 0; i < arr_len; i++) { inArray[i] = random.nextLong(); } Type.Builder typeBuilder = new Type.Builder(mRS, Element.I64_3(mRS)); typeBuilder.setX(width).setY(height); Allocation alloc = Allocation.createTyped(mRS, typeBuilder.create()); alloc.setAutoPadding(true); alloc.copyFrom(inArray); alloc.copyTo(outArray); boolean result = true; for (int i = 0; i < arr_len; i++) { if (inArray[i] != outArray[i]) { result = false; break; } } assertTrue( "test_AllocationCopyTo_2D_Padded_Long Failed, output array does not match input", result); }
/** * 高斯模糊 * * @param bitmap * @return */ @SuppressLint("NewApi") public static Bitmap blurBitmap(Bitmap bitmap) { // Let's create an empty bitmap with the same size of the bitmap we want // to blur Bitmap outBitmap = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Config.ARGB_8888); // Instantiate a new Renderscript RenderScript rs = RenderScript.create(MyApplication.getAppContext()); // Create an Intrinsic Blur Script using the Renderscript U8_4(rs) ScriptIntrinsicBlur blurScript = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs)); // Create the Allocations (in/out) with the Renderscript and the in/out // bitmaps Allocation allIn = Allocation.createFromBitmap(rs, bitmap); Allocation allOut = Allocation.createFromBitmap(rs, outBitmap); // Set the radius of the blur blurScript.setRadius(25.f); // Perform the Renderscript blurScript.setInput(allIn); blurScript.forEach(allOut); // Copy the final bitmap created by the out Allocation to the outBitmap allOut.copyTo(outBitmap); // recycle the original bitmap // bitmap.recycle(); // After finishing everything, we destroy the Renderscript. rs.destroy(); return outBitmap; }
/** * Blurs the given Bitmap using RenderScript. * * @param context * @param bitmap * @return */ @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1) private static Bitmap blurUsingRenderScript(final Context context, final Bitmap bitmap) { // Create another bitmap that will hold the results of the filter. Bitmap blurredBitmap = bitmap.copy(bitmap.getConfig(), true); if (blurredBitmap != null) { // Create the Renderscript instance that will do the work. RenderScript rs = RenderScript.create(context); // Allocate memory for Renderscript to work with Allocation input = Allocation.createFromBitmap( rs, blurredBitmap, Allocation.MipmapControl.MIPMAP_FULL, Allocation.USAGE_SCRIPT); Allocation output = Allocation.createTyped(rs, input.getType()); // Load up an instance of the specific script that we want to use. ScriptIntrinsicBlur script = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs)); script.setInput(input); script.setRadius(4); // Set the blur radius script.forEach(output); // Start the ScriptIntrinisicBlur output.copyTo(blurredBitmap); // Copy the output to the blurred bitmap } return blurredBitmap; }
public void test_AllocationPadded_Double3_1D() { Random random = new Random(0x172d8ab9); int width = random.nextInt(512); int arr_len = width * 3; double[] inArray = new double[arr_len]; double[] outArray = new double[arr_len]; for (int i = 0; i < arr_len; i++) { inArray[i] = (double) random.nextFloat(); } Type.Builder typeBuilder = new Type.Builder(mRS, Element.F64_3(mRS)); typeBuilder.setX(width); Allocation alloc = Allocation.createTyped(mRS, typeBuilder.create()); alloc.setAutoPadding(true); alloc.copyFrom(inArray); alloc.copyTo(outArray); boolean result = true; for (int i = 0; i < arr_len; i++) { if (inArray[i] != outArray[i]) { result = false; break; } } assertTrue( "test_AllocationCopyTo_1D_Padded_Double Failed, output array does not match input", result); }
private void float4input(long seed, int testId) { Allocation mAllocationIn = Allocation.createSized(mRS, Element.F32_4(mRS), INPUTSIZE); Allocation mAllocationOut = Allocation.createSized(mRS, Element.U8_4(mRS), INPUTSIZE); float[] inArray = new float[INPUTSIZE * 4]; byte[] outArray = new byte[INPUTSIZE * 4]; byte[] refArray = new byte[INPUTSIZE * 4]; RSUtils.genRandom(seed, 1, 0, inArray); mAllocationIn.copy1DRangeFrom(0, INPUTSIZE, inArray); try { RSUtils.forEach(this, testId, mAllocationIn, mAllocationOut); } catch (RSRuntimeException e) { } mAllocationOut.copyTo(outArray); for (int i = 0; i < outArray.length; i += 4) { int offset = i; Float4 inValues = new Float4( inArray[offset], inArray[offset + 1], inArray[offset + 2], inArray[offset + 3]); byte[] cValue = rs_PackColorTo8888(inValues); refArray[i] = cValue[0]; refArray[i + 1] = cValue[1]; refArray[i + 2] = cValue[2]; refArray[i + 3] = cValue[3]; for (int j = 0; j < 4; j++) { assertEquals(refArray[i + j] & 0xff, outArray[i + j] & 0xff); } } }
private void verifyResultsIlogbFloatInt(Allocation inV, Allocation out, boolean relaxed) { float[] arrayInV = new float[INPUTSIZE * 1]; Arrays.fill(arrayInV, (float) 42); inV.copyTo(arrayInV); int[] arrayOut = new int[INPUTSIZE * 1]; Arrays.fill(arrayOut, (int) 42); out.copyTo(arrayOut); StringBuilder message = new StringBuilder(); boolean errorFound = false; for (int i = 0; i < INPUTSIZE; i++) { for (int j = 0; j < 1; j++) { // Extract the inputs. ArgumentsFloatInt args = new ArgumentsFloatInt(); args.inV = arrayInV[i]; // Extract the outputs. args.out = arrayOut[i * 1 + j]; // Ask the CoreMathVerifier to validate. String errorMessage = CoreMathVerifier.verifyIlogb(args); boolean valid = errorMessage == null; if (!valid) { if (!errorFound) { errorFound = true; message.append("Input inV: "); appendVariableToMessage(message, args.inV); message.append("\n"); message.append("Output out: "); appendVariableToMessage(message, args.out); message.append("\n"); message.append(errorMessage); message.append("Errors at"); } message.append(" ["); message.append(Integer.toString(i)); message.append(", "); message.append(Integer.toString(j)); message.append("]"); } } } assertFalse( "Incorrect output for checkIlogbFloatInt" + (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound); }
public byte[] decodeBMPToYUV422(Bitmap bmp) { int width = bmp.getWidth(); int height = bmp.getHeight(); boolean needUpdateAllocation = false; if (mOriginHeight2 != height || mOriginWidth2 != width) { mOriginWidth2 = width; mOriginHeight2 = height; needUpdateAllocation = true; } Type.Builder tbIn = new Type.Builder(mRS, Element.RGBA_8888(mRS)); tbIn.setX(width).setY(height); // tbIn.setX(nv21.length); Type.Builder tbOut = new Type.Builder(mRS, Element.U8(mRS)); tbOut.setX(width * height + width * height / 2); // if(mInAlloc2==null){ // mInAlloc2=Allocation.createTyped(mRS, tbIn.create(),Allocation.USAGE_SCRIPT); // } if (mOutAlloc2 == null || needUpdateAllocation) { mOutAlloc2 = Allocation.createTyped(mRS, tbOut.create(), Allocation.USAGE_SCRIPT); } mInAlloc2 = Allocation.createFromBitmap(mRS, bmp); mScript.bind_bmpInput(mInAlloc2); mScript.bind_yuvOutput(mOutAlloc2); // // mScript.bind_input(mInAlloc2); // mScript.bind_output(mOutAlloc2); mScript.set_mImageWidth(width); mScript.set_mImageHeight(height); int[] indexBuffer = new int[height]; for (int i = 0; i < indexBuffer.length; i++) { indexBuffer[i] = i; } Type.Builder tbIndex = new Type.Builder(mRS, Element.I32(mRS)); tbIndex.setX(indexBuffer.length); if (mIndexAlloc2 == null || needUpdateAllocation) { mIndexAlloc2 = Allocation.createTyped(mRS, tbIndex.create()); mOriginHeight2 = height; } mIndexAlloc2.copyFrom(indexBuffer); mScript.forEach_process_jpg2yuv(mIndexAlloc2); if (mOutput2 == null || needUpdateAllocation) { mOutputLength2 = width * height + width * height / 2; mOutput2 = new byte[mOutputLength2]; } mOutAlloc2.copyTo(mOutput2); return mOutput2; }
/* 本程序中大概耗时为20-30毫秒 */ private Bitmap blurBitmap(Bitmap bitmap, int radius) { RenderScript rs = RenderScript.create(this); Allocation overlayAlloc = Allocation.createFromBitmap(rs, bitmap); ScriptIntrinsicBlur blur = ScriptIntrinsicBlur.create(rs, overlayAlloc.getElement()); blur.setInput(overlayAlloc); blur.setRadius(radius); blur.forEach(overlayAlloc); overlayAlloc.copyTo(bitmap); rs.destroy(); return bitmap; }
private void verify(double[] a1, double[] a2, Allocation alloc, String s, int vsize) { alloc.copyTo(a2); for (int i = 0; i < gWidth; i++) { if (a1[i] != a2[i]) { if ((vsize == 3) && ((i % 4) == 3)) { continue; } throw new RSRuntimeException(s + a1[i] + ", " + a2[i] + ", at " + i); } a2[i] = 0; } alloc.copyFrom(a2); }
public Bitmap blur(Bitmap bitmap) { Bitmap blurredMap = bitmap.copy(bitmap.getConfig(), true); RenderScript rs = RenderScript.create(this); final Allocation input = Allocation.createFromBitmap(rs, blurredMap); final Allocation output = Allocation.createTyped(rs, input.getType()); final ScriptIntrinsicBlur script = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs)); script.setRadius(5f); script.setInput(input); script.forEach(output); output.copyTo(blurredMap); return blurredMap; }
@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1) @Override protected Bitmap blur(Bitmap bitmap, int radius) { RenderScript rs = RenderScript.create(getActivity()); Allocation overlayAlloc = Allocation.createFromBitmap(rs, bitmap); ScriptIntrinsicBlur blur = ScriptIntrinsicBlur.create(rs, overlayAlloc.getElement()); blur.setInput(overlayAlloc); blur.setRadius(radius); blur.forEach(overlayAlloc); overlayAlloc.copyTo(bitmap); rs.destroy(); return bitmap; }
public static Bitmap blur(Context context, Bitmap image, float radius) { int width = Math.round(image.getWidth() * BITMAP_SCALE); int height = Math.round(image.getHeight() * BITMAP_SCALE); Bitmap inputBitmap = Bitmap.createScaledBitmap(image, width, height, false); Bitmap outputBitmap = Bitmap.createBitmap(inputBitmap); RenderScript rs = RenderScript.create(context); ScriptIntrinsicBlur theIntrinsic = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs)); Allocation tmpIn = Allocation.createFromBitmap(rs, inputBitmap); Allocation tmpOut = Allocation.createFromBitmap(rs, outputBitmap); theIntrinsic.setRadius(radius); theIntrinsic.setInput(tmpIn); theIntrinsic.forEach(tmpOut); tmpOut.copyTo(outputBitmap); return outputBitmap; }
public byte[] decodeNV21ToRGB888(byte[] nv21, int width, int height, int degree) { Type.Builder tbIn = new Type.Builder(mRS, Element.U8(mRS)); tbIn.setX(nv21.length); Type.Builder tbOut = new Type.Builder(mRS, Element.U8(mRS)); tbOut.setX(width * height * 4); if (mInAlloc == null) { mInAlloc = Allocation.createTyped(mRS, tbIn.create()); } if (mOutAlloc == null) { mOutAlloc = Allocation.createTyped(mRS, tbOut.create()); } mInAlloc.copyFrom(nv21); mScript.bind_input(mInAlloc); mScript.bind_output(mOutAlloc); mScript.set_rotateDegree(degree); mScript.set_mImageWidth(width); mScript.set_mImageHeight(height); int[] indexBuffer = new int[height]; for (int i = 0; i < indexBuffer.length; i++) { indexBuffer[i] = i; } Type.Builder tbIndex = new Type.Builder(mRS, Element.I32(mRS)); tbIndex.setX(indexBuffer.length); if (mIndexAlloc == null) { mIndexAlloc = Allocation.createTyped(mRS, tbIndex.create()); } mIndexAlloc.copyFrom(indexBuffer); mScript.forEach_process(mIndexAlloc); if (mOutput == null || mOutputLength == -1) { mOutputLength = width * height * 4; mOutput = new byte[mOutputLength]; } mOutAlloc.copyTo(mOutput); return mOutput; }
private void updateBlur() { if (!(mDrawable instanceof BitmapDrawable)) { return; } final int textViewHeight = mTextView.getHeight(); if (textViewHeight == 0) { return; } // Determine the size of the TextView compared to the height of the ImageView final float ratio = (float) textViewHeight / mImageView.getHeight(); // Get the Bitmap final BitmapDrawable bitmapDrawable = (BitmapDrawable) mDrawable; final Bitmap originalBitmap = bitmapDrawable.getBitmap(); // Calculate the height as a ratio of the Bitmap int height = (int) (ratio * originalBitmap.getHeight()); // The y position is the number of pixels height represents from the bottom of the Bitmap final int y = originalBitmap.getHeight() - height; final Bitmap portionToBlur = Bitmap.createBitmap(originalBitmap, 0, y, originalBitmap.getWidth(), height); final Bitmap blurredBitmap = portionToBlur.copy(Bitmap.Config.ARGB_8888, true); // Use RenderScript to blur the pixels RenderScript rs = RenderScript.create(getContext()); ScriptIntrinsicBlur theIntrinsic = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs)); Allocation tmpIn = Allocation.createFromBitmap(rs, portionToBlur); Allocation tmpOut = Allocation.createFromBitmap(rs, blurredBitmap); theIntrinsic.setRadius(25f); theIntrinsic.setInput(tmpIn); theIntrinsic.forEach(tmpOut); tmpOut.copyTo(blurredBitmap); new Canvas(blurredBitmap).drawColor(mScrimColor); // Create the new bitmap using the old plus the blurred portion and display it final Bitmap newBitmap = originalBitmap.copy(Bitmap.Config.ARGB_8888, true); final Canvas canvas = new Canvas(newBitmap); canvas.drawBitmap(blurredBitmap, 0, y, new Paint()); mImageView.setImageBitmap(newBitmap); }
public static Bitmap convertToBlur(Bitmap bmp, Context context) { final int radius = 20; if (Build.VERSION.SDK_INT > 16) { Log.d(MenuView.class.getSimpleName(), "VERSION.SDK_INT " + Build.VERSION.SDK_INT); Bitmap bitmap = bmp.copy(bmp.getConfig(), true); final RenderScript rs = RenderScript.create(context); final Allocation input = Allocation.createFromBitmap( rs, bmp, Allocation.MipmapControl.MIPMAP_NONE, Allocation.USAGE_SCRIPT); final Allocation output = Allocation.createTyped(rs, input.getType()); final ScriptIntrinsicBlur script = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs)); script.setRadius(radius /* e.g. 3.f */); script.setInput(input); script.forEach(output); output.copyTo(bitmap); return bitmap; } return bmp; }
/** 图片模糊效果 */ public static Bitmap blurBitmap(Context context, Bitmap bitmap, float radius) { Bitmap outBitmap = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Bitmap.Config.ARGB_8888); RenderScript rs = RenderScript.create(context); ScriptIntrinsicBlur blurScript = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs)); Allocation allIn = Allocation.createFromBitmap(rs, bitmap); Allocation allOut = Allocation.createFromBitmap(rs, bitmap); blurScript.setRadius(radius); blurScript.setInput(allIn); blurScript.forEach(allOut); allOut.copyTo(outBitmap); bitmap.recycle(); rs.destroy(); return outBitmap; }
@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1) public static Bitmap blur(Context context, Bitmap bitmap, int radius) throws RSRuntimeException { RenderScript rs = null; try { rs = RenderScript.create(context); Allocation input = Allocation.createFromBitmap( rs, bitmap, Allocation.MipmapControl.MIPMAP_NONE, Allocation.USAGE_SCRIPT); Allocation output = Allocation.createTyped(rs, input.getType()); ScriptIntrinsicBlur blur = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs)); blur.setInput(input); blur.setRadius(radius); blur.forEach(output); output.copyTo(bitmap); } finally { if (rs != null) { rs.destroy(); } } return bitmap; }
public void setBackgroundProfileImage(String url, ImageView imageView) { File possibleCachedFile = new File(getCacheDir() + File.separator, Integer.toString(url.hashCode())); if (possibleCachedFile.exists()) { Bitmap photo = BitmapFactory.decodeFile(possibleCachedFile.getPath()); final RenderScript renderScript = RenderScript.create(this); final Allocation input = Allocation.createFromBitmap( renderScript, photo, Allocation.MipmapControl.MIPMAP_NONE, Allocation.USAGE_SCRIPT); final Allocation output = Allocation.createTyped(renderScript, input.getType()); final ScriptIntrinsicBlur script = ScriptIntrinsicBlur.create(renderScript, Element.U8_4(renderScript)); script.setRadius(3.f); script.setInput(input); script.forEach(output); output.copyTo(photo); imageView.setImageBitmap(photo); } }
public void blur(Bitmap bkg) { long startMs = System.currentTimeMillis(); float radius = 20; bkg = small(bkg); Bitmap bitmap = bkg.copy(bkg.getConfig(), true); final RenderScript rs = RenderScript.create(context); final Allocation input = Allocation.createFromBitmap( rs, bkg, Allocation.MipmapControl.MIPMAP_NONE, Allocation.USAGE_SCRIPT); final Allocation output = Allocation.createTyped(rs, input.getType()); final ScriptIntrinsicBlur script = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs)); script.setRadius(radius); script.setInput(input); script.forEach(output); output.copyTo(bitmap); bitmap = big(bitmap); this.bitmaps = bitmap; // setBackground(new BitmapDrawable(context.getResources(), bitmap)); rs.destroy(); Log.d("zhangle", "blur take away:" + (System.currentTimeMillis() - startMs) + "ms"); }
@SuppressLint("NewApi") public static Bitmap fastblur(Context context, Bitmap sentBitmap, int radius) { try { if (VERSION.SDK_INT > 16) { Bitmap bitmap = sentBitmap.copy(sentBitmap.getConfig(), true); final RenderScript rs = RenderScript.create(context); final Allocation input = Allocation.createFromBitmap( rs, sentBitmap, Allocation.MipmapControl.MIPMAP_NONE, Allocation.USAGE_SCRIPT); final Allocation output = Allocation.createTyped(rs, input.getType()); final ScriptIntrinsicBlur script = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs)); script.setRadius(radius /* e.g. 3.f */); script.setInput(input); script.forEach(output); output.copyTo(bitmap); return bitmap; } // Stack Blur v1.0 from // http://www.quasimondo.com/StackBlurForCanvas/StackBlurDemo.html // // Java Author: Mario Klingemann <mario at quasimondo.com> // http://incubator.quasimondo.com // created Feburary 29, 2004 // Android port : Yahel Bouaziz <yahel at kayenko.com> // http://www.kayenko.com // ported april 5th, 2012 // 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. // // If you are using this algorithm in your code please add // the following line: // // Stack Blur Algorithm by Mario Klingemann <*****@*****.**> Bitmap bitmap = sentBitmap.copy(sentBitmap.getConfig(), true); if (radius < 1) { return (null); } int w = bitmap.getWidth(); int h = bitmap.getHeight(); int[] pix = new int[w * h]; Log.e("pix", w + " " + h + " " + pix.length); bitmap.getPixels(pix, 0, w, 0, 0, w, h); int wm = w - 1; int hm = h - 1; int wh = w * h; 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(w, h)]; 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 < h; y++) { rinsum = ginsum = binsum = routsum = goutsum = boutsum = rsum = gsum = bsum = 0; for (i = -radius; i <= radius; i++) { p = pix[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 < w; x++) { 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 = pix[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 += w; } for (x = 0; x < w; x++) { rinsum = ginsum = binsum = routsum = goutsum = boutsum = rsum = gsum = bsum = 0; yp = -radius * w; 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 += w; } } yi = x; stackpointer = radius; for (y = 0; y < h; y++) { // Preserve alpha channel: ( 0xff000000 & pix[yi] ) pix[yi] = (0xff000000 & pix[yi]) | (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) * w; } 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 += w; } } Log.e("pix", w + " " + h + " " + pix.length); bitmap.setPixels(pix, 0, w, 0, 0, w, h); return (bitmap); } catch (Exception e) { e.printStackTrace(); return null; } }
public synchronized void render(RenderingRequest request) { // TODO: cleanup/remove GEOMETRY / FILTERS paths synchronized (CachingPipeline.class) { if (getRenderScriptContext() == null) { return; } if ((request.getType() != RenderingRequest.PARTIAL_RENDERING && request.getType() != RenderingRequest.ICON_RENDERING && request.getBitmap() == null) || request.getImagePreset() == null) { return; } if (DEBUG) { Log.v(LOGTAG, "render image of type " + getType(request)); } Bitmap bitmap = request.getBitmap(); ImagePreset preset = request.getImagePreset(); setupEnvironment(preset, true); mFiltersManager.freeFilterResources(preset); if (request.getType() == RenderingRequest.PARTIAL_RENDERING) { MasterImage master = MasterImage.getImage(); bitmap = ImageLoader.getScaleOneImageForPreset( master.getActivity(), mEnvironment.getBimapCache(), master.getUri(), request.getBounds(), request.getDestination()); if (bitmap == null) { Log.w(LOGTAG, "could not get bitmap for: " + getType(request)); return; } } if (request.getType() == RenderingRequest.FULL_RENDERING || request.getType() == RenderingRequest.GEOMETRY_RENDERING || request.getType() == RenderingRequest.FILTERS_RENDERING) { updateOriginalAllocation(preset); } if (DEBUG && bitmap != null) { Log.v( LOGTAG, "after update, req bitmap (" + bitmap.getWidth() + "x" + bitmap.getHeight() + " ? resizeOriginal (" + mResizedOriginalBitmap.getWidth() + "x" + mResizedOriginalBitmap.getHeight()); } if (request.getType() == RenderingRequest.FULL_RENDERING || request.getType() == RenderingRequest.GEOMETRY_RENDERING) { mOriginalAllocation.copyTo(bitmap); } else if (request.getType() == RenderingRequest.FILTERS_RENDERING) { mFiltersOnlyOriginalAllocation.copyTo(bitmap); } if (request.getType() == RenderingRequest.FULL_RENDERING || request.getType() == RenderingRequest.FILTERS_RENDERING || request.getType() == RenderingRequest.ICON_RENDERING || request.getType() == RenderingRequest.PARTIAL_RENDERING || request.getType() == RenderingRequest.STYLE_ICON_RENDERING) { if (request.getType() == RenderingRequest.ICON_RENDERING) { mEnvironment.setQuality(FilterEnvironment.QUALITY_ICON); } else { mEnvironment.setQuality(FilterEnvironment.QUALITY_PREVIEW); } if (request.getType() == RenderingRequest.ICON_RENDERING) { Rect iconBounds = request.getIconBounds(); Bitmap source = MasterImage.getImage().getThumbnailBitmap(); if (iconBounds.width() > source.getWidth() * 2) { source = MasterImage.getImage().getLargeThumbnailBitmap(); } if (iconBounds != null) { bitmap = mEnvironment.getBitmap(iconBounds.width(), iconBounds.height(), BitmapCache.ICON); Canvas canvas = new Canvas(bitmap); Matrix m = new Matrix(); float minSize = Math.min(source.getWidth(), source.getHeight()); float maxSize = Math.max(iconBounds.width(), iconBounds.height()); float scale = maxSize / minSize; m.setScale(scale, scale); float dx = (iconBounds.width() - (source.getWidth() * scale)) / 2.0f; float dy = (iconBounds.height() - (source.getHeight() * scale)) / 2.0f; m.postTranslate(dx, dy); canvas.drawBitmap(source, m, new Paint(Paint.FILTER_BITMAP_FLAG)); } else { bitmap = mEnvironment.getBitmapCopy(source, BitmapCache.ICON); } } Bitmap bmp = preset.apply(bitmap, mEnvironment); if (!mEnvironment.needsStop()) { request.setBitmap(bmp); } mFiltersManager.freeFilterResources(preset); } } }
@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1) public static Bitmap fastblur(Context context, Bitmap sentBitmap, int radius) { if (Build.VERSION.SDK_INT > 16) { Bitmap bitmap = sentBitmap.copy(sentBitmap.getConfig(), true); final RenderScript rs = RenderScript.create(context); final Allocation input = Allocation.createFromBitmap( rs, sentBitmap, Allocation.MipmapControl.MIPMAP_NONE, Allocation.USAGE_SCRIPT); final Allocation output = Allocation.createTyped(rs, input.getType()); final ScriptIntrinsicBlur script = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs)); script.setRadius(radius); script.setInput(input); script.forEach(output); output.copyTo(bitmap); return bitmap; } Bitmap bitmap = sentBitmap.copy(sentBitmap.getConfig(), true); if (radius < 1) { return (null); } int w = bitmap.getWidth(); int h = bitmap.getHeight(); int[] pix = new int[w * h]; bitmap.getPixels(pix, 0, w, 0, 0, w, h); int wm = w - 1; int hm = h - 1; int wh = w * h; 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(w, h)]; 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 < h; y++) { rinsum = ginsum = binsum = routsum = goutsum = boutsum = rsum = gsum = bsum = 0; for (i = -radius; i <= radius; i++) { p = pix[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 < w; x++) { 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 = pix[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 += w; } for (x = 0; x < w; x++) { rinsum = ginsum = binsum = routsum = goutsum = boutsum = rsum = gsum = bsum = 0; yp = -radius * w; 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 += w; } } yi = x; stackpointer = radius; for (y = 0; y < h; y++) { pix[yi] = (0xff000000 & pix[yi]) | (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) * w; } 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 += w; } } bitmap.setPixels(pix, 0, w, 0, 0, w, h); return (bitmap); }