Android - 减小图像文件大小

标签 android bitmap image-uploading image-resizing

我有一个 URI 图像文件,我想减小它的大小来上传它。初始图像文件大小取决于移动设备(可以是 2MB,也可以是 500KB),但我希望最终大小为 200KB 左右,以便上传。
根据我的阅读,我有(至少)两个选择:

  • 使用BitmapFactory.Options.inSampleSize,对原图进行二次采样,得到更小的图像;
  • 使用Bitmap.compress来压缩指定压缩质量的图片。

什么是最好的选择?


我正在考虑最初调整图像宽度/高度的大小,直到宽度或高度超过 1000 像素(例如 1024x768 或其他),然后以降低的质量压缩图像,直到文件大小超过 200KB。下面是一个例子:

int MAX_IMAGE_SIZE = 200 * 1024; // max final file size
Bitmap bmpPic = BitmapFactory.decodeFile(fileUri.getPath());
if ((bmpPic.getWidth() >= 1024) && (bmpPic.getHeight() >= 1024)) {
    BitmapFactory.Options bmpOptions = new BitmapFactory.Options();
    bmpOptions.inSampleSize = 1;
    while ((bmpPic.getWidth() >= 1024) && (bmpPic.getHeight() >= 1024)) {
        bmpOptions.inSampleSize++;
        bmpPic = BitmapFactory.decodeFile(fileUri.getPath(), bmpOptions);
    }
    Log.d(TAG, "Resize: " + bmpOptions.inSampleSize);
}
int compressQuality = 104; // quality decreasing by 5 every loop. (start from 99)
int streamLength = MAX_IMAGE_SIZE;
while (streamLength >= MAX_IMAGE_SIZE) {
    ByteArrayOutputStream bmpStream = new ByteArrayOutputStream();
    compressQuality -= 5;
    Log.d(TAG, "Quality: " + compressQuality);
    bmpPic.compress(Bitmap.CompressFormat.JPEG, compressQuality, bmpStream);
    byte[] bmpPicByteArray = bmpStream.toByteArray();
    streamLength = bmpPicByteArray.length;
    Log.d(TAG, "Size: " + streamLength);
}
try {
    FileOutputStream bmpFile = new FileOutputStream(finalPath);
    bmpPic.compress(Bitmap.CompressFormat.JPEG, compressQuality, bmpFile);
    bmpFile.flush();
    bmpFile.close();
} catch (Exception e) {
    Log.e(TAG, "Error on saving file");
}

有没有更好的方法呢?我应该尝试继续使用所有两种方法还是只使用一种?谢谢

最佳答案

使用 Bitmap.compress() 您只需指定压缩算法,顺便说一下压缩操作需要相当长的时间。如果您需要使用大小来减少图像的内存分配,您确实需要使用 Bitmap.Options 来缩放图像,首先计算位图边界,然后将其解码为您指定的大小。

我在 StackOverflow 上找到的最佳示例是 this one .

关于Android - 减小图像文件大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11061280/

相关文章:

android - 如何在 Android 中获得工作的垂直 SeekBar?

android - kotlin 绑定(bind)类引用和泛型

android - 如何将位图图像从 Activity 传输到 Fragment

ios - 为什么文件名会在 alamo fire 在 swift 3 中上传图像时返回 nil?

java - YouTubeFragmentPlayer Android 应用程序 - 仅出现黑框

android - Activity <Name> 泄露了最初绑定(bind)在这里的 ServiceConnection com.google.android.vending.licensing.LicenseChecker

node.js - 无法将图像文件上传到 PUBLISHED node.acs 应用程序

javascript - 从 div 中删除预览图像

android - 如何将 ScrollView 中的所有内容转换为位图?

c# - 从 C# 中的位图创建位图的全新副本