Use RenderScript to emboss a form in android

This question is based on a link. I tried to answer @ miloslaw-smyk. However, I could not get it to work. I'm not sure what createPath (1) means. I am not sure how to create a path with a specific stroke width. We can do this using fillpaint. In any case, I showed the full code below. Problem: I do not see the embossing effect shown by the source link (see Output Image below). Please let me know what I did wrong. (I am using targetSdkVersion 23 and the device is updated 4.1.2 android)

private Bitmap puzzelImage; // screen size image private Bitmap mBitmapIn; private Bitmap mBitmapPuzzle; private RenderScript mRS; private Allocation mInAllocation; private Allocation mPuzzleAllocation; private Allocation mCutterAllocation; private Allocation mOutAllocation; private Allocation mOutAllocation2; private Allocation mAllocationHist; private ScriptIntrinsicBlur mScriptBlur; private ScriptIntrinsicBlend mScriptBlend; private ScriptIntrinsicHistogram mScriptHistogram; private ScriptIntrinsicLUT mScriptLUT; public Activity ctx; private int bw = 780; private int bh = 780; Path path2; private void init() { if (puzzel.mybitmap == null) return; bw = puzzelImage.getWidth(); bh = puzzelImage.getHeight(); mBitmapIn = puzzelImage ; mBitmapPuzzle = Bitmap.createBitmap(bw, bh, Bitmap.Config.ARGB_8888); // this will hold the puzzle Canvas c = new Canvas(mBitmapPuzzle); createPath(); //path2 = path1; fillPaint.setStrokeWidth(5); c.drawPath(path2, fillPaint); // draw it on canvas createScript(); // get renderscripts and Allocations ready // Apply gaussian blur of radius 25 to our drawing mScriptBlur.setRadius(25); mScriptBlur.setInput(mPuzzleAllocation); mScriptBlur.forEach(mOutAllocation); // Now apply the blur of radius 1 mScriptBlur.setRadius(1); mScriptBlur.setInput(mPuzzleAllocation); mScriptBlur.forEach(mOutAllocation2); // Subtract one blur result from another mScriptBlend.forEachSubtract(mOutAllocation, mOutAllocation2); // We now want to normalize the result (eg make it use full 0-255 range). // To do that, we will first compute the histogram of our image mScriptHistogram.setOutput(mAllocationHist); mScriptHistogram.forEach(mOutAllocation2); // copy the histogram to Java array... int []hist = new int[256 * 4]; mAllocationHist.copyTo(hist); // ...and walk it from the end looking for the first non empty bin int i; for(i = 255; i > 1; i--) if((hist[i * 4] | hist[i * 4 + 1] | hist[i * 4 + 2]) != 0) break; // Now setup the LUTs that will map the image to the new, wider range. // We also use the opportunity to inverse the image ("255 -"). for(int x = 0; x <= i; x++) { int val = 255 - x * 255 / i; mScriptLUT.setAlpha(x, 255); // note we always make it fully opaque mScriptLUT.setRed(x, val); mScriptLUT.setGreen(x, val); mScriptLUT.setBlue(x, val); } // the mapping itself. mScriptLUT.forEach(mOutAllocation2, mOutAllocation); Bitmap mBitmapCutter = Bitmap.createBitmap(bw, bh, Bitmap.Config.ARGB_8888); c = new Canvas(mBitmapCutter); createPath(); fillPaint.setStrokeWidth(1); c.drawPath(path2, fillPaint); mCutterAllocation = Allocation.createFromBitmap(mRS, mBitmapCutter); // cookie cutter now mScriptBlend.forEachDstIn(mCutterAllocation, mOutAllocation); mScriptBlend.forEachMultiply(mOutAllocation, mInAllocation); mInAllocation.copyTo(mBitmapPuzzle); } private void createScript() { try { mRS = RenderScript.create(ctx); mPuzzleAllocation = Allocation.createFromBitmap(mRS, mBitmapPuzzle); // three following allocations could actually use createSized(), // but the code would be longer. mInAllocation = Allocation.createFromBitmap(mRS, mBitmapIn); mOutAllocation = Allocation.createFromBitmap(mRS, mBitmapPuzzle); mOutAllocation2 = Allocation.createFromBitmap(mRS, mBitmapPuzzle); mAllocationHist = Allocation.createSized(mRS, Element.I32_3(mRS), 256); mScriptBlur = ScriptIntrinsicBlur.create(mRS, Element.U8_4(mRS)); mScriptBlend = ScriptIntrinsicBlend.create(mRS, Element.U8_4(mRS)); mScriptHistogram = ScriptIntrinsicHistogram.create(mRS, Element.U8_4(mRS)); mScriptLUT = ScriptIntrinsicLUT.create(mRS, Element.U8_4(mRS)); }catch (Exception e) { } } public void createPath() { path2 = new Path(); //path 1 samll one Point[] araay = new Point[]{new Point(144,320),new Point(109,200), new Point(171,308),new Point(178,240),new Point(171,172),new Point(109,282),new Point(144,160)}; AddBeziers(path2, araay, 320, 144); AddLine(path2, 216, 144 ); AddLine(path2, 216, 216 ); AddLine(path2, 144, 320); fillPaint = new Paint(Paint.ANTI_ALIAS_FLAG); fillPaint.setColor(Color.WHITE); fillPaint.setFlags(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG); fillPaint.setAntiAlias(true); fillPaint.setDither(true); fillPaint.setStrokeJoin(Paint.Join.ROUND); fillPaint.setStrokeCap(Paint.Cap.ROUND); fillPaint.setStyle(Paint.Style.FILL_AND_STROKE); } protected Path AddLine(Path path, int endX, int endY) { //path.moveTo(startX, startY); path.lineTo(endX, endY); return path; } protected Path AddBeziers(Path path, Point[] points, int lastX, int lastY) { if (points[0].X != lastX && points[0].Y != lastY) path.moveTo(points[0].X, points[0].Y); int index = 1; path.cubicTo(points[index].X, points[index].Y, points[index + 1].X, points[index + 1].Y, points[index + 2].X, points[index + 2].Y); index = index + 3; path.cubicTo(points[index].X, points[index].Y, points[index + 1].X, points[index + 1].Y, points[index + 2].X, points[index + 2].Y); return path; /*pointsCounter = points.length; //point = new PointNew(new PointF(points[1].X, points[1].Y)); prev = new PointNew(new PointF(points[0].X, points[0].Y)); //next = new PointNew(new PointF(points[2].X, points[2].Y)); for (int i =1; i < points.length; i++) appendToPath(path, new PointF(points[i].X, points[i].Y), null); return path;*/ } @Override protected void onDraw(Canvas canvas) { canvas.drawBitmap(mBitmapPuzzle, 0, 0, fillPaint); super.onDraw(canvas); } 

