文档章节

Android 不用预览拍照与图片缩放剪裁

ForingY
 ForingY
发布于 2016/08/01 14:09
字数 804
阅读 109
收藏 0

码上生花,ECharts 作品展示赛正式启动!>>>

public void onTakePhotoClicked(View view) {
        final SurfaceView preview = new SurfaceView(this);
        SurfaceHolder holder = preview.getHolder();
        // deprecated setting, but required on Android versions prior to 3.0
        holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

        holder.addCallback(new SurfaceHolder.Callback() {
            @Override
            //The preview must happen at or after this point or takePicture fails
            public void surfaceCreated(SurfaceHolder holder) {
                Log.d(TAG, "Surface created");
                Camera camera = null;
                try {
                    camera = Camera.open(Camera.CameraInfo.CAMERA_FACING_BACK);
                    Log.d(TAG, "Opened camera");

                    try {
                        camera.setPreviewDisplay(holder);
                    } catch (IOException e) {
                        throw new RuntimeException(e);
                    }

                    camera.startPreview();
                    Log.d(TAG, "Started preview");
                    camera.takePicture(null, null, pictureCallback);
                } catch (Exception e) {
                    if (camera != null)
                        camera.release();
                    throw new RuntimeException(e);
                }
            }

            @Override
            public void surfaceDestroyed(SurfaceHolder holder) {}
            @Override
            public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {}
        });

        WindowManager wm = (WindowManager)getSystemService(Context.WINDOW_SERVICE);
        WindowManager.LayoutParams params = new WindowManager.LayoutParams(
                1, 1, //Must be at least 1x1
                WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY,
                0,
                //Don't know if this is a safe default
                PixelFormat.UNKNOWN);

        //Don't set the preview visibility to GONE or INVISIBLE
        wm.addView(preview, params);
    }

图片缩放与裁剪

现在几乎就可以了,pictureCallback是拍照成功后的回调,我们将在此回调中做一些对图片数据的处理工作。 首先,图片数据以字节数组的形式返回的,原型如下:

 @Override
 public void onPictureTaken(byte[] data, Camera camera) {}

我们要将数组转换成bitmap,用BitmapFactory.decodeByteArray方法即可。 但你会发现,图片是向左倒着显示的,不要急,我们要把它正过来。此时我们要用matrix.postRotate方法配上Bitmap.createBitmap创建新的bitmap。 谈谈缩放吧,参考Bitmap.createScaledBitmap方法即可。 那么裁剪呢?新建一个Rect,注意它要在整个bitmap中,比如程序中我将进行距离原图1/4处裁剪。 这还没完,做完这些工作,我会将这三个bitmap存成三张图片。注意在做bitmap的compress操作时,第二个参数quality很重要,图片的质量越高,占用的空间越大。 好了,下面是代码,请参考:

private Camera.PictureCallback pictureCallback = new Camera.PictureCallback() {
        @Override
        public void onPictureTaken(byte[] data, Camera camera) {
            Log.d(TAG, "onPictureTaken");
            if(null == data){
                return;
            }
            Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
            camera.stopPreview();
            Matrix matrix = new Matrix();
            matrix.postRotate((float) 90.0);
            bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(),
                    bitmap.getHeight(), matrix, false);
            Log.d(TAG, "original bitmap width: " + bitmap.getWidth() +
                    " height: " + bitmap.getHeight());
            Bitmap sizeBitmap = Bitmap.createScaledBitmap(bitmap,
                    bitmap.getWidth()/3, bitmap.getHeight()/3, true);
            Log.d(TAG,"size bitmap width "+sizeBitmap.getWidth()+" height "+sizeBitmap.getHeight());

            //裁剪bitmap
            int leftOffset = (int)(sizeBitmap.getWidth() * 0.25);
            int topOffset = (int)(sizeBitmap.getHeight() * 0.25);
            Rect rect = new Rect(leftOffset, topOffset, sizeBitmap.getWidth() - leftOffset,
                    sizeBitmap.getHeight() - topOffset);
            Bitmap rectBitmap = Bitmap.createBitmap(sizeBitmap,
                    rect.left, rect.top, rect.width(), rect.height());
            try {
                FileOutputStream outputStream = new FileOutputStream(Environment
                        .getExternalStorageDirectory().toString()+"/photoResize.jpg");
                sizeBitmap.compress(Bitmap.CompressFormat.JPEG, 30, outputStream);
                outputStream.close();
                FileOutputStream outputStreamOriginal = new FileOutputStream(Environment
                        .getExternalStorageDirectory().toString()+"/photoOriginal.jpg");
                bitmap.compress(Bitmap.CompressFormat.JPEG, 20, outputStreamOriginal);
                outputStreamOriginal.close();

                FileOutputStream outputStreamCut = new FileOutputStream(Environment
                        .getExternalStorageDirectory().toString()+"/photoCut.jpg");
                rectBitmap.compress(Bitmap.CompressFormat.JPEG, 100, outputStreamCut);
                outputStreamCut.close();
                Log.d(TAG,"picture saved!");
            } catch(Exception e) {
                e.printStackTrace();
            }
        }
    };

