拍照问题一览

很多APP 都有拍照的需求 但是用户一旦多起来 问题也会比较多 因为拍照会一并跟着压缩 上传甚至会有加水印 兼容问题也随之而来

这里从头到尾讲一下,看看能不能帮到大家:

1 第一个问题是权限问题 毕竟没有权限是没办法做后面的操作的

RxPermissions.getInstance(this)
                .request(Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.CAMERA)
                .subscribe(new Action1<Boolean>() {
                    @Override
                    public void call(Boolean granted) {
                        if (!granted) {
                            showToast("请把相机和存储权限打开");
                            return;
                        }
                        File sd = Environment.getExternalStorageDirectory();
                        String path = sd.getPath() + "/RxjavaImg"; // 在根目录创建一个文件夹来存放图片  可以自己创建
                        File file = new File(path);
                        if (!file.exists()) {
                            file.mkdir();
                        }
                        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);//打开摄像机列表选项
                        intent.putExtra("return-data", false);
                        final Intent intent_camera = getPackageManager().getLaunchIntentForPackage("com.android.camera");
                        if (intent_camera != null) {
                            String s = GetAction_image_capture();
                            int index = s.indexOf("com");
                            if (index == -1) {    //不存在的话  有一些手机 这个会有异常情况  如果没有这个需求的话 可以把setPackage这段注释掉 不影响使用
                                intent.setPackage("com.android.camera");  // 设置为手机自带的默认拍照软件
                            } else {
                                intent.setPackage(s);  // 有些手机 并不是com.android.camera 相对比较奇特 所以我用了一个判断前缀应用包名com开头的区分一下
                            }
                        }
                        intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(new File(AppConfig.CAMERA_TEMP)));  // 里面的AppConfig.CAMERA_TEMP 为保存的文件路径 最后是.jpg的
                        startActivityForResult(intent, CAMERA);

                    }
                });

这里的操作包括了权限的请求 和最开始的拍照请求 最终图片保存到对应的目录

2 第二个问题就是拍照完后的回调

  @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

               if (requestCode == CAMERA && resultCode == RESULT_OK) {
                  showLoadingDialog("加载中....");
                    /**
                     *  在这里进行回调  有大佬让我全部操作都写一个Rxjava里面 现在还在琢磨
                     * 这里取到用户拍完照的图片  然后进行压缩 显示
                     * getCompressPics()是 核心方法 下面会有写  AppConfig.CAMERA_TEMP是原图路径
                     * */
                          getCompressPics(AppConfig.CAMERA_TEMP);
                  } 

}

