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

时间:2011-12-21 16:18:14

标签: android bitmap compression

我尝试这样做:

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 个答案:

答案 0 :(得分:1)

您可以在FileOutputStream os;之前添加以下行:

resizedBitmap.setDensity(bitmapOrig.getDensity());

答案 1 :(得分: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 calls BitmapFactory.decodeFile参数(pathName, null)
  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){             返回bm; }

  6. 因此,本机函数中的opts似乎发生了一些不好的事情:nativeDecodeStream(is, tempStorage, outPadding, opts)

  7. 需要花费大量时间来进一步检查问题所在。另外,我不确定我的发现是否正确。