enter image description here

+1
source share
1 answer

Can you try with my version of createPath() ? I modified it a bit to draw a big puzzle and take the stroke width as an argument.

 public void createPath(int strokeWidth) { //path 2 Big one Point[]araay = new Point[]{new Point(144,320),new Point(109,200), new Point(171,308),new Point(178,240),new Point(171,172),new Point(109,282),new Point(144,160)}; Point[]braay = new Point[araay.length]; int idx = 6; for(Point p : araay) braay[idx--] = new Point((200 + px), py); path2.moveTo(144,320); AddBeziers(path2, araay, 320, 144); AddLine(path2, 216, 144); AddBeziers(path2, braay, 320, 144); AddLine(path2, 144, 320); path2.close(); Matrix m = new Matrix(); m.setScale(2, 2); path2.transform(m); MaskFilter mEmboss = new EmbossMaskFilter(new float[] { 1, 1, 1 }, 0.4f, 6, 3.5f); fillPaint = new Paint(Paint.ANTI_ALIAS_FLAG); fillPaint.setColor(Color.WHITE); fillPaint.setFlags(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG); fillPaint.setAntiAlias(true); fillPaint.setDither(true); fillPaint.setStrokeJoin(Paint.Join.ROUND); fillPaint.setStrokeCap(Paint.Cap.ROUND); fillPaint.setStrokeWidth(strokeWidth); fillPaint.setStyle(Paint.Style.FILL_AND_STROKE); fillPaint.setStrokeMiter(0); } 
0
source

All Articles