android自定义相机添加蒙板,拍照剪切

来源:互联网 发布:徐州工程学院报修软件 编辑:程序博客网 时间:2024/05/18 01:47

前几天,我写了一篇自定义相机加取景框的文章,这几天,我又研究了一下,进一步写了蒙板,并且拍照出来剪切只留取景框的照片。

加上对之前代码的调整。现在又记录下来

现在的效果是这样的

布局文件

<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:app="http://schemas.android.com/apk/res-auto"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical">    <FrameLayout        android:id="@+id/myFramelayout"        android:layout_width="match_parent"        android:layout_height="match_parent"        android:orientation="vertical">        <SurfaceView            android:id="@+id/surfaceView"            android:layout_width="match_parent"            android:layout_height="match_parent" />        <LinearLayout            android:layout_width="match_parent"            android:layout_height="match_parent"            android:orientation="vertical">            <TextView                android:id="@+id/view1"                android:layout_width="match_parent"                android:layout_height="wrap_content"                android:background="#FFFFFF"                android:gravity="center_horizontal"                android:text="\n请将方框对准证件拍摄"                android:textSize="18dp"                android:textColor="@color/colorAccent"                android:alpha="0.6"/>            <LinearLayout                android:layout_width="match_parent"                android:layout_height="wrap_content"                android:orientation="horizontal">                <View                    android:id="@+id/view2"                    android:layout_width="wrap_content"                    android:layout_height="wrap_content"                    android:background="#FFFFFF"                    android:alpha="0.6"/>                <com.example.administrator.myapplication.MyView                    android:id="@+id/myView"                    android:layout_width="wrap_content"                    android:layout_height="wrap_content"                    android:layout_gravity="center" />                <View                    android:id="@+id/view3"                    android:layout_width="wrap_content"                    android:layout_height="wrap_content"                    android:background="#FFFFFF"                    android:alpha="0.6"/>            </LinearLayout>            <View                android:id="@+id/view4"                android:layout_width="match_parent"                android:layout_height="wrap_content"                android:background="#FFFFFF"                android:alpha="0.6"/>        </LinearLayout>    </FrameLayout>    <LinearLayout        android:id="@+id/linear"        android:layout_width="55dp"        android:layout_height="match_parent"        android:layout_alignParentRight="true"        android:layout_marginRight="8dp"        android:gravity="center_vertical">        <Button            android:id="@+id/takepicture_button"            android:layout_width="50dp"            android:layout_height="50dp"            android:background="@mipmap/xiang_ji"            android:onClick="takepicture" />    </LinearLayout></RelativeLayout>
自定义MyView,这次MyView对于算取景框的线是灵活的,更改参数可以调整取景框的大小,并且取景框线也跟着移动

public class MyView extends View {        //获取屏幕的宽和高。根据屏幕的宽和高来算取景框的位置    private int screenWidth, screenHeight, myViewPaddingLeft, myViewPaddingTop;        private int  langLine = 100, //取景框长线的长度              shortLine = 50, //取景框线的长度              origin = 0;//原点    public MyView(Context context, AttributeSet attrs) {        super(context, attrs);    }    public void setMyParams(int screenWidth, int screenHeight, int myViewPaddingLeft, int myViewPaddingTop) {        this.screenWidth = screenWidth;        this.screenHeight = screenHeight;        this.myViewPaddingLeft = myViewPaddingLeft;        this.myViewPaddingTop = myViewPaddingTop;    }    @Override    public void onDraw(Canvas canvas) {        Paint paint = new Paint();        paint.setColor(Color.RED);        paint.setAlpha(250);        paint.setAntiAlias(true);        paint.setStyle(Paint.Style.STROKE);        paint.setStrokeWidth(5);        // 下面是取景框的8条线    // xy的算法是:把屏幕横着(逆时针旋转90度的屏幕),相对这个view来讲(左上角是原点0,0),从左到右是x轴,从上到下是y        //左上角两条线    canvas.drawLine(origin, origin, langLine, origin, paint);        canvas.drawLine(origin, origin, origin, shortLine, paint);        //左下角两条线    canvas.drawLine(origin, screenHeight - myViewPaddingTop, langLine, screenHeight - myViewPaddingTop, paint);        canvas.drawLine(origin, screenHeight - myViewPaddingTop, origin, screenHeight - myViewPaddingTop - shortLine, paint);        //右上角两条线    canvas.drawLine(screenWidth - myViewPaddingLeft, origin, screenWidth - myViewPaddingLeft - langLine, origin, paint);        canvas.drawLine(screenWidth - myViewPaddingLeft, origin, screenWidth - myViewPaddingLeft, shortLine, paint);        //右下角两条线    canvas.drawLine(screenWidth - myViewPaddingLeft, screenHeight - myViewPaddingTop, screenWidth - myViewPaddingLeft - langLine, screenHeight - myViewPaddingTop, paint);        canvas.drawLine(screenWidth - myViewPaddingLeft, screenHeight - myViewPaddingTop, screenWidth - myViewPaddingLeft, screenHeight - myViewPaddingTop - shortLine, paint);        super.onDraw(canvas);    }}
最后是Acvitity代码

