写在前面的话:每一个实例的代码都会附上相应的代码片或者图片,保证代码完整展示在博客中。最重要的是保证例程的完整性!!!方便自己也方便他人~欢迎大家交流讨论~本文为博主原创文章,未经博主允许不得转载。

在相机预览时增加取景蒙板/浮层的思路是自定义View,用framelayout把自定义view放在surfaceview上面,在oncreat方法中计算坐标位置,调用自定义view中的set…方法设置坐标,根据坐标绘图。
接下来把上篇的自定义相机和增加蒙板那篇的代码结合起来,为相机增加取景蒙板/浮层,上代码!

  • 新建一个Android项目
  • values文件夹
    • strings.xml
  • layout文件夹
    • activity_first.xml
    • custom.xml
    • result.xml
  • manifests
    • AndroidManifest.xml
  • Java文件夹
    • FirstActivity
    • Customcamera
    • TranslucencyView
    • ResultActivity
  • 小结

新建一个Android项目

取名为Cameratwo,具体文件的命名如下

values文件夹

strings.xml

<resources><string name="app_name">Cameratwo</string><string name="button_name">开始拍照</string>
</resources>

layout文件夹

activity_first.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"tools:context=".FirstActivity"><Button
        android:id="@+id/button"android:layout_width="match_parent"android:layout_height="wrap_content"android:onClick="customCamera"android:text="@string/button_name" /><ImageView
        android:id="@+id/iv"android:layout_width="match_parent"android:layout_height="match_parent" /></LinearLayout>

custom.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"><FrameLayout
        android:layout_width="match_parent"android:layout_height="match_parent"android:layout_alignParentTop="true"><SurfaceView
            android:id="@+id/preview"android:layout_width="match_parent"android:layout_height="match_parent"android:visibility="visible" /><com.example.administrator.cameratwo.TranslucencyView
            android:id="@+id/transView"android:layout_width="match_parent"android:layout_height="match_parent" /></FrameLayout><ImageButton
        android:id="@+id/button3"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_alignParentBottom="true"android:layout_centerHorizontal="true"android:background="@drawable/button3"android:onClick="capture" />
</RelativeLayout>

result.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"android:layout_height="match_parent"><ImageView
        android:id="@+id/pic"android:layout_width="match_parent"android:layout_height="match_parent" /></LinearLayout>

manifests

AndroidManifest.xml

在该文件中增加以下两项

    <uses-permission android:name="android.permission.CAMERA"/><uses-feature android:name="android.hardware.Camera"/><uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<activity android:name=".Customcamera"/>
<activity android:name=".ResultActivity"/>

Java文件夹

FirstActivity

package com.example.administrator.cameratwo;import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.content.Intent;
import android.view.View;public class FirstActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_first);}public void  customCamera(View view){startActivity(new Intent(this,Customcamera.class));}
}

Customcamera

这里完全没有用到Butter Knife 框架,因为我用的不熟,就删掉了orz…

