这个问题基于link。 我试了@ miloslaw-smyk的答案。但是我无法让它发挥作用。我不确定createPath(1)的含义。我不知道如何创建具有一定笔画宽度的路径。我们可以使用fillpaint来做到这一点。无论如何,我已经展示了完整的代码。问题是我没有看到原始链接显示的任何浮雕效果(参见下面的输出图像)。请让我知道我做错了什么。 (我使用的是targetSdkVersion 23,设备已更新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 (e.g. 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);
}
答案 0 :(得分:0)
您可以试用我的createPath()
版本吗?我稍微修改它以绘制更大的拼图并接受笔画宽度作为参数。
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 + p.x), p.y);
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);
}