Android拍照图片长宽设置在各手机上正常运行

   最近在项目中做图片拍照时遇到一个问题,当我将图片大小设置为固定值时,在一些手机或者平板上面运行demo时就会出现相机初始化报错。后来通过在网上查中一些例子和自己试验,最后总结了自己的一点心得。

1在拍照图片预览和设置拍摄图片大小时,因为不同机型支持的图片长宽设置和预览长宽设置不一定全部相同,因此可能会导致程序奔溃。
一下两张图片时我用一台华为平板和一台三星手机测试的结果
华为平板结果
这里写图片描述
从结果中可以看到华为支持的照片组合只有17组;
三星手机结果
这里写图片描述
三星支持的组合为31种,
所以在设置相片大小时,为了适合在各个手机上面的兼容性,我们最好别将相片长宽设置为固定值。
因此记录一下代码,方便日后重蹈覆辙。
1 开启相机权限,文件读写权限

 <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.CAMERA" />
    <!--在SDcard中创建与删除文件权限-->
    <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
    <!--往SDcard写入数据权限-->
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <uses-feature android:name="android.hardware.Camera"/>

同时我将拍照设置为乐横屏

   <activity android:name=".MainActivity"
            android:screenOrientation="landscape"
            >
            <intent-filter>
                <action android:name="android.intent.action.MAIN"
                    />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

2 layout 文件很简单,一个surfaceView,两个button。

   <?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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"
    tools:context="com.camera.demo.MainActivity">

    <SurfaceView
        android:id="@+id/surface_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <Button
            android:id="@+id/start"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentBottom="true"
            android:layout_alignParentLeft="true"
            android:layout_alignParentStart="true"
            android:layout_marginBottom="20dp"
            android:layout_marginLeft="20dp"
            android:layout_marginStart="20dp"
            android:padding="20dp"
            android:text="开始" />

        <Button
            android:id="@+id/btn_stop"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentRight="true"
            android:layout_alignParentEnd="true"
            android:layout_alignTop="@+id/start"
            android:layout_marginEnd="20dp"
            android:layout_marginRight="20dp"
            android:padding="20dp"
            android:text="停止" />
    </RelativeLayout>

</FrameLayout>

3摘要代码也很简单,也就是基本的相机拍照,
MainActivity实现SurfaceHolder.Callback接口(开启相机,操作相机,关闭相机)和 Camera.PictureCallback (将拍摄的照片转换为字节)接口

package com.camera.demo;


import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.hardware.Camera;
import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;

import java.io.ByteArrayOutputStream;
import java.util.List;


public class MainActivity extends AppCompatActivity implements SurfaceHolder.Callback, View.OnClickListener, {
    private SurfaceView mSurficeView;
    private Button btnStart;
    private SurfaceHolder mHolder;
    private Camera camera;
    private Handler mHandler = new Handler();
    private boolean mIsSurfaceCreated = false;
    private static final int CAMERA_ID = 0; //选择后置摄像头
    private Button btnStop;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();
        initEvent();

    }

    private void initView() {
        mSurficeView = (SurfaceView) findViewById(R.id.surface_view);
        btnStart = (Button) findViewById(R.id.start);
        btnStop = (Button) findViewById(R.id.btn_stop);
    }

    private void initEvent() {
        mHolder = mSurficeView.getHolder();
        mHolder.addCallback(this);
        btnStart.setOnClickListener(this);
        btnStop.setOnClickListener(this);
    }

    @Override
    protected void onPause() {
        super.onPause();
        stopPreview();
    }


    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        mIsSurfaceCreated = true;
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
        Log.v("MainActivity", String.valueOf(width) + String.valueOf(height));
        //开启相机预览
        startPreview();
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        mIsSurfaceCreated = false;
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.start:
            camera.startPreview();
           break;
            case R.id.btn_stop:
             stopPreview()
                break;
            default:
                break;
        }
    }


    private void startPreview() {
        if (camera != null || !mIsSurfaceCreated) {
            return;
        }
        camera = Camera.open(CAMERA_ID);
        Camera.Parameters parameters = camera.getParameters();
        //设置连续对焦
        parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
        //  设置相机预览方向
        camera.setDisplayOrientation(0);
        //获取手机支持的相片大小组合
        List<Camera.Size> picSize = camera.getParameters().getSupportedPictureSizes();
        int picLength = picSize.size();
        for (int i = 0; i < picLength; i++) {
            Camera.Size pSize = picSize.get(i);
            Log.v("MainActivity", "picWidth" + pSize.width + "pciHeight" + pSize.height);
        }
        //获取最小一组图片大小的长宽值
        int w = picSize.get(picSize.size() - 1).width;
        parameters.setPictureSize(picSize.get(picSize.size() - 1).width, picSize.get(picSize.size() - 1).height);
        //获取支持的图片预览大小
        List<Camera.Size> preSize = camera.getParameters().getSupportedPreviewSizes();
        for (int j = 0; j < preSize.size(); j++) {
            Camera.Size prSize = preSize.get(j);
            Log.v("MainActivity", "preWidth" + prSize.width + "preHeight" + prSize.height);
        }
        //获取最小一组图片预览长宽值
        parameters.setPreviewSize(preSize.get(preSize.size()-1).width,         preSize.get(preSize.size()-1).height);
        camera.setParameters(parameters);
        try {
            camera.setPreviewDisplay(mHolder);
        } catch (Exception e) {
            e.printStackTrace();
        }
        camera.startPreview();
    }

    private void stopPreview() {
        //释放camera
        if (camera != null) {
            try {
                camera.setPreviewDisplay(null);
                camera.stopPreview();
                camera.release();
                camera = null;
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        camera = null;
    }
}
  上面的代码中,我都是获取的最后的一组长宽值,项目中。我们可以根据需要去选取。但是最好别写固定值,之前在网上面看见很多都是写的固定值,走了不少弯路。。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值