package com.example.administrator.cameratwo;import android.content.Intent;
import android.graphics.ImageFormat;
import android.graphics.PixelFormat;
import android.hardware.Camera;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.ImageButton;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;public class Customcamera extends AppCompatActivity implements SurfaceHolder.Callback{private Camera mCamera;private SurfaceView mPreview;private SurfaceHolder mHolder;private int cameraId=1;private int mHeight;private Camera.PictureCallback mpictureCallback=new Camera.PictureCallback(){@Overridepublic void onPictureTaken(byte[] data,Camera camera){File tempfile=new File("/sdcard/emp.png");try{ FileOutputStream fos =new FileOutputStream(tempfile);fos.write(data);fos.close();Intent intent=new Intent(Customcamera.this,ResultActivity.class);intent.putExtra("picpath",tempfile.getAbsolutePath());startActivity(intent);Customcamera.this.finish();}catch (IOException e){e.printStackTrace();}}};@Overrideprotected void onCreate( Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.custom);mPreview=findViewById(R.id.preview);mPreview.setZOrderOnTop(false);mHolder=mPreview.getHolder();mHolder.setFormat(PixelFormat.TRANSPARENT);mHolder.addCallback(this);mPreview.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {mCamera.autoFocus(null);}});//获取imgButton的坐标,以便蒙板在imgButton处掏空,并获取页面参数ImageButton imgButton=findViewById(R.id.button3);TranslucencyView translucencyView=findViewById(R.id.transView);imgButton.postDelayed(new Runnable() {@Overridepublic void run() {runOnUiThread(new Runnable() {@Overridepublic void run() {ImageButton imgButton=findViewById(R.id.button3);mHeight = getSupportActionBar().getHeight();int left = imgButton.getLeft();int right = imgButton.getRight();int top = imgButton.getTop();int bottom = imgButton.getBottom();int mCoodinate[] = {left, top, right, bottom};TranslucencyView translucencyView=findViewById(R.id.transView);translucencyView.setCircleLocation(mCoodinate);}});}},1200);FrameLayout.LayoutParams layoutParams=(FrameLayout.LayoutParams) translucencyView.getLayoutParams();translucencyView.setLayoutParams(layoutParams);translucencyView.setOnTouchListener(new View.OnTouchListener() {@Overridepublic boolean onTouch(View v, MotionEvent event) {mCamera.autoFocus(null);return false;}});mHolder.lockCanvas();}public void capture(View view){Camera.Parameters parameters=mCamera.getParameters();parameters.setPictureFormat(ImageFormat.JPEG);parameters.setPreviewSize(800,400);parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);mCamera.autoFocus(new Camera.AutoFocusCallback(){@Overridepublic void onAutoFocus(boolean success, Camera camera) {if(success){mCamera.takePicture(null,null, mpictureCallback);}}});}@Overrideprotected void onResume() {super.onResume();if (mCamera==null){mCamera=getCamera();if(mHolder!=null){setStartPreview(mCamera,mHolder);}}}@Overrideprotected void onPause() {super.onPause();releaseCamera(); }private Camera getCamera(){Camera camera;try{camera=Camera.open(cameraId);}catch (Exception e){camera=null;e.printStackTrace(); }return camera;}private void setStartPreview(Camera camera,SurfaceHolder holder){try{camera.setPreviewDisplay(holder);camera.setDisplayOrientation(90);camera.startPreview();}catch (Exception e){e.printStackTrace(); }}private void releaseCamera(){if(mCamera!=null){mCamera.stopPreview();mCamera.setPreviewCallback(null);mCamera.release();mCamera=null;}}@Overridepublic void surfaceCreated(SurfaceHolder holder) {setStartPreview(mCamera,mHolder);}@Overridepublic void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {mCamera.stopPreview();setStartPreview(mCamera,mHolder);}@Overridepublic void surfaceDestroyed(SurfaceHolder holder) {releaseCamera();}@Overridepublic void onWindowFocusChanged(boolean hasFocus) {super.onWindowFocusChanged(hasFocus); }}

TranslucencyView

