缩放图像不会丢失图像质量没有工作 [英] Scale image without losing image quality did not work

查看:142
本文介绍了缩放图像不会丢失图像质量没有工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有谁知道如何不失画质缩放位图图像?目前我面临这个<一个href=\"http://stackoverflow.com/questions/34315387/will-the-image-too-big-caused-app-return-to-$p$pvious-activity\">problem,其中,选择图像的大小可能过大引起的应用程序回归到另一个活动。

所以,现在我使用这种方法,而不会失去其质量缩放选定的图像尝试。我得到的code从<一个href=\"http://adilatwork.blogspot.my/2012/10/android-how-to-scale-bitmap-and-retain.html\">here.

 保护无效的onActivityResult(INT申请code,INT结果code,
                                    意图数据){
        super.onActivityResult(要求code,结果code,数据);
        开关(要求code){
            案例RESULT_LOAD_IMAGE:
                如果(要求code == RESULT_LOAD_IMAGE&放大器;&安培;结果code == RESULT_OK&安培;!NULL =数据){
                    乌里selectedImage = data.getData();
                    的String [] = filePathColumn {MediaStore.Images.Media.DATA};
                    光标光标= getContentResolver()
                            .query(selectedImage,filePathColumn,NULL,NULL,
                                    空值);
                    cursor.moveToFirst();
                    INT参数:columnIndex = cursor.getColumnIndex(filePathColumn [0]);
                    字符串picturePath = cursor.getString(参数:columnIndex);
                    cursor.close();
                    位图=(BitmapFactory.de codeFILE(picturePath));
                    相片= scaleBitmap(一,200,200);
                    imageView.setImageBitmap(照片);
                }
                打破;
}  公共静态位图scaleBitmap(位图位图,诠释newWidth,诠释newHeight){
        位图scaledBitmap = Bitmap.createBitmap(newWidth,newHeight,Bitmap.Config.ARGB_8888);        漂浮的scaleX = newWidth /(浮点)bitmap.getWidth();
        漂浮的scaleY = newHeight /(浮点)bitmap.getHeight();
        浮pivotX = 0;
        浮pivotY = 0;        矩阵scaleMatrix =新的Matrix();
        scaleMatrix.setScale(将scaleX,的scaleY,pivotX,pivotY);        帆布帆布=新的Canvas(scaledBitmap);
        canvas.setMatrix(scaleMatrix);
        canvas.drawBitmap(位图,0,0,新涂料(Paint.FILTER_BITMAP_FLAG));        返回scaledBitmap;
    }

答案似乎有助于大多数人,但它为什么不为我工作?我错过了什么?

原始图像

上的ImageView 选择的图像显示


解决方案

 使用此它一定会帮助你减少大小没有松动质量。
公共位图COM pressImage(字符串imageUri){        字符串文件路径= imageUri;
        //字符串文件路径= getRealPathFromURI(imageUri);
        位图scaledBitmap = NULL;        BitmapFactory.Options选项=新BitmapFactory.Options();        //通过设置此字段为真,实际的位图像素不是
        //加载在存储器中。就在边界被加载。如果
        //您尝试使用位图在这里,你会得到空。
        options.inJustDe codeBounds = TRUE;
        BMP位图= BitmapFactory.de codeFILE(文件路径,期权);        INT的ActualHeight = options.outHeight;
        INT ActualWidth的= options.outWidth;        在COM pressed形象//最大高度和宽度值取为
        // 816x612        / *
         *浮了maxHeight = 816.0f;浮了maxWidth = 612.0f;
         * /
        浮了maxHeight = 1080.0f;
        浮了maxWidth = 800.0f;        浮imgRatio = ActualWidth的/(浮动)的ActualHeight;
        浮maxRatio =了maxWidth /(浮点)了maxHeight;        //宽度和高度值被设置保持的纵横比
        // 图片        如果(的ActualHeight&GT;了maxHeight || ActualWidth的&GT;了maxWidth){
            如果(imgRatio&LT; maxRatio){
                imgRatio =了maxHeight /的ActualHeight;
                ActualWidth的=(INT)(imgRatio * ActualWidth的);
                的ActualHeight =(INT)了maxHeight;
            }否则如果(imgRatio&GT; maxRatio){
                imgRatio =了maxWidth / ActualWidth的;
                的ActualHeight =(INT)(imgRatio *的ActualHeight);
                ActualWidth的=(INT)了maxWidth;
            }其他{
                的ActualHeight =(INT)了maxHeight;
                ActualWidth的=(INT)了maxWidth;            }
        }        //设置inSampleSize值允许装载的缩小版本
        //原始图像        options.inSampleSize = calculateInSampleSize(选项,ActualWidth的,的ActualHeight);        //设置为false inJustDe codeBounds加载实际的位图
        options.inJustDe codeBounds = FALSE;        //这个选项允许权利要求的位图内存的Andr​​oid,如果电量不足
        //内存
        options.inPurgeable = TRUE;
        options.inInputShareable = TRUE;
        options.inTempStorage =新的字节[16 * 1024];        尝试{
            //来自其路径加载位图
            BMP = BitmapFactory.de codeFILE(文件路径,期权);
        }赶上(例外的OutOfMemoryError){
            exception.printStackTrace();        }
        尝试{
            scaledBitmap = Bitmap.createBitmap(ActualWidth的,的ActualHeight,Bitmap.Config.ARGB_8888);
        }赶上(例外的OutOfMemoryError){
            exception.printStackTrace();
        }        浮ratioX = ActualWidth的/(浮点)options.outWidth;
        浮ratioY =的ActualHeight /(浮点)options.outHeight;
        浮middleX = ActualWidth的/ 2.0F;
        浮middleY =的ActualHeight / 2.0F;        矩阵scaleMatrix =新的Matrix();
        scaleMatrix.setScale(ratioX,ratioY,middleX,middleY);        帆布帆布=新的Canvas(scaledBitmap);
        canvas.setMatrix(scaleMatrix);
        canvas.drawBitmap(BMP,middleX - bmp.getWidth()/ 2,middleY - bmp.getHeight()/ 2,新油漆(Paint.FILTER_BITMAP_FLAG));        //检查图像的旋转并正确显示
        ExifInterface EXIF​​;
        尝试{
            EXIF =新ExifInterface(文件路径);            INT方向= exif.getAttributeInt(ExifInterface.TAG_ORIENTATION,0);
            displayLogs(EXIF,的Exif:+方向);
            字模=新的Matrix();
            如果(方向== 6){
                matrix.postRotate(90);
                displayLogs(EXIF,的Exif:+方向);
            }否则如果(取向== 3){
                matrix.postRotate(180);
                displayLogs(EXIF,的Exif:+方向);
            }否则如果(方向== 8){
                matrix.postRotate(270);
                displayLogs(EXIF,的Exif:+方向);
            }            scaledBitmap = Bitmap.createBitmap(scaledBitmap,0,0,scaledBitmap.getWidth(),scaledBitmap.getHeight(),矩阵,真);
        }赶上(IOException异常五){
            e.printStackTrace();
        }        FileOutputStream中走出= NULL;
        字符串的文件名的getFileName =(文件路径);
        //文件图像=新的文件(用GetFileName(),System.currentTimeMillis的()+
        //.JPG);
        尝试{
            OUT =新的FileOutputStream(文件名);            //写COM pressed位在被指定的目标
            // 文件名。
            布尔didWrite = scaledBitmap.com preSS(Bitmap.Com pressFormat.JPEG,80出);            out.close();            的System.out.println(didWrite);
        }赶上(FileNotFoundException异常五){
            e.printStackTrace();
        }赶上(IOException异常五){            e.printStackTrace();
        }        返回scaledBitmap;    }    私人字符串getRealPathFromURI(字符串contentURI){
        乌里contentUri = Uri.parse(contentURI);
        。光标光标= getContentResolver()查询(contentUri,NULL,NULL,NULL,NULL);
        如果(光标== NULL){
            返回contentUri.getPath();
        }其他{
            cursor.moveToFirst();
            INT指数= cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA);
            返回cursor.getString(索引);
        }
    }    公众诠释calculateInSampleSize(BitmapFactory.Options选项,诠释reqWidth,诠释reqHeight){
        最终诠释身高= options.outHeight;
        最终诠释宽度= options.outWidth;
        INT inSampleSize = 1;        如果(高度&GT; reqHeight ||宽度GT; reqWidth){
            最终诠释heightRatio = Math.round((浮点)高度/(浮点)reqHeight);
            最终诠释widthRatio = Math.round((浮点)宽/(浮点)reqWidth);
            inSampleSize = heightRatio&LT; widthRatio? heightRatio:widthRatio;
        }
        最终浮动totalPixels =宽*高;
        最终浮动totalReqPixelsCap = reqWidth * reqHeight * 2;
        而(totalPixels /(inSampleSize * inSampleSize)GT; totalReqPixelsCap){
            inSampleSize ++;
        }        返回inSampleSize;
    }    公众的getFileName字符串(字符串ORIGINALNAME){        ImageCache imageCache =新ImageCache(本);
        档案文件=新的文件(您的文件夹路径);        //返回文件;
        串uriSting =(file.getAbsolutePath()+/+F_+ System.currentTimeMillis的()+.PNG);
        返回uriSting;    }

