2011-12-21 3 views
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 точек на дюйм, но и исходный файл = 72 точек на дюйм. Почему это происходит и как это исправить?

ответ

1

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

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

Это не работает. Я получаю тот же результат. –

+0

@sherman это влияет только на плотность пикселей, а не на размер файла. Из документации: «возможно, что возвращаемое растровое изображение из BitmapFactory может быть в другом битовом сигнале и/или может потеряться на пиксель альфа (например, JPEG поддерживает только непрозрачные пиксели)». Кроме того, вы указываете качество '100', что может привести к большему выходу, чем к входу. –

+0

Да, вы правы, но почему плотность не меняется? –

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), где выбирает = нуль
  4. BitmapFactory.decodeStream(stream, null, opts) вызов родной функции bm = nativeDecodeStream(is, tempStorage, outPadding, opts);, а затем вызывает finishDecode(bm, outPadding, opts); Помните, что в нашем случае КЛЮЧ равны нулю.
  5. В finishDecode(bm, outPadding, opts) есть первый чек, который должен вернуть битовую карту без изменений (ОПТС в нашем случае должен быть пустым):

    если (Ьт == NULL || == выбирает NULL) { возврата Ьт; }

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

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