• 开源android-crop裁剪库的bug并修复


    最近项目中使用了开源裁剪库android-crop,使用过程中遇到了三星手机拍照后裁剪的bug,上官方github里看issues发现果真还是有开发者同样遇到这个问题的。bug描述如下:
    用手机拍照(保持竖屏)后进入裁剪界面,裁剪完后的图片是旋转90度的,但是在裁剪预览界面中看的是正常的。

    最好到官方github去clone原始项目,运行其中的example程序体验下。

    先看修复前bug截图:
    1.png

    2.png
    修复后截图:
    Paste_Image.png

    Paste_Image.png

    修复过程

    1. CropImageActivity.java修改前的saveOutput方法:
    private void saveOutput(Bitmap croppedImage) {
        if (saveUri != null) {
            OutputStream outputStream = null;
            try {
                outputStream = getContentResolver().openOutputStream(saveUri);
                if (outputStream != null) {
                    croppedImage.compress(saveAsPng ? Bitmap.CompressFormat.PNG : Bitmap.CompressFormat.JPEG,
                            90,     // note: quality is ignored when using PNG
                            outputStream);
                }
            } catch (IOException e) {
                setResultException(e);
                Log.e("Cannot open file: " + saveUri, e);
            } finally {
                CropUtil.closeSilently(outputStream);
            }
    
            CropUtil.copyExifRotation(
                    CropUtil.getFromMediaUri(this, getContentResolver(), sourceUri),
                    CropUtil.getFromMediaUri(this, getContentResolver(), saveUri)
            );
    
            setResultUri(saveUri);
        }
    
        final Bitmap b = croppedImage;
        handler.post(new Runnable() {
            public void run() {
                imageView.clear();
                b.recycle();
            }
        });
    
        finish();
    }
    

    修改后的saveOutput方法:

    private void saveOutput(Bitmap croppedImage) {
        if (saveUri != null) {
            OutputStream outputStream = null;
    
            Bitmap destBitmap = croppedImage;
            if(exifRotation != 0){
                destBitmap = CropUtil.rotateImage(croppedImage, exifRotation);
            }
            FileInputStream inputStream = null;
            try {
                //save bitmap to file
                outputStream = getContentResolver().openOutputStream(saveUri);
                if (outputStream != null) {
                    destBitmap.compress(saveAsPng ? Bitmap.CompressFormat.PNG : Bitmap.CompressFormat.JPEG,
                            90,     // note: quality is ignored when using PNG
                            outputStream);
                }
                destBitmap.recycle();
            } catch (OutOfMemoryError error) {
            } catch (IOException e){
                setResultException(e);
                Log.e("Cannot open file: " + saveUri, e);
            }finally {
                CropUtil.closeSilently(inputStream);
                CropUtil.closeSilently(outputStream);
            }
    
            CropUtil.copyExifRotation(
                    CropUtil.getFromMediaUri(this, getContentResolver(), sourceUri),
                    CropUtil.getFromMediaUri(this, getContentResolver(), saveUri)
            );
    
            setResultUri(saveUri);
        }
    
        final Bitmap b = croppedImage;
        handler.post(new Runnable() {
            public void run() {
                imageView.clear();
                b.recycle();
            }
        });
    
        finish();
    }
    

    其实只是加入了旋转角度的判定,如果角度不为0则旋转图片再保存

    if(exifRotation != 0){
        destBitmap = CropUtil.rotateImage(croppedImage, exifRotation);
    }
    

    CropUtil.rotateImage的代码如下:

    public static Bitmap rotateImage(Bitmap img, int rotate) {
        Matrix matrix = new Matrix();
        matrix.postRotate(rotate);
        int width = img.getWidth();
        int height = img.getHeight();
        img = Bitmap.createBitmap(img, 0, 0, width, height, matrix, false);
        return img;
    }
    
    1. 在CropImageActivity.java的onSaveClicked方法中的croppedImage = decodeRegionCrop(r, outWidth, outHeight);前加入如下代码:
    if(exifRotation != 0 && exifRotation % 90 == 0){
        int tmp = outWidth;
        outWidth = outHeight;
        outHeight = tmp;
    }
    

    如果有旋转角度,则在decodeRegionCrop裁剪前,需要对裁剪的宽和高进行交换处理。

    写在最后

    大家可以在我的github地址android-cropclone我的官方fork版本。
    example中相比原始项目增加了拍照后裁剪的demo。

  • 相关阅读:
    ionic 导航
    vscode多光标编辑(MAC)
    vscode保存文件时自动删除行尾空格
    ionic-native sqlite 插件5.x版的在ionic3.x上报错 cannot read property 'split' of undefined
    MAC OSX 自带Apache 配置及使用
    ionic中ion-item下的div,span,p不渲染,应该给这些元素加上item-content属性
    开发ionic + cordova应用时遇到的坑,resources/splash.png do not meet minimum size requirements: 2732x2732
    ionic 创建指令的命名规则
    Soldier and Badges (set的检索简单运用)
    打败大魔王之最小排列数问题(全排列)
  • 原文地址:https://www.cnblogs.com/laoguigame/p/5645124.html
Copyright © 2020-2023  润新知