gpt4 book ai didi

android - 在 android 中显示深度的图像形状的浮雕边缘

转载 作者:塔克拉玛干 更新时间:2023-11-02 20:37:10 25 4
gpt4 key购买 nike

我想显示 3D 浮雕外观,如下图所示。我使用了 EmbossMaskFilter 但无法显示效果(请参见下面的代码)。有没有不同的方法来做到这一点?或者我如何为此使用 EmbossMaskFilter。

要求的输出

enter image description here

我的输出

enter image description here

Path path2 = new Path();
public Paint fillPaint = null;
// called in constructor
public void createPath()
{
//path 2 Big one
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);

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.setStyle(Paint.Style.FILL);
paint.setMaskFilter(mEmboss);
}

// add lines to the path
protected Path AddLine(Path path, int endX, int endY) {
//path.moveTo(startX, startY);

path.lineTo(endX, endY);
return path;
}

// add curves to the 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;
}

//draw on canvas
@Override
public void onDraw(Canvas canvas) {

canvas.drawPath(path2, fillPaint);
super.onDraw(canvas);
}

最佳答案

如果您只想进行位图处理(而不是 3D 或矢量),您最好的选择可能是:

  1. 从您的拼图中生成模板掩码,
  2. 使用Difference of Gaussians处理它(我在这个例子中使用了大小为 12 和 2 像素的内核),然后对结果进行归一化和反转,
  3. 使用蒙版 (1.) 作为模板 channel ,将“2”的输出 Alpha 混合到原始图像中。

Mask Difference of Gaussians Result

更新:代码来了。我试图重用您的变量名,以便更容易理解。该代码尽可能使用 Renderscript 内在函数,以使事情变得更快、更有趣。

private Paint fillPaint = null;
private Path path2;
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;
private Context ctx;
private int bw = 780;
private int bh = 780;

private void init()
{
mBitmapIn = loadBitmap(R.drawable.cat7); // background image
mBitmapPuzzle = Bitmap.createBitmap(bw, bh, Bitmap.Config.ARGB_8888); // this will hold the puzzle
Canvas c = new Canvas(mBitmapPuzzle);

path2 = new Path();
createPath(5); // create the path with stroke width of 5 pixels
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);

让我们稍作休息,看看到目前为止我们有什么。观察左边的整个图像是不透明的(即包括拼图外面的空间),我们现在必须剪掉形状并适本地消除其边缘的锯齿。不幸的是,使用原始形状是行不通的,因为它太大并且切掉太多,导致边缘附近出现令人不快的伪影(右图)。

enter image description here enter image description here

因此我们绘制另一条路径,这次使用较窄的笔触...

    Bitmap mBitmapCutter = Bitmap.createBitmap(bw, bh, Bitmap.Config.ARGB_8888);
c = new Canvas(mBitmapCutter);
path2 = new Path();
createPath(1); // stroke width 1
c.drawPath(path2, fillPaint);
mCutterAllocation = Allocation.createFromBitmap(mRS, mBitmapCutter);

// cookie cutter now
mScriptBlend.forEachDstIn(mCutterAllocation, mOutAllocation);

...为了更好看的结果。让我们用它来遮盖背景图像。 enter image description here

    mScriptBlend.forEachMultiply(mOutAllocation, mInAllocation);
mInAllocation.copyTo(mBitmapPuzzle);
}

enter image description here

你好!现在只是 Renderscript 设置代码。

private void createScript() {
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));
}

最后 onDraw():

@Override
protected void onDraw(Canvas canvas) {
canvas.drawBitmap(mBitmapPuzzle, 0, 0, fillPaint);
super.onDraw(canvas);
}

TODO:检查其他描边斜接是否会产生更舒适的角。

关于android - 在 android 中显示深度的图像形状的浮雕边缘,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31562845/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com