自定义水印相机(watercamera)

关于自定义水印相机(watercamera)的一点心得


本文为原创,转载请声明!


网上有很多自定义相机,但是跟我需要的项目真心不符,所以最后还是只能找了一个(git上面的例子:原本想链接地址的,结果没找到了,是个外国朋友的项目,所以还是用我的吧)过来修改了,还是我一贯的作风,代码中注释说明!

两个类:

第一个类CameraDialog相机

是关于相机的,从调用相机到设计相机参数等,这个类可以随意更改继承fragment或者dialog,关键在于你运用的地方需求了
对了,这个类中有运用了(事件分发),如果需要详细了解的话,请点击郭霖大神的链接

首先,权限声明:
由于我们项目版本支持要求,不能使用camera2, 因此继续沿用camera这个过时的api,第一个是用户使用相机权限,第二个是硬件请求权限,第三个是相机自动对焦权限,第四个是写入SD卡权限。

<!--相机相关权限-->
    <uses-permission android:name="android.permission.CAMERA" />
    <uses-feature android:name="android.hardware.camera" android:required="true"/>
    <uses-feature android:name="android.hardware.camera.autofocus" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

其次,讲讲水印相机的所涉及的一般问题:
一. 水印的添加:关于水印的添加,我主要是以下这种思路,1. 通过方法

 mCamera.takePicture(null, null, mPicture);

拍出图片。


我并不想直接利用intent这个方法

Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(intent, 1);

然后再去处理

@Override  
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {  
        // TODO Auto-generated method stub  
        super.onActivityResult(requestCode, resultCode, data);  
}

而是采取以Camera.PictureCallback回调方法传回的图片数据(byte[] data)进行转化(转成bitmap)

Camera.PictureCallback mPicture = new Camera.PictureCallback() {
        @Override
        public void onPictureTaken(byte[] data, Camera camera) {
             //处理图片数据data
         }

再来,就是看几个重要的方法了,输出图片路径方法getOutputMediaFile()


/**
     * 设置相片储存目录
     * FileUtils 顾名思义是一个用来处理文件的常用工具类,自己定义的
     * getStringToday()也是常用时间工具类里面的一个自定义方法
     */
private File getOutputMediaFile() {
        File file = FileUtils.setPictureDirectory(mContext);
        path = file.getAbsolutePath() + File.separator
                + getStringToday() + ".jpg";
        File mediaFile = new File(path);
        return mediaFile;
    }

    /**
     * 设置相片目录
     * @param context
     * @param
     * @return
     */
    public static File setPictureDirectory(Context context) {
        String filePath = setPicturePath(context);
        File destDir = new File(filePath);
        if (!destDir.exists()) {
            boolean isCreate = destDir.mkdirs();
            log(filePath + " has created. " + isCreate);
        }
        return destDir;
    }

    /**
     * 设置图片路径
     *
     * @param context
     * @param
     * @return
     */
    public static String setPicturePath(Context context) {
        String filePath;
        // 如SD卡已存在,则存储;反之存在data目录下
        if (hasSdcard()) {
            // SD卡路径:SD\Picture\AutoCapture 目录下
            filePath = Environment.getExternalStorageDirectory() + File.separator +"Picture"  + File.separator +"AutoCapture"
//  + dirName
            ;
        } else {
            filePath = context.getCacheDir().getPath() + File.separator
//  + dirName
            ;
        }

    /**
     * 得到现在时间
     * 格式化时间格式为yyyyMMdd_HHmmss
     * @return 字符串 yyyyMMdd_HHmmss
     */
    public static String getStringToday() {
        Date currentTime = new Date();
        SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMddHHmmssSSS");
        String dateString = formatter.format(currentTime);
        return dateString;
    }

然后,就是看另一个重要问题,拍照时,预览界面跟拍照后相片不能正摆问题,有些会倒90度,有些则是-90度,总之就是角度调整方法 setOrientations()

    /**
     *  解决预览界面跟拍照后相片不能正摆问题
     *  
     */
    private void setOrientations() {
        if (mCamera != null) {
            Camera.Parameters cameraParameter = mCamera.getParameters();
            cameraParameter.setRotation(90);
            cameraParameter.set("rotation", 90);
            if ((orientations >= 45) && (orientations < 135)) {
                cameraParameter.setRotation(180);
                cameraParameter.set("rotation", 180);
            }
            if ((orientations >= 135) && (orientations < 225)) {
                cameraParameter.setRotation(270);
                cameraParameter.set("rotation", 270);
            }
            if ((orientations >= 225) && (orientations < 315)) {
                cameraParameter.setRotation(0);
                cameraParameter.set("rotation", 0);
            }
            mCamera.setParameters(cameraParameter);
        }
    }

        //当然,在预览界面CameraPreview类中可以通过调用
        //mCamera.setDisplayOrientation(90)来改变
        //(根据横屏竖屏需求来处理)

    @Override
    public void surfaceCreated(SurfaceHolder surfaceHolder) {
        try {
            mCamera.setPreviewDisplay(surfaceHolder);
            mCamera.getParameters().setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
            mCamera.setDisplayOrientation(90);
            mCamera.startPreview();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

最后就说一说Bitmap.compress(CompressFormat format, int quality, OutputStream stream)这个方法了,通过API源码我们可以知道CompressFormat 一共有三种储存格式

public enum CompressFormat {
        JPEG    (0),
        PNG     (1),
        WEBP    (2);

        CompressFormat(int nativeInt) {
            this.nativeInt = nativeInt;
        }
        final int nativeInt;
    }    

其中 PNG 和WEBP我了解不多,时间需要,也没去深究,但是查阅了很多相关资料才知道:只有Bitmap.CompressFormat格式为JPEG,第二个参数quality才能起作用!这是令我多么悲痛的领悟啊…第三个参数也是很重要的,但是必须通过 ByteArrayOutputStream stream = new ByteArrayOutputStream()来作容器,原理大概是这么讲:Bitmap.compress方法即将数据以jpeg格式压缩,压缩比例为quality,压缩后的数据存入stream。

Camera.PictureCallback mPicture = new Camera.PictureCallback() {
        @Override
        public 
  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值