3 第三个 这里应该是核心问题了 图片压缩 打水印 和最后的回传

    public void getCompressPics(final String pathString) {
        File file = new File(pathString);
        final String paths[] = new String[2];
        LubanText.get(PhotoBaseActivity3.this)
                .load(file)
                .putGear(LubanText.THIRD_GEAR)/** 兼容性最好*/
                        .asObservable()
                .subscribeOn(Schedulers.newThread())
                .observeOn(AndroidSchedulers.mainThread())
                .map(new Func1<File, File>() {
                    @Override
                    public File call(File file) {
                        /**加水印  这里传的是 文件地址   操作的 都是一样的东西*/
                        return Watermark(file.getPath(), 80);
                    }
                })
                .subscribeOn(Schedulers.newThread())
                .observeOn(AndroidSchedulers.mainThread())
                .unsubscribeOn(Schedulers.io())
                .doOnError(new Action1<Throwable>() {
                    @Override
                    public void call(Throwable throwable) {
                        throwable.printStackTrace();
                    }
                })
                .onErrorResumeNext(new Func1<Throwable, Observable<? extends File>>() {
                    @Override
                    public Observable<? extends File> call(Throwable throwable) {
//                        Toast.makeText(mContext, "由于没有读写权限导致无法正常压缩", Toast.LENGTH_SHORT).show();

                        dismissLoadingDialog(); //取消加载框  不写的话 注释掉就可以了
//                        String s = "/storage/emulated/0/RxjavaImg/image/2017-07-19/1500447991691.jpg";
                                onReceiveCamera1(AppConfig.CAMERA_TEMP);  // onReceiveCamera1()这个方法是一个回调 把 图片路径返回 回去
                             return Observable.empty();
                    }
                })
                .subscribe(new Action1<File>() {
                    @Override
                    public void call(File file) {
                        LogUtil.e("msg", "file:" + file);
                        LogUtil.e("msg", file.length() / 1024 + "k");
                        LogUtil.e("msg", 
               
                        pach = file + "";
                        /**处理完之后回调回去  返回给对应的类*/
                          dismissLoadingDialog();  //取消加载框  不写的话 注释掉就可以了
                         onReceiveCamera1(pach);  // onReceiveCamera1()这个方法是一个回调 把 图片路径返回 回去
                    }
                });
    }

回调之后 要干嘛就干嘛了 下面是支持的方法 还有最重要的水印

4 第四个 水印


 /***
     * 打水印的方法
     * 三次修改版
     * 1 就是先缩放读取原图,
     * 2 然后加水印,
     * 3 再生成新的图片文件
     */
    private File Watermark(String filePath, int Ratio) {

        /**
         * 最终保存的图片尺寸
         * 宽度  高度  压缩率
         * 宽高并不会固定为输入尺寸 只是参考
         * 压缩率直接影响 文件大小
         * 有问题 直接修改这里的数值!!
         * .putGear(LubanText.CUSTOM_GEAR) 这里也有影响
         *  */
        int Width = 720;
        int Height = 1280;
        int ratio = Ratio;

        /**保存的图片名称  记得要创建一下   最终提交的图片  */
        String PathName = AppConfig.APP_IMAGE_FOLDER + System.currentTimeMillis() + ".jpg";


        File preFile = new File(PathName);
        try {
            /** 创建一下*/
            if (!preFile.exists()) {
                preFile.createNewFile();
            }
            /** 缩放并读取图片文件    质量问题 直接调后面两个长宽度  按照等比 缩放的 所以没问题* */
            Bitmap resizedBitmap = BitmapUtilsText.getZoomImage(filePath, Width, Height);

//  ImageTool.generatorContactCountIcon 这个是打水印的方法 百度一下 挺多的 

            if (true || true) {
                LogUtil.e("msg", "打水印" + PathName);
           isHasWaterMark1 = "2017年12月31日11.11.11";
           s = "广州市天河区超级超级美女店!";
                resizedBitmap = ImageTool.generatorContactCountIcon(resizedBitmap, this, isHasWaterMark1, s);
            }

            /**保存操作 这里放的是新地址*/
            BufferedOutputStream bos2;
            bos2 = new BufferedOutputStream(new FileOutputStream(preFile));
            resizedBitmap.compress(Bitmap.CompressFormat.JPEG, ratio, bos2);

            LogUtil.e("msg", "file:getWidth" + resizedBitmap.getWidth());
            LogUtil.e("msg", "file:getHeight" + resizedBitmap.getHeight());
            LogUtil.e("msg", "拍照后保存的图片文件大小" + preFile.length() / 1024 + "kb");

            resizedBitmap.recycle();
            resizedBitmap = null;
            bos2.flush();
            bos2.close();

        } catch (Exception e) {
            LogUtil.e("msg", "添加水印出现异常");
            e.printStackTrace();
        }

        return preFile;
    }

5 第5个 支撑上面运行的方法

 //获取手机内部原生的应用相机包名
    private String GetAction_image_capture() {
        String Action_image_capture = "";
        Intent infoIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        ResolveInfo resolveInfo = getPackageManager().resolveActivity(infoIntent, 0);
        if (resolveInfo != null) {
            Log.d("PhotoBaseActivity3", "手机默认相机名称为" + resolveInfo.activityInfo.packageName);
            Action_image_capture = resolveInfo.activityInfo.packageName;
        }
        return Action_image_capture;
    }

    /**
     * 接收到相机拍照的图片
     */
    protected abstract void onReceiveCamera1(String path);
 不知道还有没有遗漏 也就仅供参考罢了  亲自测试了 华为 小米 oppo vivo 努比亚 索尼  乐视 等等几十台手机,还在提高兼容度 有不对的地方 希望大家指出  最后 感谢  浪浪大佬的耐心指导  非常感谢!
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,835评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,598评论 1 295
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,569评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,159评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,533评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,710评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,923评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,674评论 0 203
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,421评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,622评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,115评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,428评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,114评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,097评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,875评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,753评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,649评论 2 271

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 170,569评论 25 707
  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 11,618评论 4 59
  • React介绍 react不是一个mvc的框架,它仅仅是V层。它是一个鼓励构建随着数据变化而改变UI表现的库。 R...
    我能坚持多久阅读 586评论 0 1
  • 因为本地存在该账号的证书,解决办法: 因为你的账号中已经有了证书了,而那个证书是由别的电脑生成的,所以你这个不能生...
    亦晴工作室阅读 895评论 0 0
  • 夜静,朦胧,欲催归 屏风墨迹香,梅印潦僚, 月稀风寂,画扇深处女子香,尘世几许望断肠,谁伤一生? 梧桐树下,画扇依...
    小屋的屋阅读 194评论 0 1