    private MyView myView;    private View view2, view3, view4;//3个蒙板  private TextView view1;//1个蒙板
    private Camera camera;
private Button takepicture_button; private SurfaceView surfaceview; private int screenWidth, screenHeight; private int myViewPaddingLeft = 500, //MyView左右距离屏幕的距离(意思是MyView左右两边一共空了500 myViewPaddingTop = 300;//MyView上下距离屏幕的距离(意思是MyView上下两边一共空了500
    private ToneGenerator tone;
  private Camera.AutoFocusCallback myAutoFocusCallback = new Camera.AutoFocusCallback() { @Override public void onAutoFocus(boolean success, Camera camera) { Log.w("print", "聚焦完成,,,,"); //聚焦后发出提示音 tone = new ToneGenerator(AudioManager.STREAM_MUSIC,ToneGenerator.MAX_VOLUME); tone.startTone(ToneGenerator.TONE_PROP_BEEP2); } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);//把屏幕设置成横屏 setContentView(R.layout.test_layout); WindowManager wm = (WindowManager) this.getSystemService(Context.WINDOW_SERVICE); screenWidth = wm.getDefaultDisplay().getWidth(); screenHeight = wm.getDefaultDisplay().getHeight(); view1 = (TextView) findViewById(R.id.view1); LinearLayout.LayoutParams layoutParams1 = (LinearLayout.LayoutParams) view1.getLayoutParams(); layoutParams1.height = myViewPaddingTop / 2; view1.setLayoutParams(layoutParams1); myView = (MyView) findViewById(R.id.myView); myView.setMyParams(screenWidth, screenHeight, myViewPaddingLeft, myViewPaddingTop); LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) myView.getLayoutParams(); layoutParams.width = screenWidth - myViewPaddingLeft; layoutParams.height = screenHeight - myViewPaddingTop; myView.setLayoutParams(layoutParams); view2 = findViewById(R.id.view2); LinearLayout.LayoutParams layoutParams2 = (LinearLayout.LayoutParams) view2.getLayoutParams(); layoutParams2.width = myViewPaddingLeft / 2; layoutParams2.height = screenHeight - myViewPaddingTop; view2.setLayoutParams(layoutParams2); view3 = findViewById(R.id.view3); LinearLayout.LayoutParams layoutParams3 = (LinearLayout.LayoutParams) view3.getLayoutParams(); layoutParams3.width = myViewPaddingLeft / 2; layoutParams3.height = screenHeight - myViewPaddingTop; view3.setLayoutParams(layoutParams3); view4 = findViewById(R.id.view4); LinearLayout.LayoutParams layoutParams4 = (LinearLayout.LayoutParams) view4.getLayoutParams(); layoutParams4.height = myViewPaddingTop / 2; view4.setLayoutParams(layoutParams4); surfaceview = (SurfaceView) findViewById(R.id.surfaceView); myView.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { camera.autoFocus(myAutoFocusCallback); return false; } }); getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); SurfaceHolder holder = surfaceview.getHolder(); holder.setKeepScreenOn(true);// 屏幕常亮 holder.setType(SurfaceHolder.SURFACE_TYPE_NORMAL); holder.addCallback(new MySurfaceCallback()); holder.lockCanvas(); } private final class MySurfaceCallback implements Callback { @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { //surface的格式或大小发生改变,这个方法就被调用 } @Override public void surfaceCreated(SurfaceHolder holder) { try { camera = Camera.open(); Camera.Parameters params = camera.getParameters(); camera.setPreviewDisplay(surfaceview.getHolder()); // 开启预览 camera.startPreview(); } catch (IOException e) { e.printStackTrace(); } } @Override public void surfaceDestroyed(SurfaceHolder holder) { if (camera != null) { camera.release(); camera = null; } } } public void takepicture(View v) { camera.takePicture(mShutterCallback, null,mPictureCallback); }
    Camera.ShutterCallback mShutterCallback = new Camera.ShutterCallback(){
public void onShutter() { } }; private Camera.PictureCallback mPictureCallback = new Camera.PictureCallback() { @Override public void onPictureTaken(byte[] data, Camera camera) { Bitmap mBitmap = BitmapFactory.decodeByteArray(data, 0, data.length); Bitmap mBitmapCut = ImageCrop(mBitmap); String rootPath = Environment.getExternalStorageDirectory().toString() + File.separator; File file = new File(rootPath + System.currentTimeMillis() + ".jpg"); try { file.createNewFile(); BufferedOutputStream os = new BufferedOutputStream(new FileOutputStream(file)); mBitmapCut.compress(Bitmap.CompressFormat.JPEG, 100, os);//100 是压缩率,100表示不压缩 os.flush(); os.close(); Toast.makeText(getApplicationContext(), "保存成功", Toast.LENGTH_SHORT).show(); } catch (IOException e) { e.printStackTrace(); } } }; /** * 按图片比例裁切图片 */ public Bitmap ImageCrop(Bitmap bitmap) { int w = bitmap.getWidth(); // 得到图片的宽,高 int h = bitmap.getHeight(); //剪切的初始xy位置,原点位置 都是根据比例来算的 int x = (int) ((w * (myViewPaddingLeft / 2)) / screenWidth); int y = (int) (h * (myViewPaddingTop / 2) / screenHeight); //剪切的宽和高 int retX = (int) ((w * (screenWidth - myViewPaddingLeft)) / screenWidth); int retY = (int) (h * (screenHeight - myViewPaddingTop) / screenHeight); //必须x+retX要小于或等于bitmap.getWidth()y+retY要小于或等于bitmap.getHeight(),不然会报错 return Bitmap.createBitmap(bitmap, x, y, retX, retY, null, false); }
最后放上一张保存下来,剪切后的照片,看看效果

如有不妥之处,请大家指正!!

0 0
原创粉丝点击