I want to show 3D embossed look and feel as shown in following image. I used EmbossMaskFilter but cannot get it to show the effect (see code below). Is there a different way to do this? or how can I use the EmbossMaskFilter for this.
Required output
My output
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);
}
If you only want to do bitmap processing (as opposed to 3D or vectors), your best bet probably is to:
UPDATE: here comes the code. I tried to reuse your variable names so that it's easier to understand. The code uses Renderscript intrinsics whenever possible in order to make things faster and more interesting.
Let's make a short break and see what we have so far. Observe that the entire image on the left is opaque (i.e. including the space outside the puzzle), and we now have to cut out the shape and antialias its edge properly. Unfortunately, using original shape won't work, as it is too large and cuts out too much, leading to unpleasant artifacts near the edge (figure on the right).
We therefore draw another path, this time using a narrower stroke...
...for a much better looking result. Let's use it to mask out a background image.
Hello there! Now just the Renderscript setup code.
And finally
onDraw()
:TODO: check if other stroke miters would give more pleasant corners.
If you're not afraid of dabbling into some low-level image processing, you can use convolution matrices to achieve an emboss effect. You could use your image's silhouette (i.e. the alpha channel) as an input to the filter. For example, if you use this 5x5 matrix:
and apply it to such image (representing an alpha channel):
you'll get this effect:
All of the computed values have been decreased by 127 to ensure that they will be in range of 0-255. I used
n = 10
in this particular example. You can manipulate the radius by using a matrix of different size (it's not hard to extrapolate) and the depth by adjusting the value ofn
(the bigger the value, the subtler the effect).Given the original alpha channel, and the computed mask you can determine offsets to apply to the respective pixels of the original image, thus creating an emboss effect.
Hope that helps.
I think you will need a larger blur radius and smaller values for ambient light and specular highlight.
I played around with this by creating a UI to tweak parameters.
Here is the code I used, so you can try it out. I used a simple blue rectangle, but you should be able to easily plug in whatever image you want to draw.
MainActivity.java:
DrawView.java:
activity_main.xml: