如何在不改变文件大小的情况下旋转位图?

3
我尝试做到这一点:
Bitmap bitmapOrg = BitmapFactory.decodeFile("/sdcard/"+ photoName + ".jpg");

        int width = bitmapOrg.getWidth();
        int height = bitmapOrg.getHeight();

        Matrix matrix = new Matrix();

        matrix.postRotate(90);

        Bitmap resizedBitmap = Bitmap.createBitmap(bitmapOrg, 0, 0, width,
                height, matrix, true);

        FileOutputStream os;
        try {
            os = new FileOutputStream(String.format(
                "/sdcard/" + photoName + "-rotate.jpg",
                    System.currentTimeMillis()));

        resizedBitmap.compress(Bitmap.CompressFormat.JPEG, 100, os);

因为旋转后的文件分辨率=96 dpi,而原始文件为72 dpi,所以旋转后的文件大小>原始文件大小。那么这是为什么呢?如何修复这个问题?

2个回答

1

在我的看法中,另一个可能的解决方案是改变第一行:

Bitmap bitmapOrg = BitmapFactory.decodeFile("/sdcard/"+ photoName + ".jpg");

使用以下代码:

Bitmap bitmapOrg = BitmapFactory.decodeFile("/sdcard/"+ photoName + ".jpg", (new BitmapFactory.Options()).inDensity=0);

但我没有检查过这个解决方案。

此外,我认为您的解决方案也应该有效。我认为AOSP中存在某些错误,因为:

  1. 函数createBitmap(Bitmap source, int x, int y, int width, int height, Matrix m, boolean filter)不会改变文件的密度(bitmap.mDensity = source.mDensity;)。新的密度等于源的密度。因此,在调用此函数之前,似乎已经更改了密度。
  2. BitmapFactory.decodeFile使用参数(pathName, null)调用BitmapFactory.decodeFile
  3. BitmapFactory.decodeFile(pathName, null)将文件转换为流,并调用BitmapFactory.decodeStream(stream, null, opts),其中opts = null
  4. BitmapFactory.decodeStream(stream, null, opts)调用本地函数bm = nativeDecodeStream(is, tempStorage, outPadding, opts);,然后调用finishDecode(bm, outPadding, opts);请记住,在我们的情况下,opts等于null。
  5. finishDecode(bm, outPadding, opts)中,有第一个检查应该返回未更改的位图(在我们的情况下,opts应该为null):

    if (bm == null || opts == null) { return bm; }

  6. 因此,似乎在本地函数nativeDecodeStream(is, tempStorage, outPadding, opts)中发生了一些错误。

需要花费很多时间进一步检查问题所在。而且,我也不确定我的发现是否正确。


1
你可以在FileOutputStream os;之前添加以下行:
resizedBitmap.setDensity(bitmapOrig.getDensity());

@sherman 这只影响像素密度,而不是文件大小。根据文档:“从BitmapFactory返回的位图可能具有不同的位深度和/或可能丢失每个像素的alpha(例如,JPEG仅支持不透明像素)。”此外,您正在指定100的质量,这可能会导致输出比输入更大。 - Chris Cashwell

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接