Does anyone know how to scale the bitmap image without losing the image quality ? Currently I facing this problem, where the size of selected image maybe too big caused the app return to another activity.

So now I tried using this method to scale the selected image without losing its quality. I get the code from here.

 protected void onActivityResult(int requestCode, int resultCode,
                                    Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        switch (requestCode) {
            case RESULT_LOAD_IMAGE:
                if (requestCode == RESULT_LOAD_IMAGE && resultCode == RESULT_OK & null != data) {
                    Uri selectedImage = data.getData();
                    String[] filePathColumn = {MediaStore.Images.Media.DATA};
                    Cursor cursor = getContentResolver()
                            .query(selectedImage, filePathColumn, null, null,
                                    null);
                    cursor.moveToFirst();
                    int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
                    String picturePath = cursor.getString(columnIndex);
                    cursor.close();
                    Bitmap a = (BitmapFactory.decodeFile(picturePath));
                    photo = scaleBitmap(a, 200, 200);
                    imageView.setImageBitmap(photo);
                }
                break;
}

  public static Bitmap scaleBitmap(Bitmap bitmap, int newWidth, int newHeight) {
        Bitmap scaledBitmap = Bitmap.createBitmap(newWidth, newHeight, Bitmap.Config.ARGB_8888);

        float scaleX = newWidth / (float) bitmap.getWidth();
        float scaleY = newHeight / (float) bitmap.getHeight();
        float pivotX = 0;
        float pivotY = 0;

        Matrix scaleMatrix = new Matrix();
        scaleMatrix.setScale(scaleX, scaleY, pivotX, pivotY);

        Canvas canvas = new Canvas(scaledBitmap);
        canvas.setMatrix(scaleMatrix);
        canvas.drawBitmap(bitmap, 0, 0, new Paint(Paint.FILTER_BITMAP_FLAG));

        return scaledBitmap;
    }

The answer seems helpful for most of the people, but why it doesn't work for me ? Have I missed anything?

original image

selected image display on imageView

解决方案

Use this it will definitely help you to reduce the size without loosing quality.
public Bitmap compressImage(String imageUri) {

        String filePath = imageUri;
        // String filePath = getRealPathFromURI(imageUri);
        Bitmap scaledBitmap = null;

        BitmapFactory.Options options = new BitmapFactory.Options();

        // by setting this field as true, the actual bitmap pixels are not
        // loaded in the memory. Just the bounds are loaded. If
        // you try the use the bitmap here, you will get null.
        options.inJustDecodeBounds = true;
        Bitmap bmp = BitmapFactory.decodeFile(filePath, options);

        int actualHeight = options.outHeight;
        int actualWidth = options.outWidth;

        // max Height and width values of the compressed image is taken as
        // 816x612

        /*
         * float maxHeight = 816.0f; float maxWidth = 612.0f;
         */
        float maxHeight = 1080.0f;
        float maxWidth = 800.0f;

        float imgRatio = actualWidth / (float) actualHeight;
        float maxRatio = maxWidth / (float) maxHeight;

        // width and height values are set maintaining the aspect ratio of the
        // image

        if (actualHeight > maxHeight || actualWidth > maxWidth) {
            if (imgRatio < maxRatio) {
                imgRatio = maxHeight / actualHeight;
                actualWidth = (int) (imgRatio * actualWidth);
                actualHeight = (int) maxHeight;
            } else if (imgRatio > maxRatio) {
                imgRatio = maxWidth / actualWidth;
                actualHeight = (int) (imgRatio * actualHeight);
                actualWidth = (int) maxWidth;
            } else {
                actualHeight = (int) maxHeight;
                actualWidth = (int) maxWidth;

            }
        }

        // setting inSampleSize value allows to load a scaled down version of
        // the original image

        options.inSampleSize = calculateInSampleSize(options, actualWidth, actualHeight);

        // inJustDecodeBounds set to false to load the actual bitmap
        options.inJustDecodeBounds = false;

        // this options allow android to claim the bitmap memory if it runs low
        // on memory
        options.inPurgeable = true;
        options.inInputShareable = true;
        options.inTempStorage = new byte[16 * 1024];

        try {
            // load the bitmap from its path
            bmp = BitmapFactory.decodeFile(filePath, options);
        } catch (OutOfMemoryError exception) {
            exception.printStackTrace();

        }
        try {
            scaledBitmap = Bitmap.createBitmap(actualWidth, actualHeight, Bitmap.Config.ARGB_8888);
        } catch (OutOfMemoryError exception) {
            exception.printStackTrace();
        }

        float ratioX = actualWidth / (float) options.outWidth;
        float ratioY = actualHeight / (float) options.outHeight;
        float middleX = actualWidth / 2.0f;
        float middleY = actualHeight / 2.0f;

        Matrix scaleMatrix = new Matrix();
        scaleMatrix.setScale(ratioX, ratioY, middleX, middleY);

        Canvas canvas = new Canvas(scaledBitmap);
        canvas.setMatrix(scaleMatrix);
        canvas.drawBitmap(bmp, middleX - bmp.getWidth() / 2, middleY - bmp.getHeight() / 2, new Paint(Paint.FILTER_BITMAP_FLAG));

        // check the rotation of the image and display it properly
        ExifInterface exif;
        try {
            exif = new ExifInterface(filePath);

            int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, 0);
            displayLogs("EXIF", "Exif: " + orientation);
            Matrix matrix = new Matrix();
            if (orientation == 6) {
                matrix.postRotate(90);
                displayLogs("EXIF", "Exif: " + orientation);
            } else if (orientation == 3) {
                matrix.postRotate(180);
                displayLogs("EXIF", "Exif: " + orientation);
            } else if (orientation == 8) {
                matrix.postRotate(270);
                displayLogs("EXIF", "Exif: " + orientation);
            }

            scaledBitmap = Bitmap.createBitmap(scaledBitmap, 0, 0, scaledBitmap.getWidth(), scaledBitmap.getHeight(), matrix, true);
        } catch (IOException e) {
            e.printStackTrace();
        }

        FileOutputStream out = null;
        String filename = getFilename(filePath);
        // File image = new File(getFilename(), System.currentTimeMillis() +
        // ".jpg");
        try {
            out = new FileOutputStream(filename);

            // write the compressed bitmap at the destination specified by
            // filename.
            boolean didWrite = scaledBitmap.compress(Bitmap.CompressFormat.JPEG, 80, out);

            out.close();

            System.out.println(didWrite);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {

            e.printStackTrace();
        }

        return scaledBitmap;

    }

    private String getRealPathFromURI(String contentURI) {
        Uri contentUri = Uri.parse(contentURI);
        Cursor cursor = getContentResolver().query(contentUri, null, null, null, null);
        if (cursor == null) {
            return contentUri.getPath();
        } else {
            cursor.moveToFirst();
            int index = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA);
            return cursor.getString(index);
        }
    }

    public int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {
        final int height = options.outHeight;
        final int width = options.outWidth;
        int inSampleSize = 1;

        if (height > reqHeight || width > reqWidth) {
            final int heightRatio = Math.round((float) height / (float) reqHeight);
            final int widthRatio = Math.round((float) width / (float) reqWidth);
            inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
        }
        final float totalPixels = width * height;
        final float totalReqPixelsCap = reqWidth * reqHeight * 2;
        while (totalPixels / (inSampleSize * inSampleSize) > totalReqPixelsCap) {
            inSampleSize++;
        }

        return inSampleSize;
    }

    public String getFilename(String originalname) {

        ImageCache imageCache = new ImageCache(this);
        File file = new File("Your folder path");

        // return file;
        String uriSting = (file.getAbsolutePath() + "/" + "F_" + System.currentTimeMillis() + ".png");
        return uriSting;

    }

这篇关于缩放图像不会丢失图像质量没有工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