你需要的权限:

 <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.CAMERA" />

    <uses-feature android:name="android.hardware.camera" />
    <uses-feature android:name="android.hardware.camera.autofocus" />

本文转载自:http://stackoverflow.com/questions/2386025/taking-picture-from-camera-without-preview

ForingY
粉丝 23
博文 272
码字总数 156129
作品 0
杭州
程序员
私信 提问
加载中
请先登录后再评论。
如何实现RTMP推送Android Camera2数据

Camera2简介 在Google 推出Android 5.0的时候, Android Camera API 版本升级到了API2(android.hardware.camera2), 之前使用的API1(android.hardware.camera)就被标为 Deprecated 了。 Camera......

daniulive
04/05
0
0
Android 音视频开发入门指南(2)

GLSurfaceView是OpenGL中的一个类,也是可以预览Camera的,而且在预览Camera上有其独到之处。独到之处在哪?当使用Surfaceview无能为力、痛不欲生时就只有使用GLSurfaceView了,它能够真正做...

shareus
2018/04/23
0
0
调用系统相机、相册、剪裁图片并上传(常用于上传头像,兼容Android7.0)

由于在Android 7.0 采用了StrictMode API政策禁,其中有一条限制就是对目录访问的限制。 这项变更意味着我们无法通过File API访问手机存储上的数据,也就是说,给其他应用传递 file:// URI ...

osc_d5exiys5
2018/07/14
35
0
android多图选择器 图片/视频 单选or多选,以及视频录制。

PictureSelector 最近项目中用到多图选择上传的需求,考虑到android机型众多问题就自己花时间写了一个,测试了大概60款机型,出现过一些问题也都一一修复了,基本上稳定了特分享出来,界面U...

osc_k0q149k0
2019/05/08
12
0
Android调用系统摄像头拍照并剪裁压缩

由于业务需要写了一个Android手机拍照的功能Demo,同时实现了图片剪裁和图片压缩。以下是源码 package com.klp.demo_025; import java.io.ByteArrayInputStream;import java.io.ByteArrayOu...

学习的小猪
2018/06/26
0
0

没有更多内容

加载失败,请刷新页面

加载更多

聊聊puma的ChangedEvent

序 本文主要研究一下puma的ChangedEvent Event puma/core/src/main/java/com/dianping/puma/core/event/Event.java public abstract class Event implements Serializable {private stat......

go4it
24分钟前
9
0
为什么Kubernetes和容器与机器学习密不可分?

当前,数字化转型的热潮在IT领域发展的如火如荼,越来越多的企业投身其中,机器学习和人工智能等现代技术的融合在公司组织内部也逐渐流行起来。 随着那些构成企业复杂IT基础架构的技术日益成...

京东智联云开发者
25分钟前
5
0
协程swoole对比golang

协程概念 协程(Coroutines)是一种比线程更加轻量级的存在,正如一个进程可以拥有多个线程一样,一个线程可以拥有多个协程。 协程具有以下几个特点 用户态执行,完全由程序所控制,不是被操...

冻结not
42分钟前
5
0
如何在macOS或OS X上安装pip? - How do I install pip on macOS or OS X?

问题: This post is a Community Wiki . 这篇文章是社区维基 。 Edit existing answers to improve this post. 编辑现有答案以改善此职位。 It is not currently accepting new answers. 它......

fyin1314
58分钟前
11
0
net.sf.JSONException Map中value字段为null,服务响应500

6月2号凌晨系统生产发布,2号白天仓库作业时有仓库拣选单打印面单接口500,不是所有的拣选单掉接口都是500, 当时通过接口响应正产和响应500,逻辑梳理以及数据对比,最后发现是Map 对象里面...

Lbj虞
今天
13
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部