自定义相机(二)

第一步:拍照预览 自定义相机(一)
第二步:相机参数设置、对焦实现、拍照存储在本地、拍照声音、闪光灯、图片缩放与旋转

上一步,我们完成了相机的预览,但是显示有问题。接下来我们将解决这些问题:

主要涉及:
Camera类
AutoFocusCallback、PictureCallback回调

在Activity中设置相机参数,调整拍照状态。

都在Activity中

//开始预览相机
private void openCamera(){
    if (camera==null){
        //获取相机实例
        camera=camera.open();
        //获取相机参数实例
        Camera.Parameters parameters=camera.getParameters();
        //将相机顺时针旋转90度
        camera.setDisplayOrientation(90);
        //设置输出图片类型
        parameters.setPictureFormat(ImageFormat.JPEG);
        //获取默认照片和相机尺寸 private List<Size> photoSizes, previewSizes;
        photoSizes=camera.getParameters().getSupportedPictureSizes();
        //从大到小还是从小到大顺序
        boolean isF = photoSizes.get(0).width < photoSizes.get(photoSizes
                .size() - 1).width;
        for (Size size : photoSizes) {
            System.out.println("width:" + size.width + "-height:"
                    + size.height);
            if (isF) {
                //设置width:2048-height:1536 图片大小
                if (size.width > 1800) {
                    parameters.setPictureSize(size.width, size.height);
                    break;
                }
            } else {
                if (size.width < 2000) {
                    parameters.setPictureSize(size.width, size.height);
                    break;
                }
            }
        }
        previewSizes = parameters.getSupportedPreviewSizes();
        boolean isFp = previewSizes.get(0).width < previewSizes
                .get(previewSizes.size() - 1).width;
        for (Size size : previewSizes) {
            System.out.println("width:" + size.width + "-height:"
                    + size.height);
            if (isFp) {
                //设置width:1920-height:1088 预览
                if (size.width > 1800) {
                    parameters.setPreviewSize(size.width, size.height);
                    break;
                }
            } else {
                if (size.width < 2000) {
                    parameters.setPreviewSize(size.width, size.height);
                    break;
                }
            }
        }
        camera.setParameters(parameters);
        if (container==null) {
            container = (LinearLayout) findViewById(R.id.ll_contain);
        }
        cameraPreview=new CameraPreview(CameraActivity.this,camera);
        container.addView(cameraPreview);
    }
}



//自动对焦回调
private Camera.AutoFocusCallback afcb =new Camera.AutoFocusCallback() {
    @Override
    public void onAutoFocus(boolean success, Camera camera) {
        //对焦状态
        isFoucs=success;
        if (success){
            //对焦成功的样式图片
            iv_camera.setBackgroundResource(R.drawable.ic_focus_successed);
            try{
                camera.takePicture(null,null,pcb);
            }catch (Exception e){
                e.printStackTrace();
            }
        }else {
            //对焦失败的样式图片
            iv_camera.setBackgroundResource(R.drawable.ic_focus_failed);
        }
    }
};
private Camera.PictureCallback pcb=new Camera.PictureCallback() {
    @Override
    public void onPictureTaken(byte[] data, Camera camera) {
        //播放系统拍照声音
        shootSound();
        isFoucs = false;
        iv_camera.setBackgroundResource(R.drawable.ic_focusing_begin);
        //得到文件路径
        String path = getPhotoPath();
        //相片高度及默认高度
        int height = camera.getParameters().getPictureSize().height;
        if (height <= 0) {
            height = 320;
        }

        camera.startPreview();
        photosList.add(path);
        //输出文件流
        addPhoto(path,data);
    }
};
private void addPhoto(String path,byte[] data){
    if (path!=null){
            try {
                FileOutputStream os=new FileOutputStream(path);
                os.write(data);
                os.close();
            }catch (Exception e){
                e.printStackTrace();
            }
        }
        File file=new File(path);
        if (file!=null){
            Bitmap bitmap= BitmapUtils.getSamllerBitmap(path,200,200);
            bitmap=BitmapUtils.rotateBitmap(bitmap,90);//BitmapUtils.getBitmapAngle(path)
            iv_show.setImageBitmap(bitmap);
        }else {
            Toast.makeText(CameraActivity.this,"显示照片失败!",Toast.LENGTH_SHORT);
        }
}
/**
 * 播放系统拍照声音
 */
public void shootSound() {
    AudioManager meng = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
    int volume = meng.getStreamVolume(AudioManager.STREAM_NOTIFICATION);

    if (volume != 0) {
        MediaPlayer shootMP = null;
        if (shootMP == null)
            shootMP = MediaPlayer
                    .create(this,
                            Uri.parse("file:///system/media/audio/ui/camera_click.ogg"));
        if (shootMP != null)
            shootMP.start();
    }
}
private String getPhotoPath(){
    if (photoPath==null){
        photoPath = Environment.getExternalStorageDirectory().getPath() + "/test1/photo/";
        File file = new File(photoPath);
        if (!file.exists()) {
            file.mkdirs();
        }
    }
    return photoPath+ System.currentTimeMillis()+".jpg";
}


public void onClick(View v) {

    switch (v.getId()){
        case R.id.btn_camera:
            if (isFoucs){
                camera.takePicture(null,null,pcb);
            }else {
                camera.autoFocus(afcb);
            }

            break;
    }
}


//        Camera.Parameters params = camera.getParameters();
//        // 开启闪光灯
//        params.setFlashMode(Camera.Parameters.FLASH_MODE_ON);
//        // 关闭闪光灯
//        params.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);

图片缩放和旋转

//图片帮助类
public class BitmapUtils {
    //计算图片的缩放值
    public static int calculateinSampleSize(BitmapFactory.Options options,int reqWidth,int reqHeight){
        final int width =options.outWidth;
        final int height =options.outHeight;
        int inSampleSize =1;
        if (reqHeight<height||reqWidth<width){
            final int widthRadio=Math.round((float) width/(float)reqWidth);
            final int heightRadio=Math.round((float) height/(float)reqHeight);
            inSampleSize=widthRadio<heightRadio?widthRadio:heightRadio;
        }
        return inSampleSize;
    }
    // 根据路径获得图片并压缩,返回bitmap用于显示
    public static Bitmap getSamllerBitmap(String path,int reqWidth,int reqHeight){
        final BitmapFactory.Options options=new BitmapFactory.Options();
        //只加载图像框架
        options.inJustDecodeBounds=true;
        BitmapFactory.decodeFile(path,options);

        options.inSampleSize=calculateinSampleSize(options,reqWidth,reqHeight);
        //设置加载全部图像内容
        options.inJustDecodeBounds=false;
        return BitmapFactory.decodeFile(path,options);
    }
    //旋转照片
    public static Bitmap rotateBitmap(Bitmap bitmap,int angle){
        if (null!=bitmap){
            Matrix matrix=new Matrix();
            matrix.postRotate(angle);

            bitmap=Bitmap.createBitmap(bitmap,0,0,bitmap.getWidth(),bitmap.getHeight(),matrix,true);
        }
        return bitmap;
    }
    //得到照片旋转角度
    public static int getBitmapAngle(String path){
        int angle=0;
        try {
            ExifInterface exifInterface=new ExifInterface(path);
            int orientation =exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION,
                    ExifInterface.ORIENTATION_NORMAL);
            switch (orientation){
                case ExifInterface.ORIENTATION_ROTATE_90:
                    angle=90;
                    break;
                case ExifInterface.ORIENTATION_ROTATE_180:
                    angle=180;
                    break;
                case ExifInterface.ORIENTATION_ROTATE_270:
                    angle=270;
                    break;
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return angle;
    }
}

自定义相机源码


  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android自定义相机是一种使用相机API来定制自己的相机界面或开发特殊相机功能的方法。它适用于需要对照片进行裁剪、滤镜处理、添加贴纸、表情、地点标签等操作的场景。相比直接通过Intent调用系统相机组件,自定义相机能够提供更多的灵活性和可定制性。在使用自定义相机之前,需要进行系统权限配置,包括相机权限、文件读写权限以及相机自动对焦配置。同时,应该检查设备是否具备相机功能,以避免在没有相机的设备上使用相关功能。 <span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [Androd自定义控件(五)打造自己的Camera](https://blog.csdn.net/sdkfjksf/article/details/51137408)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* [Android自定义相机—Camera篇](https://blog.csdn.net/m0_56146626/article/details/128595800)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值