package com.example.administrator.cameratwo;import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.DashPathEffect;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PathEffect;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.widget.ImageView;public class TranslucencyView extends  ImageView{private  final Context mContext;private int[] mCircleLocation;//声明存放坐标的数组public TranslucencyView(Context context){this(context,null);}public TranslucencyView(Context context, AttributeSet attributeSet){this(context,attributeSet,0);}public TranslucencyView(Context context,AttributeSet attributeSet,int defStyleAttr){super(context,attributeSet,defStyleAttr);this.mContext=context;initView();}private void initView(){setBackgroundColor(Color.parseColor("#7f000000"));}//设置半透明底色public void setCircleLocation(int[] location){this.mCircleLocation=location;invalidate();}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);if(mCircleLocation!=null){//掏空一个圆形Paint paintarc=new Paint(Paint.ANTI_ALIAS_FLAG);//创建一个画笔实例PorterDuffXfermode porterDuffXfermode=new PorterDuffXfermode(PorterDuff.Mode.CLEAR);paintarc.setXfermode(porterDuffXfermode);paintarc.setAntiAlias(true);RectF rectF=new RectF(mCircleLocation[0],mCircleLocation[1],mCircleLocation[2],mCircleLocation[3]);canvas.drawArc(rectF,0,360,true,paintarc);//画虚线Paint paintdashed=new Paint(Paint.ANTI_ALIAS_FLAG);paintdashed.setStyle(Paint.Style.STROKE);paintdashed.setColor(Color.WHITE);paintdashed.setStrokeWidth(5);PathEffect pathEffect=new DashPathEffect(new float[]{10,10},0);paintdashed.setPathEffect(pathEffect);canvas.drawArc(rectF,0,360,true,paintdashed);//画矩形框/** Paint paintrect=new Paint(Paint.ANTI_ALIAS_FLAG);PorterDuffXfermode porterDuffXfermode1=new PorterDuffXfermode(PorterDuff.Mode.CLEAR);paintrect.setXfermode(porterDuffXfermode1);paintrect.setAntiAlias(true);//paintrect.setStrokeWidth(5);canvas.drawRect(200, 400, 900, 1300, paintrect);*///画椭圆Paint paintoval=new Paint(Paint.ANTI_ALIAS_FLAG);PorterDuffXfermode porterDuffXfermode2=new PorterDuffXfermode(PorterDuff.Mode.CLEAR);paintoval.setXfermode(porterDuffXfermode2);paintoval.setAntiAlias(true);//paintoval.setStrokeWidth(10);canvas.drawOval(100,200,1000,1200,paintoval);}}
}         

这里画了个椭圆,注意用的都是绝对坐标,我估计在不同的手机中可能会出现适配问题,不过还没想好相对的怎么画啦

ResultActivity

这个的代码和之前的3.3ResultActivity.java代码一模一样,大家直接看
Android Studio:使用Camera拍照(二)自定义相机 - CSDN博客 https://blog.csdn.net/Leo_Huang720/article/details/81289309#33resultactivityjava就可以了

小结

上完了代码,我要小结一下给相机加取景蒙版和之前一篇的直接添加(文章后面有附上)有什么差别,我最开始的时候确实是很简单的两处代码合在一起,然后执行时发现两个问题:
1.整个显示出来的是深蓝色的
2.在蒙版还没稳定出现前,surfaceview尚在预览,蒙板稳定出现后,surfaceview瞬间卡在了那时的页面
解决问题1:我又回去看了自定义相机的执行(那个项目叫startcamera),发现surfaceview从开始到预览确实有个从暗变深蓝再变浅的过程,于是我猜是 showMask() 方法(这个方法中的内容后来被单独拿出来放到了onCreate中)中设置的时间太短,该时间用于测量view是够了(因为蒙板能顺利显示,如果时间不够,整个页面其实会闪退),那就是通过intent传给TranslucencyActivity.java的时间太短,surfaceview还没构造完,intent就把坐标信息给TranslucencyActivity了,于是我把时间从500ms改到1200ms
解决问题2:其实从解决问题1的最后几句话已经能看出问题2的端倪了,就是原本的showMask() 最后有几句代码:

Intent intent = new Intent(SecondActivity.this, TranslucencyActivity.class);
intent.putExtra("Location", mCoodinate);
startActivity(intent);

这就意味着信使不仅将坐标传给TranslucencyActivity,还打开了TranslucencyActivity!!那这个界面就把surfaceview定住了,因为TranslucencyActivity没有任何写预览的方法,它只是把自定义的view和自己的页面绑在一起,所以要弄取景框蒙板没有TranslucencyActivity任何事情,我就把它删掉了,其他所做的更改上面代码已详细给出。

执行效果:

附: Android Studio:增加蒙板/浮层特效 - CSDN博客 https://blog.csdn.net/Leo_Huang720/article/details/81542015#secondactivityjava
Android Studio:使用Camera拍照(二)自定义相机 - CSDN博客https://blog.csdn.net/Leo_Huang720/article/details/81289309#33resultactivityjava

Android Studio:使用Camera拍照(三)为相机增加取景蒙板/浮层相关推荐

  1. Android Studio 插件开发详解三:翻译插件实战

    转载请标明出处:http://blog.csdn.net/zhaoyanjun6/article/details/78113868 本文出自[赵彦军的博客] 系列目录 Android Gradle使用 ...

  2. 查找android studio版本号,Android studio版本号查看的三种方法

    Android studio版本号查看的三种方法 发布于 2016-04-10 22:50:17 | 688 次阅读 | 评论: 0 | 来源: 网友投递 Android Studio Android ...

  3. Android开发技巧——Camera拍照功能

    本篇是我对开发项目的拍照功能过程中,对Camera拍照使用的总结.由于camera2是在api level 21(5.0.1)才引入的,而Camera到6.0仍可使用,所以暂未考虑camera2. 文 ...

  4. 5、Android Studio+JNI+Opencv4.5 调用系统相机,实现图像滤波

    基本思想:使用Android Studio+Opencv4.5 实现滤波,并打包成apk,纯属学习~ 该工程git: https://github.com/sxj731533730/AndroidIn ...

  5. Android 骁龙Camera拍照流程梳理

    本文以SnapdragonCamera为例,分析骁龙Camera的拍照流程,其实现与camera2大致相同. 首先将SnapdragonCamera源码倒入android studio, 具体操作,可 ...

  6. Android Studio OpenGL ES绘制三棱锥/四面体的多纹理贴图 每个面使用一张图片渲染

    本文参考了王刚的<疯狂Android讲义(第3版)>P554-P559 要求:利用OpenGL ES绘制一个三棱锥,并对每个面进行纹理贴图,每个面使用不同的图片进行渲染. 环境:Andro ...

  7. android studio操作手机相机,Android Studio 调用Camera实现拍照功能

    首先创建一个SurfaceHolder实现对SurfaceView的回调,然后重写SurfaceCreate函数,实现对Camera的初始化等一系列工作:代码如下: @Override public ...

  8. android模拟器拍照图,android模拟器无法使用camera拍照

    遇到的问题: 1 在模拟器里,无法启动camera: 2 成功启动camera之后,真正拍照的时候,提示"your sdcard is full",我明明有一个100M的sdcar ...

  9. Android的模拟器能不能照相,android模拟器无法使用camera拍照

    遇到的问题: 1 在模拟器里,无法启动camera: 2 成功启动camera之后,真正拍照的时候,提示"your sdcard is full",我明明有一个100M的sdcar ...

最新文章

  1. python基础语法第10关作业-Python基础作业一
  2. Portlet开发指南第二章
  3. tomcat屏蔽ip
  4. SAP屠夫---折旧在13-16调整期间的烦恼
  5. php ob_flush 和flush
  6. 使用混合云的SQL Server
  7. MVC路由中routes.IgnoreRoute({resource}.axd/{*pathInfo}) 到底什么意思!
  8. 【计算机组成原理】Chapter1-复习题
  9. 诗与远方:无题(二十九)
  10. hdu 6351 Beautiful Now
  11. 计算机绘图实训任务书,autocad模块化实训任务书-2011.11
  12. 反激式开关电源设计资料
  13. 在Android Studio 中使用Assets资源文件
  14. cmos逻辑门传输延迟时间_【转载】CMOS与TTL电路的区别
  15. 思维导图 基础篇(07)擎绘系统-阅读导图
  16. 标注与注记的区别和联系
  17. DBA常用Sql语句--留着给自己看
  18. 【ctype.h isdigit】
  19. 如何获取iPhone 各机型以及系统的状态栏高度进行适配
  20. 如何将EXCEL表格的内容导入到CDR中?

热门文章

  1. aws ec2开启bbr加速
  2. ​LeetCode刷题实战355:设计推特
  3. springboot个人理财系统
  4. Kafka 配置指南
  5. SAS学习之自定义输入和输出格式
  6. 男女有别:行为抑制系统和腹内侧前额叶皮层连接的性别差异
  7. c语言char数组和short数组的区别,详解C语言中Char型指针数组与字符数组的区别
  8. Android 7.0+配置Burpsuite证书
  9. 一个让她泪流满面的礼物
  10. js 获取n位随机数