Как вращать растровое изображение без изменения размера файла? - PullRequest
3 голосов
/ 21 декабря 2011

Я пытаюсь сделать это:

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 голос
/ 21 декабря 2011

Мне кажется, что другим возможным решением является изменение первой строки:

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); Помните, что в нашем случае опции равны нулю.
  5. В finishDecode(bm, outPadding, opts) есть первая проверка, которая должна вернуть битовую карту без изменений (в нашем случае опции должны быть нулевыми):

    if (bm == null || opts == null) { возврат бм; }

  6. Таким образом, кажется, что с опциями в нативной функции произошло нечто плохое: nativeDecodeStream(is, tempStorage, outPadding, opts)

Требуется много времени, чтобы проверить, где проблема. Кроме того, я не уверен, что я прав в своих выводах.

1 голос
/ 21 декабря 2011

Вы можете добавить в следующую строку прямо перед FileOutputStream os;:

resizedBitmap.setDensity(bitmapOrig.getDensity());
...