简体   繁体   English

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

[英]How to rotate bitmap without changing file size?

I try do this: 我试着这样做:

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);

rotated file size > original file size, because rotated file resolution = 96 dpi, but original file = 72 dpi. 旋转文件大小>原始文件大小,因为旋转文件分辨率= 96 dpi,但原始文件= 72 dpi。 Why is this happening and how to fix it? 为什么会发生这种情况以及如何解决?

You could add in the following line right before FileOutputStream os; 您可以在FileOutputStream os;之前添加以下行FileOutputStream os; :

resizedBitmap.setDensity(bitmapOrig.getDensity());

It seems to me that another possible solution is to change the first line: 在我看来,另一种可能的解决方案是改变第一行:

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

With the code: 随着代码:

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

But I did not check this solution. 但我没有检查这个解决方案。

Moreover, it seems to me that your solution should also work. 而且,在我看来,你的解决方案也应该有效。 I think there is somewhere an error in the AOSP, because: 我认为AOSP中存在某个错误,因为:

  1. Function createBitmap(Bitmap source, int x, int y, int width, int height, Matrix m, boolean filter) does not change the density of the file ( bitmap.mDensity = source.mDensity; ) . 函数createBitmap(Bitmap source, int x, int y, int width, int height, Matrix m, boolean filter)不会更改文件的密度( bitmap.mDensity = source.mDensity; )。 New density is equal to density of the source. 新密度等于源密度。 Thus, it seems that the density is changed before this call. 因此,似乎在此呼叫之前密度已经改变。
  2. BitmapFactory.decodeFile calls BitmapFactory.decodeFile with the parameters (pathName, null) BitmapFactory.decodeFile calls BitmapFactory.decodeFile使用参数BitmapFactory.decodeFile calls BitmapFactory.decodeFile (pathName, null)
  3. BitmapFactory.decodeFile(pathName, null) transforms file into the stream and calls BitmapFactory.decodeStream(stream, null, opts) where opts = null BitmapFactory.decodeFile(pathName, null)将文件转换为流并调用BitmapFactory.decodeStream(stream, null, opts) ,其中opts = null
  4. BitmapFactory.decodeStream(stream, null, opts) call native function bm = nativeDecodeStream(is, tempStorage, outPadding, opts); BitmapFactory.decodeStream(stream, null, opts)调用本机函数bm = nativeDecodeStream(is, tempStorage, outPadding, opts); and then calls finishDecode(bm, outPadding, opts); 然后调用finishDecode(bm, outPadding, opts); Remember that in our case opts are equal to null. 请记住,在我们的情况下,opts等于null。
  5. In the finishDecode(bm, outPadding, opts) there is the first check that should return bitmap unchanged (opts in our case should be null): finishDecode(bm, outPadding, opts)中,第一次检查应该返回位图(在我们的例子中opts应该为null):

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

  6. Thus, it seems that something bad has happened with opts in the native function: nativeDecodeStream(is, tempStorage, outPadding, opts) 因此,在本机函数中opts似乎发生了一些不好的事情: nativeDecodeStream(is, tempStorage, outPadding, opts)

It needs a lot of time to check further where the problem is. 需要花费大量时间来进一步检查问题所在。 Also, I'm not sure that I'm right in my findings. 另外,我不确定我的发现是对的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM