引言:
最近接到需求,要做一个仿微信拍照的程序,并添加一个证件照蒙皮。
做法:
自定义一个View,这个View的中心绘制一个矩形,即我们的证件框,周围绘制阴影(就是这里的蒙皮)
代码:
package com.example.myjcamera.cameralibrary;
import android.app.Activity;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.View;
import com.example.myjcamera.cameralibrary.util.ScreenUtils;
public class CameraTopRectView extends View {
private int viewWidth;
private int viewHeight;
public int rectWidth;
public int rectHeght;
private int rectTop;
private int rectLeft;
private int rectRight;
private int rectBottom;
private int lineLen; //这个是四个角 八条线 的宽度
private static final int LINE_WIDTH = 5;
private static final int LEFT_PADDING = 10;
private static final int RIGHT_PADDING = 10;
private static final String TIPS = "请将身份证放入到方框中";
private Paint linePaint;
private Paint wordPaint;
private Rect rect;
private int baseline;
public CameraTopRectView(Context context, AttributeSet attrs) {
super(context, attrs);
Activity activity = (Activity) context;
int panelWidth = ScreenUtils.getScreenWidth(context); //拿到屏幕的宽
int panelHeght = ScreenUtils.getScreenHeight(context);//拿到屏幕的高
//高度不需要dp转换px,不然整体相机会向上移动一小节
// viewHeight = panelHeght - (int) DisplayUtil.dp2px(activity,TOP_BAR_HEIGHT + BOTTOM_BTN_HEIGHT);
viewHeight = panelHeght;
//viewHeight,界面的高,viewWidth,界面的宽
viewWidth = panelWidth;
rectWidth = panelWidth - ScreenUtils.dp2px(activity,LEFT_PADDING + RIGHT_PADDING);
rectHeght = (int) (rectWidth * 54 / 85.6);
// 相对于此view,框框的四个边界值,即绘制矩形的四个参数
rectTop = (viewHeight - rectHeght) / 2;
rectLeft = (viewWidth - rectWidth) / 2;
rectBottom = rectTop + rectHeght;
rectRight = rectLeft + rectWidth;
lineLen = panelWidth / 8;
linePaint = new Paint();
linePaint.setAntiAlias(true);
linePaint.setColor(Color.rgb(0xdd, 0x42, 0x2f));
linePaint.setStyle(Paint.Style.STROKE);
linePaint.setStrokeWidth(LINE_WIDTH);// 设置线宽
linePaint.setAlpha(255);
//默认情况为FILL模式
wordPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
wordPaint.setStrokeWidth(3);
wordPaint.setTextSize(35);
rect = new Rect(rectLeft, rectTop - 80, rectRight, rectTop - 10);
Paint.FontMetricsInt fontMetrics = wordPaint.getFontMetricsInt();
baseline = rect.top + (rect.bottom - rect.top - fontMetrics.bottom + fontMetrics.top) / 2 - fontMetrics.top;
wordPaint.setTextAlign(Paint.Align.CENTER);
}
@Override
public void onDraw(Canvas canvas) {
super.onDraw(canvas);
wordPaint.setColor(Color.TRANSPARENT);
canvas.drawRect(rect, wordPaint);
//画蒙层 即将方块周围的部分涂上阴影
//下面
wordPaint.setColor(0xa0000000); //蒙皮的颜色
rect = new Rect(0, viewHeight/2+rectHeght/2, viewWidth, viewHeight);
canvas.drawRect(rect, wordPaint);
//上面
rect = new Rect(0, 0, viewWidth, viewHeight/2-rectHeght/2);
canvas.drawRect(rect, wordPaint);
//左边
rect = new Rect(0, viewHeight/2-rectHeght/2, (viewWidth-rectWidth)/2, viewHeight/2+rectHeght/2);
canvas.drawRect(rect, wordPaint);
//右边
rect = new Rect(viewWidth-(viewWidth-rectWidth)/2, viewHeight/2-rectHeght/2, viewWidth, viewHeight/2+rectHeght/2);
canvas.drawRect(rect, wordPaint);
//重制rect 并画文字 吧文字置于rect中间 这里画的是边角 一共八条线
rect = new Rect(rectLeft, rectTop - 80, rectRight, rectTop - 10);
wordPaint.setColor(Color.WHITE);
canvas.drawText(TIPS, rect.centerX(), baseline, wordPaint);
canvas.drawLine(rectLeft, rectTop, rectLeft + lineLen, rectTop,
linePaint);
canvas.drawLine(rectRight - lineLen, rectTop, rectRight, rectTop,
linePaint);
canvas.drawLine(rectLeft, rectTop, rectLeft, rectTop + lineLen,
linePaint);
canvas.drawLine(rectRight, rectTop, rectRight, rectTop + lineLen,
linePaint);
canvas.drawLine(rectLeft, rectBottom, rectLeft + lineLen, rectBottom,
linePaint);
canvas.drawLine(rectRight - lineLen, rectBottom, rectRight, rectBottom,
linePaint);
canvas.drawLine(rectLeft, rectBottom - lineLen, rectLeft, rectBottom,
linePaint);
canvas.drawLine(rectRight, rectBottom - lineLen, rectRight, rectBottom,
linePaint);
}
public int getRectLeft() {
return rectLeft;
}
public int getRectTop() {
return rectTop;
}
public int getRectRight() {
return rectRight;
}
public int getRectBottom() {
return rectBottom;
}
public int getViewWidth() {
return viewWidth;
}
public int getViewHeight() {
return viewHeight;
}
}
绘制原理图:
用法:
绘制出该View,将此View添加在你的布局中,布局根布局使用FramLayout,先放入你的相机view,再放入我们这个view即可。
效果展示: