Android从相机意图压缩小尺寸和高质量的图像

问题描述

在我的应用程序中,用户可以从相机意图拍摄照片,然后我将此图像保存为全尺寸图像 不是缩略图。然后我想要做的是使用这个保存的图像来压缩它并将其发送到服务器。

来自相机意图的图像大小约为 7-8 MB,分辨率为 5664x4248。

要求是40-80KB的whatsapp相同大小和质量的图像

我尝试了不同的解决方案,但无法达到同样好的质量和尺寸。

为此,我使用了 id.zelory:compressor:2.1.1

有什么想法吗?

这里我在保存图片调用这个方法来调整大小

private File customCompressImage (File imgFile) {
    String destinationDirectoryPath=  Environment.getExternalStorageDirectory().getPath() + "/Pictures/";
    try {
        return new CustomCompressor(context)
                 .setMaxWidth(612)
                 .setMaxHeight(816)
                 .setQuality(80)
                 .setCompressFormat(Bitmap.CompressFormat.JPEG)
                 .setDestinationDirectoryPath(destinationDirectoryPath)
                 .compresstoFile(imgFile);
    } catch (IOException e) {
        e.printstacktrace();
    }
    return null;
}

压缩图片

static File compressImage(File imageFile,int reqWidth,int reqHeight,Bitmap.CompressFormat compressFormat,int quality,String destinationPath) throws IOException {
    FileOutputStream fileOutputStream = null;
    File file = new File(destinationPath).getParentFile();
    if (!file.exists()) {
        file.mkdirs();
    }
    try {
        fileOutputStream = new FileOutputStream(destinationPath);
        // write the compressed bitmap at the destination specified by destinationPath.
        decodeSampledBitmapFromFile(imageFile,reqWidth,reqHeight).compress(compressFormat,quality,fileOutputStream);
    } finally {
        if (fileOutputStream != null) {
            fileOutputStream.flush();
            fileOutputStream.close();
        }
    }

    return new File(destinationPath);
}


static Bitmap decodeSampledBitmapFromFile(File imageFile,int reqHeight) throws IOException {
    // First decode with inJustDecodeBounds=true to check dimensions
    BitmapFactory.Options options = new BitmapFactory.Options();
    options.inJustDecodeBounds = true;
    BitmapFactory.decodeFile(imageFile.getAbsolutePath(),options);

    // Calculate inSampleSize
    options.inSampleSize = calculateInSampleSize(options,reqHeight);

    // Decode bitmap with inSampleSize set
    options.inJustDecodeBounds = false;

    Bitmap scaledBitmap = BitmapFactory.decodeFile(imageFile.getAbsolutePath(),options);

    //check the rotation of the image and display it properly
    ExifInterface exif;
    exif = new ExifInterface(imageFile.getAbsolutePath());
    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,scaledBitmap.getWidth(),scaledBitmap.getHeight(),matrix,true);
    return scaledBitmap;
}


private static int calculateInSampleSize(BitmapFactory.Options options,int reqHeight) {
    // Raw height and width of image
    final int height = options.outHeight;
    final int width = options.outWidth;
    int inSampleSize = 1;

    if (height > reqHeight || width > reqWidth) {

        final int halfheight = height / 2;
        final int halfWidth = width / 2;

        // Calculate the largest inSampleSize value that is a power of 2 and keeps both
        // height and width larger than the requested height and width.
        while ((halfheight / inSampleSize) >= reqHeight && (halfWidth / inSampleSize) >= reqWidth) {
            inSampleSize *= 2;
        }
    }

    return inSampleSize;
}

我尝试通过不同的最大宽度和高度以及质量,但我从未实现过小尺寸和高质量

解决方法

你可以试试这段代码。

public static Bitmap getCompressed( Bitmap imageBitmap) {
    ByteArrayOutputStream bytes = new ByteArrayOutputStream();
    imageBitmap.compress(Bitmap.CompressFormat.JPEG,100,bytes);
    return imageBitmap;
}

// 100 是质量, 根据您的需要更改它

,

@End User 不应该是这样的(这至少是我从阅读文档中得到的):

public static Bitmap getCompressed(Bitmap imageBitmap) {
    ByteArrayOutputStream out = new ByteArrayOutputStream();
    if (!imageBitmap.compress(Bitmap.CompressFormat.JPEG,out))
        throw new IllegalStateException("Unable to compress image");
    ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
    return BitmapFactory.decodeStream(in);
}