Android相机开发

Android相机开发

推荐几个好的图片选择+拍照的框架
bilibili/boxing
LuckSiege/PictureSelector5900多个star
jeasonlzy/ImagePicker3600多个star
sucese/phoenix有Camera1和Camera2使用
只有相机功能
CameraKit/camerakit-android3900多个star
natario1/CameraView自由度很高的相机

申请权限




动态权限不要忘了

创建一个可以预览的界面

1.创建一个新工程

2.在新创建的工程中activity中布局文件


3.创建一个相机预览的view 继承SurfaceView

最新都开始用TextureView,关于SurfaceView/TextureView

  • SurfaceView是一个有自己Surface的View。界面渲染可以放在单独线程而不是主线程中。它更像是一个Window,自身不能做变形和动画。
  • TextureView同样也有自己的Surface。但是它只能在拥有硬件加速层层的Window中绘制,它更像是一个普通View,可以做变形和动画。

更多关于SurfaceView与TextureView区别的内容可以参考这篇文章Android 5.0(Lollipop)中的SurfaceTexture,TextureView, SurfaceView和GLSurfaceView.

官方给出的方案,图片来自于Android平台Camera开发实践指南:

官方给出的方案
public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {

    private final SurfaceHolder mHolder;
    private Camera mCamera;

    public CameraPreview(Context context) {
        super(context);
        mHolder = getHolder();
        mHolder.addCallback(this);
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        //surface第一次创建时回调
        //打开相机
        mCamera = Camera.open();
        try {
            mCamera.setPreviewDisplay(holder);
            mCamera.startPreview();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
        //surface变化的时候回调(格式/大小)
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        //surface销毁的时候回调
        mHolder.removeCallback(this);
        mCamera.setPreviewCallback(null);
        mCamera.stopPreview();
        mCamera.release();
        mCamera = null;
    }
}

4.在activity中添加

public class MainActivity extends AppCompatActivity {

    private FrameLayout mFrameLayout;

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

    private void initCamera() {
        CameraPreview preview = new CameraPreview(this);
        mFrameLayout.addView(preview);
    }

    private void initView() {
        mFrameLayout = (FrameLayout) findViewById(R.id.preview_f);
    }
}

至此可以显示一个相机界面,并有图像显示。

添加偏好设置

如分辨率、闪光灯、对焦等。

通过当前界面的相机camera对象获取起设置的参数getParameters()

预览分辨率

  • parameters.getSupportedPreviewSizes()获取相机支持的所有预览分辨率

预览格式

具体参照ImageFormat或者自己Google

  • parameters.getSupportedPreviewFormats()获取相机支持的所有预览格式

照片分辨率

  • parameters.getSupportedPictureSizes()获取相机支持的所有图片分辨率

图片格式

具体参照ImageFormat或者自己Google

  • parameters.getSupportedPictureFormats()获取相机支持的所有图片格式

视频分辨率

parameters.getSupportedVideoSizes()获取相机支持的所有视频分辨率

对焦模式

  • parameters.getSupportedFocusModes()获取相机支持的所有对焦模式

曝光补偿

  • parameters.getMinExposureCompensation()获取相机支持的最低曝光补偿
  • parameters.getMaxExposureCompensation()获取相机支持的最高曝光补偿

闪光灯模式

  • parameters.getSupportedFlashModes()获取相机支持的闪光灯模式

白平衡

  • parameters.getSupportedWhiteBalance()获取相机支持的白平衡

场景

parameters.getSupportedSceneModes()获取相机支持的场景

声明GPS权限

想要拍到的照片中包含GPS信息


代码如下

int numberOfCameras = Camera.getNumberOfCameras();
Log.d("123===", "相机个数===" + numberOfCameras);
Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
for (int i = 0; i < numberOfCameras; i++) {
    Camera.getCameraInfo(i, cameraInfo);
    //后置:0 CAMERA_FACING_BACK; 前置:1 CAMERA_FACING_FRONT
    Log.d("123===", "当前相机信息=" + cameraInfo.facing);
}


Camera camera = mPreview.getCamera();
Camera.Parameters parameters = camera.getParameters();

Log.d("123===", "预览分辨率-----------");
List supportedPreviewSizes = parameters.getSupportedPreviewSizes();
for (Camera.Size previewSize : supportedPreviewSizes) {
    Log.d("123===", previewSize.width + "---" + previewSize.height);
}
Log.d("123===", "预览分辨率-----------");
Log.d("123===", "");
Log.d("123===", "");


Log.d("123===", "获得相机支持的图片预览格式-----------ImageFormat");
List supportedPreviewFormats = parameters.getSupportedPreviewFormats();
for (Integer supportedPreviewFormat : supportedPreviewFormats) {
    Log.d("123===", supportedPreviewFormat + "");
}
Log.d("123===", "获得相机支持的图片预览格式-----------");
Log.d("123===", "");
Log.d("123===", "");


Log.d("123===", "照片分辨率-----------");
List supportedPictureSizes = parameters.getSupportedPictureSizes();
for (Camera.Size pictureSize : supportedPictureSizes) {
    Log.d("123===", pictureSize.width + "---" + pictureSize.height);
}
Log.d("123===", "照片分辨率-----------");
Log.d("123===", "");
Log.d("123===", "");


Log.d("123===", "获得相机支持的图片格式-----------ImageFormat");
List supportedPictureFormats = parameters.getSupportedPictureFormats();
for (Integer supportedPreviewFormat : supportedPictureFormats) {
    Log.d("123===", supportedPreviewFormat + "");
}
Log.d("123===", "获得相机支持的图片格式-----------");
Log.d("123===", "");
Log.d("123===", "");


Log.d("123===", "视频分辨率-----------");
List supportedVideoSizes = parameters.getSupportedVideoSizes();
for (Camera.Size supportedVideoSize : supportedVideoSizes) {
    Log.d("123===", supportedVideoSize.width + "---" + supportedVideoSize.height);

}
Log.d("123===", "视频分辨率-----------");
Log.d("123===", "");
Log.d("123===", "");

Log.d("123===", "对焦模式-----------ImageFormat");
List supportedFocusModes = parameters.getSupportedFocusModes();
for (String supportedFocusMode : supportedFocusModes) {
    Log.d("123===", supportedFocusMode + "");
}
Log.d("123===", "对焦模式-----------");
Log.d("123===", "");
Log.d("123===", "");

Log.d("123===", "曝光补偿-----------");
int minExposureCompensation = parameters.getMinExposureCompensation();
int maxExposureCompensation = parameters.getMaxExposureCompensation();
Log.d("123===", "最高=" + maxExposureCompensation);
Log.d("123===", "最低=" + minExposureCompensation);
Log.d("123===", "曝光补偿-----------");
Log.d("123===", "");
Log.d("123===", "");


Log.d("123===", "支持闪光灯模式-----------");
List supportedFlashModes = parameters.getSupportedFlashModes();
for (String supportedFlashMode : supportedFlashModes) {
    Log.d("123===", "闪光模式--->" + supportedFlashMode);
}
Log.d("123===", "支持闪光灯模式-----------");
Log.d("123===", "");
Log.d("123===", "");


Log.d("123===", "支持白平衡-----------");
List supportedWhiteBalance = parameters.getSupportedWhiteBalance();
for (String s : supportedWhiteBalance) {
    Log.d("123===", "--->" + s);
}
Log.d("123===", "支持白平衡-----------");
Log.d("123===", "");
Log.d("123===", "");

Log.d("123===", "场景-----------");
List supportedSceneModes = parameters.getSupportedSceneModes();
for (String s : supportedSceneModes) {
    Log.d("123===", "--->" + s);
}
Log.d("123===", "场景-----------");
Log.d("123===", "");
Log.d("123===", "");

拍照,视频,对焦

假如需要使用原生拍照功能的话,Camera#takePicture()

拍照和视频都是网上那一套流程,具体的因为时间原因暂时先这样了。

相机预览和保存注意事项

下面三张图片引用自:Android: Camera相机开发详解(中) ——实现预览、拍照、保存照片等功能

  • 相机预览方向
相机预览方向
  • 采集的图像方向
采集的图像方向
  • 前置摄像头预览与保存一致
前置摄像头预览与保存一致

参考

  • Android相机开发系列
  • Android Camera相机开发详解
  • Android: Camera相机开发详解(上) —— 知识储备
  • Android: Camera相机开发详解(中) ——实现预览、拍照、保存照片等功能
  • Android 相机(二): 最详细的自定义相机的步骤拆解
  • Android平台Camera开发实践指南 这有Camera2的知识
  • Android设备对新Camera2 API的支持问题:以华为M2为例

你可能感兴趣的:(Android相机开发)