【问题标题】:Image compression after selecting an image from gallery into an ImageView从图库中选择图像到 ImageView 后的图像压缩
【发布时间】:2017-01-05 20:03:36
【问题描述】:

我一直在搜索图像压缩,我发现这个有用的链接是类似whatsapp 的压缩示例http://grishma102.blogspot.ug/2016/03/image-compression-in-android.html,并在同一问题上阅读了不同的帖子,例如How whatsapp/Instagram or other compresses the image before uploading it to server?,但我未能实现我想要的。

我的成就是:-

  1. 我希望当我从图库中选择一张图片时,它会在已压缩的情况下将其自身附加到 ImageView 上。

我就是这样做的

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


    if (requestCode == PICK_IMAGE_REQUEST && resultCode == RESULT_OK) {
        if (data == null) {
            //showError("Failed to open picture!");
            return;
        }
        try {

            imageUri = data.getData();
            compressImage(imageUri.toString());
            Picasso.with(c).load(imageUri).fit().into(imageSelect);


        } catch (Exception e) {

            e.printStackTrace();
        }
    }
}

当然还有compressImage()方法,如下我从我发布的链接中得到的,

  public static String compressImage(String imagePath) {
    Bitmap scaledBitmap = null;
    BitmapFactory.Options options = new BitmapFactory.Options();
    options.inJustDecodeBounds = true;
    Bitmap bmp = BitmapFactory.decodeFile(imagePath, options);

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

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

    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;
        }
    }
    options.inSampleSize = calculateInSampleSize(options, actualWidth, actualHeight);
    options.inJustDecodeBounds = false;
    options.inDither = false;
    options.inPurgeable = true;
    options.inInputShareable = true;
    options.inTempStorage = new byte[16 * 1024];
    try {
        bmp = BitmapFactory.decodeFile(imagePath, options);
    } catch (OutOfMemoryError exception) {
        exception.printStackTrace();
    }
    try {
        scaledBitmap = Bitmap.createBitmap(actualWidth, actualHeight, Bitmap.Config.RGB_565);
    } 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));
    if (bmp != null) {
        bmp.recycle();
    }
    ExifInterface exif;
    try {
        exif = new ExifInterface(imagePath);
        int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, 0);
        Matrix matrix = new Matrix();
        if (orientation == 6) {
            matrix.postRotate(90);
        } else if (orientation == 3) {
            matrix.postRotate(180);
        } else if (orientation == 8) {
            matrix.postRotate(270);
        }
        scaledBitmap = Bitmap.createBitmap(scaledBitmap, 0, 0, scaledBitmap.getWidth(), scaledBitmap.getHeight(), matrix, true);
    } catch (IOException e) {
        e.printStackTrace();
    }
    FileOutputStream out = null;
    String filepath = getFilename();
    try {
        //new File(imageFilePath).delete();
        out = new FileOutputStream(filepath);

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

    } catch (FileNotFoundException e) {
        e.printStackTrace();
    }

    return filepath;
}

public static String getFilename() {
    File mediaStorageDir = new File(Environment.getExternalStorageDirectory()
            + "/ImageCompApp/Images");

    // Create the storage directory if it does not exist
    if (!mediaStorageDir.exists()) {
        mediaStorageDir.mkdirs();
    }

    String mImageName = "IMG_" + String.valueOf(System.currentTimeMillis()) + ".jpg";
    String uriString = (mediaStorageDir.getAbsolutePath() + "/" + mImageName);
    return uriString;
}

public static void hideKeyboard(Activity context) {
    try {
        if (context == null) return;
        InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
        imm.hideSoftInputFromWindow(context.getWindow().getCurrentFocus().getWindowToken(), 0);
    } catch (Exception e) {
    }
}

但它并没有按照预期的方式工作,请问我哪里错了

【问题讨论】:

    标签: java android imageview


    【解决方案1】:

    试试这个代码:

     public String compressImage(String 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 = 500.0f;
            float maxWidth = 500.0f;
            float imgRatio = actualWidth / actualHeight;
            float maxRatio = maxWidth / 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);
                Log.d("EXIF", "Exif: " + orientation);
                Matrix matrix = new Matrix();
                if (orientation == 6) {
                    matrix.postRotate(90);
                    Log.d("EXIF", "Exif: " + orientation);
                } else if (orientation == 3) {
                    matrix.postRotate(180);
                    Log.d("EXIF", "Exif: " + orientation);
                } else if (orientation == 8) {
                    matrix.postRotate(270);
                    Log.d("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();
            try {
                out = new FileOutputStream(filename);
    
    //          write the compressed bitmap at the destination specified by filename.
                scaledBitmap.compress(Bitmap.CompressFormat.JPEG, 80, out);
    
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }
    
            return filename;
    
        }
    
        public String getFilename() {
            File file = new File(Environment.getExternalStorageDirectory().getPath(), "MyFolder/Images");
            if (!file.exists()) {
                file.mkdirs();
            }
            String uriSting = (file.getAbsolutePath() + "/" + System.currentTimeMillis() + ".jpg");
            return uriSting;
    
        }
    
        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;
        }
    

    上面的代码用于在保持纵横比的情况下减小图像的大小。

    source

    希望对你有帮助..

    【讨论】:

    • 感谢@rafsanahmad,但它是否保持图像质量,这是我的主要精髓
    • 因为我想要的是,在将图像附加到 inageView 之后,当它已经被压缩时,我将它发送到服务器
    • 所以你想调整和缩放位图而不损失它的质量...?
    • 是的,类似whatsapp之类的压缩方式,我知道图片会损失质量,但是whatsapp之类的压缩在损失质量方面有一点变化,眼睛都看不到
    • @rafsanahmad007,感谢您的编辑,但这是我已经在使用的方法,请仔细阅读我的问题。谢谢
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-08
    相关资源
    最近更新 更多