zoukankan      html  css  js  c++  java
  • 仿扫一扫实现拍摄框内的照片

    就是仿照现在扫一扫的形式,周围是半透明的遮挡,然后中间是全透明的,拍摄后只截取框内的内容

    查了很多博客,实现起来真的太复杂了,本人比较怕麻烦所以在很多地方偷懒了

    先上效果图:

    第一步:设置照相机预览以及拍照

    这是所有步骤的前提,没有预览,用户怎么知道自己拍的什么呢。预览用的是SurfaceView

    http://www.cnblogs.com/androidez/archive/2013/02/04/2892439.html

    这篇博文写得已经十分详细了,打开照相机,然后拍照,而且十分简洁!不想别的博客一下就几百行代码不知所云。这篇代码可以复制下去当相机模版使用。

    这里遇到一个问题,就是预览的效果是左转90度的,拍出来也是左转90度的,查了很多资料,大家统一的做法就是。在相机预览那里设置右旋90度,拍下的照片再右旋90度,具体的做法我会贴代码

    第二步:设置半透明边框

    很多博客的做法是绘图呀什么的,太过负责。

    其实如果考虑简单点的话,只要在surfaceView上面叠加一层图片就好了,用Framelayout布局

    就是背景半透明,中间扣掉

    第三步:怎么只拍摄框内的图片

    这个问题,很多博客都是长篇大论,什么矩阵运算都用上了,虽然很强,但是不想看下去。

    拍摄框内的图片,就直接拍完整张照片之后,在照片里面抠图就好了啊。

    Bitmap.createBitmap(bitmap,50,250,650,500);
    

    自己算一下透明框大概在什么位置,左上角的坐标是什么,宽和高是什么。用上述函数就可以在原照片抠图了。

    第四步:完善一点,加入点击对焦

    其实就是在点击事件里面调用对焦函数就行

    总的代码:

    public class MainActivity extends AppCompatActivity {
    
    
            private SurfaceView surfaceview;
            private Camera camera;
            private Button take;
    
            @Override
            protected void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                requestWindowFeature(Window.FEATURE_NO_TITLE); // 没有标题  必须在设置布局之前找到调用
                setContentView(R.layout.activity_main);
    
                /*
                getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, // 设置全屏显示
                        WindowManager.LayoutParams.FLAG_FULLSCREEN);
                */
    
                take = (Button)findViewById(R.id.take);
    
                surfaceview = (SurfaceView) findViewById(R.id.surfaceview);
                SurfaceHolder holder = surfaceview.getHolder();
                holder.setFixedSize(176, 155);// 设置分辨率
                holder.setKeepScreenOn(true);
                holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
    
                // SurfaceView只有当activity显示到了前台,该控件才会被创建     因此需要监听surfaceview的创建
                holder.addCallback(new MySurfaceCallback());
    
                //拍照按钮
                take.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View view) {
    
                        takepicture();
    
                    }
                });
    
    
            }
    
    
        //点击事件
        @Override
        public boolean onTouchEvent(MotionEvent event) {
    
            //对焦
            camera.autoFocus(new Camera.AutoFocusCallback() {
                @Override
                public void onAutoFocus(boolean b, Camera camera) {
                    camera.cancelAutoFocus();
                }
            });
    
            return super.onTouchEvent(event);
        }
    
        /**
             * 监听surfaceview的创建
             * @author Administrator
             *    Surfaceview只有当activity显示到前台,该空间才会被创建
             */
            private final class MySurfaceCallback implements SurfaceHolder.Callback {
    
                @Override
                public void surfaceChanged(SurfaceHolder holder, int format, int width,
                                           int height) {
                    // TODO Auto-generated method stub
    
                }
    
    
    
                @Override
                public void surfaceCreated(SurfaceHolder holder) {
                    // TODO Auto-generated method stub
    
                    try {
                        // 当surfaceview创建就去打开相机
                        camera = Camera.open();
                        Camera.Parameters params = camera.getParameters();
                       // Log.i("i", params.flatten());
                        params.setJpegQuality(80);  // 设置照片的质量
                        params.setPictureSize(1024, 768);
                        params.setPreviewFrameRate(5);  // 预览帧率
                        camera.setParameters(params); // 将参数设置给相机
                        //右旋90度,将预览调正
                        camera.setDisplayOrientation(90);
                        // 设置预览显示
                        camera.setPreviewDisplay(surfaceview.getHolder());
                        // 开启预览
                        camera.startPreview();
    
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
    
                }
    
                @Override
                public void surfaceDestroyed(SurfaceHolder holder) {
                    // TODO Auto-generated method stub
                    if(camera != null){
                        camera.release();
                        camera = null;
                    }
                }
    
            }
    
    
    
          //拍照的函数
            public void takepicture(){
            /*
             * shutter:快门被按下
             * raw:相机所捕获的原始数据
             * jpeg:相机处理的数据
             */
                camera.takePicture(null, null, new MyPictureCallback());
            }
    
            //byte转Bitmap
            public Bitmap Bytes2Bimap(byte[] b) {
            if (b.length != 0) {
                return BitmapFactory.decodeByteArray(b, 0, b.length);
            } else {
                return null;
            }
             }
    
            //bitmap转byte
            public byte[] Bitmap2Bytes(Bitmap bm) {
                    ByteArrayOutputStream baos = new ByteArrayOutputStream();
                    bm.compress(Bitmap.CompressFormat.PNG, 100, baos);
                    return baos.toByteArray();
            }
    
        //照片回调函数,其实是处理照片的
            private final class MyPictureCallback implements Camera.PictureCallback {
    
                @Override
                public void onPictureTaken(byte[] data, Camera camera) {
                    // TODO Auto-generated method stub
                    try {
    
                        Bitmap bitmap = Bytes2Bimap(data);
                        Matrix m = new Matrix(); int width = bitmap.getWidth(); int height = bitmap.getHeight(); m.setRotate(90);
                        //将照片右旋90度
                        bitmap = Bitmap.createBitmap(bitmap, 0, 0, width, height, m,
                                true);
    
                        Log.d("TAG","width "+width);
                        Log.d("TAG","height "+height);
    
                        //截取透明框内照片
                        bitmap = Bitmap.createBitmap(bitmap,50,250,650,500);
    
                        data = Bitmap2Bytes(bitmap);
                        File file = new File(Environment.getExternalStorageDirectory(),System.currentTimeMillis()+".jpg");
                        FileOutputStream fos = new FileOutputStream(file);
                        fos.write(data);
                        // 在拍照的时候相机是被占用的,拍照之后需要重新预览
                        camera.startPreview();
                    } catch (Exception e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
    
                }
    
            }
    
    }
    

      

    写很复杂的代码的确很强,但我觉得要是能用简单的方法实现差不多的功能也很不错

  • 相关阅读:
    php练习4——排序,查找
    php练习3——猜拳游戏,评委打分问题
    php练习2——乘法表,变量的使用
    php练习1——计算器
    php函数的初步使用
    php练习——打印半金字塔、金字塔、空心金字塔、菱形、空心菱形
    Discuz论坛下载与安装
    phpMyAdmin下载与安装
    mysql5.7下载与安装,php5.6与mysql5.7整合
    php5下载,apache2.4与php5整合
  • 原文地址:https://www.cnblogs.com/wzben/p/5888035.html
Copyright © 2011-2022 走看看