2016-02-12 11 views
2

Я пытаюсь сжать изображения, выбранные пользователем из галереи для загрузки. Я видел, что мои снимки камеры составляют более 5 МБ, и я хотел бы сжать их (как можно раньше, например, facebook). То, что я пытался:Сжатие изображения перед загрузкой Bitmap.CompressFormat

я позволить пользователю выбрать фотографию из галереи, получить Ури и использовать это:

File file = new File(getRealPathFromURI(getActivity(), selectedImageUri)); 
      long length = file.length(); 
      Log.e("Filesize:", "Before: " + length); 
      if (file.getName().toLowerCase().endsWith("jpg")||file.getName().toLowerCase().endsWith("jpeg")){ 
       Bitmap original; 
       try { 
        original = MediaStore.Images.Media.getBitmap(getActivity().getContentResolver(), selectedImageUri); 
        length = sizeOf(original); 
        Log.e("Filesize:", "BeforeCompression: " + length); 
        ByteArrayOutputStream out = new ByteArrayOutputStream(); 
        original.compress(Bitmap.CompressFormat.JPEG, 50, out); 
        Bitmap decoded = BitmapFactory.decodeStream(new ByteArrayInputStream(out.toByteArray())); 
        length = sizeOf(decoded); 
        Log.e("Filesize:", "AfterCompression: " + length); 
       } catch (IOException e) { 
        e.printStackTrace(); 
        Log.e("Filesize:", "Error: " + e); 
       } 

Я сделал это, чтобы проверить, если он работал первый, но то, что я получаю в консоли:

/name.company.newapp E/Filesize:: Before: 4970874 
/name.company.newapp E/Filesize:: BeforeConversion: 63489024 
/name.company.newapp E/Filesize:: AfterConversion: 63489024 

Размер не меняется вообще. Правильно ли это?

ответ

1

Это происходит потому, что вы фактически получаете размер памяти, используемый объектом Bitmap, вызывая sizeOf (bitmap), а не фактический размер файла.

Как вы знаете, растровое изображение работает с количеством пикселей в изображении. Даже если вы сжимаете изображение с помощью сжатия JPEG, ширина и высота изображения не изменяются. Таким образом, количество пикселей не изменяется, и поэтому размер Bitmap (в памяти) тоже не изменится.

Однако, если вы сохранили сжатое растровое изображение в месте на жестком диске и используете File.length() для вычисления размера сжатого изображения, то вы заметите разницу.

+1

Благодарим вас за ответ. Я понимаю это сейчас. Я думал, что это не работает, но ваш ответ имеет смысл. Могу ли я загрузить его без сохранения в память? –

+0

Ну. Сначала вам нужно загрузить его в память для выполнения сжатия. Затем вы можете напрямую сжать его в файл. Затем вы можете обратиться к файлу. Надеюсь, вы поняли, что я имею в виду. –

+0

Не совсем, у меня не было опыта работы с растровыми изображениями, но я попробую. Спасибо. –

-1

Пожалуйста, проверьте размер перед декодированием и после сжатия:

length = sizeOf(original); 

Также я бы порекомендовал вам очистить и закрыть OutputStream:

out.flush(); 
out.close(); 

Надежда я мог бы помочь!


Edit: Пожалуйста, попробуйте следующий способ для декодирования растрового изображения:

 public static Bitmap decodeFile(File f,int WIDTH,int HEIGHT){ 
    try { 
     BitmapFactory.Options o = new BitmapFactory.Options(); 
     o.inJustDecodeBounds = true; 
     BitmapFactory.decodeStream(new FileInputStream(f),null,o); 

     final int REQUIRED_WIDTH=WIDTH; 
     final int REQUIRED_HEIGHT=HEIGHT; 
     //Find the correct scale value. It should be the power of 2. 
     int scale=1; 
     while(o.outWidth/scale/2>=REQUIRED_WIDTH && o.outHeight/scale/2>=REQUIRED_HEIGHT) 
      scale*=2; 

     BitmapFactory.Options o2 = new BitmapFactory.Options(); 
     o2.inSampleSize=scale; 
     return BitmapFactory.decodeStream(new FileInputStream(f), null, o2); 
    } catch (FileNotFoundException e) {} 
    return null; 
} 

Вы можете изменить ширину и высоту изображения, чтобы сделать его меньше.

+0

Но я делал это. Дело в том, что размер не меняется. –

+0

изменить, я не хочу менять ширину и высоту. В этом весь смысл использования Bitmap.CompressFormat. Пожалуйста, прочтите мой вопрос. –