zoukankan      html  css  js  c++  java
  • 开源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。

  • 相关阅读:
    "Hello world" of ML
    数据读进set,进行后处理
    从csv文件读取数据到二维vector
    logistic regression
    Probabilistic interpretation
    python3 批量管理Linux服务器 下发命令与传输文件
    Redis 主从复制、读写分离(基于docker)
    Springboot 整合Redis
    Unable to connect to Redis; nested exception is io.lettuce.core.RedisConnectionException: Unable to connect to 106.xx.xxx229:6379
    docker 创建redis容器以及redis命令笔记
  • 原文地址:https://www.cnblogs.com/laoguigame/p/5645124.html
Copyright © 2011-2022 走看看