Intereting Posts
Метод моментального снимка GoogleMap возвращает белое изображение Масштабирование Bitmapfont в LibGDX Является ли метод onUpgrade когда-либо называемым? Как я могу не допустить, чтобы активность Android вкратце попадала в портретный режим, когда я указал пейзаж? Изменить панель инструментов. Цвет элемента (не скрытое действие). Гибкое пространство в Android Предотвращение автосохранения фотографий в галерее при загрузке фотографий в Android-браузере с использованием типа ввода = захват файла = камера Поддержка Android (cardView, RecyclerView) в старых версиях с целевым Kitkat Алгоритм соответствия шаблону формы в Java Android 5.0 – Анимация домашней иконки AppCompat v7 21 из программы burger to back arrow программно Android CursorLoader Может запустить эмулятор без HAXM в андроид-студии? Android webview cookie возвращает null Как сделать свечение текста? Как предотвратить выбранную дату date в DatePickerDialog (setMinDate не работает должным образом)

Android: изменение размера файла растрового изображения на масштабируемый выходной файл

У меня есть большой битмап (скажем, 3888×2592) в файле. Теперь я хочу изменить размер растрового изображения до 800×533 и сохранить его в другом файле. Я обычно масштабировал растровое изображение, вызывая метод Bitmap.createBitmap но для первого аргумента он должен иметь исходный Bitmap.createBitmap , который я не могу предоставить, потому что загрузка исходного изображения в объект Bitmap будет, конечно, превышать память (см. Здесь , например ).

Я также не могу прочитать растровое изображение с, например, BitmapFactory.decodeFile(file, options) , предоставляя BitmapFactory.Options.inSampleSize , потому что я хочу изменить его размер до точной ширины и высоты. Использование inSampleSize бы размер растрового изображения на 972×648 (если я использую inSampleSize=4 ) или 778×518 (если я использую inSampleSize=5 , который даже не имеет значения 2).

Я также хотел бы избежать прочтения изображения, используя inSampleSize с, например, 972×648 на первом шаге, а затем изменив его размер до 800×533 на втором шаге, потому что качество будет плохой по сравнению с прямым изменением размера исходного изображения.

Подводя итог моему вопросу: есть ли способ прочитать большой файл изображения с 10 или более мегабайтами и сохранить его в новом файле изображения, измененном до определенной ширины и высоты, без получения исключения OutOfMemory?

Я также попробовал BitmapFactory.decodeFile(file, options) и устанавливал значения Options.outHeight и Options.outWidth вручную до 800 и 533, но это не работает.

Solutions Collecting From Web of "Android: изменение размера файла растрового изображения на масштабируемый выходной файл"

Нет. Мне бы хотелось, чтобы кто-то меня исправил, но я принял подход загрузки / изменения размера, который вы пробовали в качестве компромисса.

Вот шаги для тех, кто просматривает:

  1. Вычислите максимально возможное значение в inSampleSize которое по-прежнему дает изображение, большее, чем ваша цель.
  2. Загрузите изображение с помощью BitmapFactory.decodeFile(file, options) , передав параметрSampleSize в качестве опции.
  3. Измените размер до требуемых размеров, используя Bitmap.createScaledBitmap() .

Джастин ответил на перевод в код (отлично работает для меня):

 private Bitmap getBitmap(String path) { Uri uri = getImageUri(path); InputStream in = null; try { final int IMAGE_MAX_SIZE = 1200000; // 1.2MP in = mContentResolver.openInputStream(uri); // Decode image size BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; BitmapFactory.decodeStream(in, null, options); in.close(); int scale = 1; while ((options.outWidth * options.outHeight) * (1 / Math.pow(scale, 2)) > IMAGE_MAX_SIZE) { scale++; } Log.d(TAG, "scale = " + scale + ", orig-width: " + options.outWidth + ", orig-height: " + options.outHeight); Bitmap resultBitmap = null; in = mContentResolver.openInputStream(uri); if (scale > 1) { scale--; // scale to max possible inSampleSize that still yields an image // larger than target options = new BitmapFactory.Options(); options.inSampleSize = scale; resultBitmap = BitmapFactory.decodeStream(in, null, options); // resize to desired dimensions int height = resultBitmap.getHeight(); int width = resultBitmap.getWidth(); Log.d(TAG, "1th scale operation dimenions - width: " + width + ", height: " + height); double y = Math.sqrt(IMAGE_MAX_SIZE / (((double) width) / height)); double x = (y / height) * width; Bitmap scaledBitmap = Bitmap.createScaledBitmap(resultBitmap, (int) x, (int) y, true); resultBitmap.recycle(); resultBitmap = scaledBitmap; System.gc(); } else { resultBitmap = BitmapFactory.decodeStream(in); } in.close(); Log.d(TAG, "bitmap size - width: " +resultBitmap.getWidth() + ", height: " + resultBitmap.getHeight()); return resultBitmap; } catch (IOException e) { Log.e(TAG, e.getMessage(),e); return null; } 

Это «Mojo Risin's и« Офирские решения »вместе взятые». Это даст вам пропорционально измененное изображение с границами максимальной ширины и максимальной высоты.

  1. Он только считывает метаданные, чтобы получить исходный размер (options.inJustDecodeBounds)
  2. Он использует грубое изменение размера для сохранения памяти (itmap.createScaledBitmap)
  3. Он использует точно измененное изображение на основе грубого бита, созданного ранее.

Для меня он отлично работает на 5 MegaPixel изображениях ниже.

 try { int inWidth = 0; int inHeight = 0; InputStream in = new FileInputStream(pathOfInputImage); // decode image size (decode metadata only, not the whole image) BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; BitmapFactory.decodeStream(in, null, options); in.close(); in = null; // save width and height inWidth = options.outWidth; inHeight = options.outHeight; // decode full image pre-resized in = new FileInputStream(pathOfInputImage); options = new BitmapFactory.Options(); // calc rought re-size (this is no exact resize) options.inSampleSize = Math.max(inWidth/dstWidth, inHeight/dstHeight); // decode full image Bitmap roughBitmap = BitmapFactory.decodeStream(in, null, options); // calc exact destination size Matrix m = new Matrix(); RectF inRect = new RectF(0, 0, roughBitmap.getWidth(), roughBitmap.getHeight()); RectF outRect = new RectF(0, 0, dstWidth, dstHeight); m.setRectToRect(inRect, outRect, Matrix.ScaleToFit.CENTER); float[] values = new float[9]; m.getValues(values); // resize bitmap Bitmap resizedBitmap = Bitmap.createScaledBitmap(roughBitmap, (int) (roughBitmap.getWidth() * values[0]), (int) (roughBitmap.getHeight() * values[4]), true); // save image try { FileOutputStream out = new FileOutputStream(pathOfOutputImage); resizedBitmap.compress(Bitmap.CompressFormat.JPEG, 80, out); } catch (Exception e) { Log.e("Image", e.getMessage(), e); } } catch (IOException e) { Log.e("Image", e.getMessage(), e); } 

Почему бы не использовать API?

 int h = 48; // height in pixels int w = 48; // width in pixels Bitmap scaled = Bitmap.createScaledBitmap(largeBitmap, w, h, true); 

Подтверждая еще один отличный ответ, лучший код, который я видел еще для этого, содержится в документации для инструмента для съемки фотографий.

См. Раздел «Декодировать масштабированное изображение».

http://developer.android.com/training/camera/photobasics.html

Решение, которое оно предлагает, представляет собой масштабирование, а затем масштабируемое решение, как и другие, но это довольно аккуратно.

Для удобства я скопировал код ниже как готовую к работе функцию.

 private void setPic(String imagePath, ImageView destination) { int targetW = destination.getWidth(); int targetH = destination.getHeight(); // Get the dimensions of the bitmap BitmapFactory.Options bmOptions = new BitmapFactory.Options(); bmOptions.inJustDecodeBounds = true; BitmapFactory.decodeFile(imagePath, bmOptions); int photoW = bmOptions.outWidth; int photoH = bmOptions.outHeight; // Determine how much to scale down the image int scaleFactor = Math.min(photoW/targetW, photoH/targetH); // Decode the image file into a Bitmap sized to fill the View bmOptions.inJustDecodeBounds = false; bmOptions.inSampleSize = scaleFactor; bmOptions.inPurgeable = true; Bitmap bitmap = BitmapFactory.decodeFile(imagePath, bmOptions); destination.setImageBitmap(bitmap); } 

После прочтения этих ответов и документации для Android вот код для изменения размера растрового изображения без его загрузки в память:

 public Bitmap getResizedBitmap(int targetW, int targetH, String imagePath) { // Get the dimensions of the bitmap BitmapFactory.Options bmOptions = new BitmapFactory.Options(); //inJustDecodeBounds = true <-- will not load the bitmap into memory bmOptions.inJustDecodeBounds = true; BitmapFactory.decodeFile(imagePath, bmOptions); int photoW = bmOptions.outWidth; int photoH = bmOptions.outHeight; // Determine how much to scale down the image int scaleFactor = Math.min(photoW/targetW, photoH/targetH); // Decode the image file into a Bitmap sized to fill the View bmOptions.inJustDecodeBounds = false; bmOptions.inSampleSize = scaleFactor; bmOptions.inPurgeable = true; Bitmap bitmap = BitmapFactory.decodeFile(imagePath, bmOptions); return(bitmap); } 

Когда у меня есть большие растровые изображения, и я хочу их декодировать, я использую следующие

 BitmapFactory.Options options = new BitmapFactory.Options(); InputStream is = null; is = new FileInputStream(path_to_file); BitmapFactory.decodeStream(is,null,options); is.close(); is = new FileInputStream(path_to_file); // here w and h are the desired width and height options.inSampleSize = Math.max(options.outWidth/w, options.outHeight/h); // bitmap is the resized bitmap Bitmap bitmap = BitmapFactory.decodeStream(is,null,options); 

Это может быть полезно для кого-то другого, рассматривающего этот вопрос. Я переписал код Justin, чтобы позволить методу получать требуемый объект размера цели. Это очень хорошо работает при использовании Canvas. Весь кредит должен пойти в JUSTIN за его отличный исходный код.

  private Bitmap getBitmap(int path, Canvas canvas) { Resources resource = null; try { final int IMAGE_MAX_SIZE = 1200000; // 1.2MP resource = getResources(); // Decode image size BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; BitmapFactory.decodeResource(resource, path, options); int scale = 1; while ((options.outWidth * options.outHeight) * (1 / Math.pow(scale, 2)) > IMAGE_MAX_SIZE) { scale++; } Log.d("TAG", "scale = " + scale + ", orig-width: " + options.outWidth + ", orig-height: " + options.outHeight); Bitmap pic = null; if (scale > 1) { scale--; // scale to max possible inSampleSize that still yields an image // larger than target options = new BitmapFactory.Options(); options.inSampleSize = scale; pic = BitmapFactory.decodeResource(resource, path, options); // resize to desired dimensions int height = canvas.getHeight(); int width = canvas.getWidth(); Log.d("TAG", "1th scale operation dimenions - width: " + width + ", height: " + height); double y = Math.sqrt(IMAGE_MAX_SIZE / (((double) width) / height)); double x = (y / height) * width; Bitmap scaledBitmap = Bitmap.createScaledBitmap(pic, (int) x, (int) y, true); pic.recycle(); pic = scaledBitmap; System.gc(); } else { pic = BitmapFactory.decodeResource(resource, path); } Log.d("TAG", "bitmap size - width: " +pic.getWidth() + ", height: " + pic.getHeight()); return pic; } catch (Exception e) { Log.e("TAG", e.getMessage(),e); return null; } } 

Код Justin очень эффективен для сокращения накладных расходов при работе с большими растровыми изображениями.

Я не знаю, является ли мое решение лучшей практикой, но я достиг загрузки растрового изображения с желаемым масштабированием, используя параметры inDensity и inTargetDensity . inDensity = 0 вначале, когда не загружается ресурс с возможностью рисования, поэтому этот подход предназначен для загрузки изображений без ресурсов.

Переменные imageUri , maxImageSideLength и context являются параметрами моего метода. Для ясности я опубликовал только реализацию метода без обертывания AsyncTask.

  ContentResolver resolver = context.getContentResolver(); InputStream is; try { is = resolver.openInputStream(imageUri); } catch (FileNotFoundException e) { Log.e(TAG, "Image not found.", e); return null; } Options opts = new Options(); opts.inJustDecodeBounds = true; BitmapFactory.decodeStream(is, null, opts); // scale the image float maxSideLength = maxImageSideLength; float scaleFactor = Math.min(maxSideLength / opts.outWidth, maxSideLength / opts.outHeight); // do not upscale! if (scaleFactor < 1) { opts.inDensity = 10000; opts.inTargetDensity = (int) ((float) opts.inDensity * scaleFactor); } opts.inJustDecodeBounds = false; try { is.close(); } catch (IOException e) { // ignore } try { is = resolver.openInputStream(imageUri); } catch (FileNotFoundException e) { Log.e(TAG, "Image not found.", e); return null; } Bitmap bitmap = BitmapFactory.decodeStream(is, null, opts); try { is.close(); } catch (IOException e) { // ignore } return bitmap; 

Принимая во внимание, что вы хотите изменить размер до нужного размера и хотите сохранить как можно больше качества, я думаю, вы должны попробовать это.

  1. Узнайте размер измененного изображения с вызовом BitmapFactory.decodeFile и предоставив checkSizeOptions.inJustDecodeBounds
  2. Вычислите максимально возможный параметрSampleSize, который вы можете использовать на своем устройстве, чтобы не превышать память. BitmapSizeInBytes = 2 * width * height; Как правило, для вашей картинки вSampleSize = 2 было бы хорошо, так как вам понадобится только 2 * 1944×1296) = 4.8Mbб, который должен иметь ножки в памяти
  3. Используйте BitmapFactory.decodeFile с inSampleSize для загрузки Bitmap
  4. Масштабируйте растровое изображение до точного размера.

Мотивация: масштабирование с несколькими шагами может дать вам изображение более высокого качества, однако нет гарантии, что он будет работать лучше, чем использование high inSampleSize. На самом деле, я думаю, что вы также можете использовать inSampleSize, например 5 (не pow of 2), чтобы иметь прямое масштабирование в одной операции. Или просто используйте 4, а затем вы можете просто использовать это изображение в пользовательском интерфейсе. Если вы отправляете его на сервер, – вы можете делать масштабирование до точного размера на стороне сервера, что позволяет использовать расширенные методы масштабирования.

Примечания: если битмап, загруженный на этапе 3, по крайней мере в 4 раза больше (так что 4 * targetWidth <ширина), вы, вероятно, можете использовать несколько размеров для достижения лучшего качества. По крайней мере, что работает в общей java, в android у вас нет возможности указать интерполяцию, используемую для масштабирования http://today.java.net/pub/a/today/2007/04/03/perils-of- изображения getscaledinstance.html

Я использовал такой код:

  String filePath=Environment.getExternalStorageDirectory()+"/test_image.jpg"; BitmapFactory.Options options=new BitmapFactory.Options(); InputStream is=new FileInputStream(filePath); BitmapFactory.decodeStream(is, null, options); is.close(); is=new FileInputStream(filePath); // here w and h are the desired width and height options.inSampleSize=Math.max(options.outWidth/460, options.outHeight/288); //Max 460 x 288 is my desired... // bmp is the resized bitmap Bitmap bmp=BitmapFactory.decodeStream(is, null, options); is.close(); Log.d(Constants.TAG, "Scaled bitmap bytes, "+bmp.getRowBytes()+", width:"+bmp.getWidth()+", height:"+bmp.getHeight()); 

Я пробовал оригинальное изображение 1230 х 1230, и получил битмап говорит 330 х 330.
И если вы попробовали 2590 x 3849, я получим OutOfMemoryError.

Я проследил его, он по-прежнему бросает OutOfMemoryError в строке «BitmapFactory.decodeStream (is, null, options);», если исходное растровое изображение слишком велико …

Выше код сделал немного чище. InputStreams наконец закрывают упаковку, чтобы гарантировать, что они также закрываются:

*Заметка
Вход: InputStream is, int w, int h
Выход: растровое изображение

  try { final int inWidth; final int inHeight; final File tempFile = new File(temp, System.currentTimeMillis() + is.toString() + ".temp"); { final FileOutputStream tempOut = new FileOutputStream(tempFile); StreamUtil.copyTo(is, tempOut); tempOut.close(); } { final InputStream in = new FileInputStream(tempFile); final BitmapFactory.Options options = new BitmapFactory.Options(); try { // decode image size (decode metadata only, not the whole image) options.inJustDecodeBounds = true; BitmapFactory.decodeStream(in, null, options); } finally { in.close(); } // save width and height inWidth = options.outWidth; inHeight = options.outHeight; } final Bitmap roughBitmap; { // decode full image pre-resized final InputStream in = new FileInputStream(tempFile); try { final BitmapFactory.Options options = new BitmapFactory.Options(); // calc rought re-size (this is no exact resize) options.inSampleSize = Math.max(inWidth/w, inHeight/h); // decode full image roughBitmap = BitmapFactory.decodeStream(in, null, options); } finally { in.close(); } tempFile.delete(); } float[] values = new float[9]; { // calc exact destination size Matrix m = new Matrix(); RectF inRect = new RectF(0, 0, roughBitmap.getWidth(), roughBitmap.getHeight()); RectF outRect = new RectF(0, 0, w, h); m.setRectToRect(inRect, outRect, Matrix.ScaleToFit.CENTER); m.getValues(values); } // resize bitmap final Bitmap resizedBitmap = Bitmap.createScaledBitmap(roughBitmap, (int) (roughBitmap.getWidth() * values[0]), (int) (roughBitmap.getHeight() * values[4]), true); return resizedBitmap; } catch (IOException e) { logger.error("Error:" , e); throw new ResourceException("could not create bitmap"); } 

Чтобы масштабировать изображение «правильным» способом, не пропуская ни одного пикселя, вам нужно будет подключиться к декодеру изображения, чтобы выполнить последовательную выборку по строке. Android (и библиотека Skia, которая лежит в основе этого) не предоставляет таких крючков, поэтому вам придется сворачивать самостоятельно. Предполагая, что вы говорите о jpeg-изображениях, лучше всего использовать libjpeg напрямую, на C.

Учитывая сложности, связанные с использованием двухступенчатой ​​подвыборки, а затем-масштабирования, вероятно, лучше всего подходит для приложений типа просмотра изображений.

Вот статья, в которой используется другой подход к изменению размера. Он попытается загрузить максимально возможное растровое изображение в память на основе доступной памяти в процессе и затем выполнить преобразования.

http://bricolsoftconsulting.com/2012/12/07/handling-large-images-on-android/

Если вы абсолютно хотите сделать одно изменение размера, вы, вероятно, можете загрузить всю растровую карту, если андроид: largeHeap = true, но, как вы видите, это не рекомендуется.

Из документов: android: largeHeap Должны ли быть созданы процессы вашего приложения с большой кучей Dalvik. Это относится ко всем процессам, созданным для приложения. Он применяется только к первому приложению, загружаемому в процесс; Если вы используете общий идентификатор пользователя, чтобы позволить нескольким приложениям использовать процесс, все они должны использовать этот параметр последовательно или у них будут непредсказуемые результаты. Большинство приложений не должны этого нуждаться и вместо этого должны сосредоточиться на сокращении общего использования памяти для повышения производительности. Включение этого также не гарантирует фиксированного увеличения доступной памяти, поскольку некоторые устройства ограничены их общей доступной памятью.

Об этой точной проблеме на веб-сайте разработчика Android есть замечательная статья: Эффективная загрузка больших растровых изображений

Это сработало для меня. Функция получает путь к файлу на SD-карте и возвращает битмап в максимальном отображаемом размере. Код из Ofir с некоторыми изменениями, такими как файл изображения на sd, вместо Ressource, а witdth и heigth – из Display Object.

 private Bitmap makeBitmap(String path) { try { final int IMAGE_MAX_SIZE = 1200000; // 1.2MP //resource = getResources(); // Decode image size BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; BitmapFactory.decodeFile(path, options); int scale = 1; while ((options.outWidth * options.outHeight) * (1 / Math.pow(scale, 2)) > IMAGE_MAX_SIZE) { scale++; } Log.d("TAG", "scale = " + scale + ", orig-width: " + options.outWidth + ", orig-height: " + options.outHeight); Bitmap pic = null; if (scale > 1) { scale--; // scale to max possible inSampleSize that still yields an image // larger than target options = new BitmapFactory.Options(); options.inSampleSize = scale; pic = BitmapFactory.decodeFile(path, options); // resize to desired dimensions Display display = getWindowManager().getDefaultDisplay(); Point size = new Point(); display.getSize(size); int width = size.y; int height = size.x; //int height = imageView.getHeight(); //int width = imageView.getWidth(); Log.d("TAG", "1th scale operation dimenions - width: " + width + ", height: " + height); double y = Math.sqrt(IMAGE_MAX_SIZE / (((double) width) / height)); double x = (y / height) * width; Bitmap scaledBitmap = Bitmap.createScaledBitmap(pic, (int) x, (int) y, true); pic.recycle(); pic = scaledBitmap; System.gc(); } else { pic = BitmapFactory.decodeFile(path); } Log.d("TAG", "bitmap size - width: " +pic.getWidth() + ", height: " + pic.getHeight()); return pic; } catch (Exception e) { Log.e("TAG", e.getMessage(),e); return null; } } 
  Bitmap yourBitmap; Bitmap resized = Bitmap.createScaledBitmap(yourBitmap, newWidth, newHeight, true); 

или:

  resized = Bitmap.createScaledBitmap(yourBitmap,(int)(yourBitmap.getWidth()*0.8), (int)(yourBitmap.getHeight()*0.8), true); 

Вот код, который я использую, который не имеет проблем с декодированием больших изображений в памяти на Android. Я смог декодировать изображения размером более 20 МБ, пока мои входные параметры составляют около 1024х1024. Вы можете сохранить возвращенное растровое изображение в другой файл. Ниже этот метод является другим методом, который я также использую для масштабирования изображений в новом растровом изображении. Не стесняйтесь использовать этот код по своему усмотрению.

 /***************************************************************************** * public decode - decode the image into a Bitmap * * @param xyDimension * - The max XY Dimension before the image is scaled down - XY = * 1080x1080 and Image = 2000x2000 image will be scaled down to a * value equal or less then set value. * @param bitmapConfig * - Bitmap.Config Valid values = ( Bitmap.Config.ARGB_4444, * Bitmap.Config.RGB_565, Bitmap.Config.ARGB_8888 ) * * @return Bitmap - Image - a value of "null" if there is an issue decoding * image dimension * * @throws FileNotFoundException * - If the image has been removed while this operation is * taking place */ public Bitmap decode( int xyDimension, Bitmap.Config bitmapConfig ) throws FileNotFoundException { // The Bitmap to return given a Uri to a file Bitmap bitmap = null; File file = null; FileInputStream fis = null; InputStream in = null; // Try to decode the Uri try { // Initialize scale to no real scaling factor double scale = 1; // Get FileInputStream to get a FileDescriptor file = new File( this.imageUri.getPath() ); fis = new FileInputStream( file ); FileDescriptor fd = fis.getFD(); // Get a BitmapFactory Options object BitmapFactory.Options o = new BitmapFactory.Options(); // Decode only the image size o.inJustDecodeBounds = true; o.inPreferredConfig = bitmapConfig; // Decode to get Width & Height of image only BitmapFactory.decodeFileDescriptor( fd, null, o ); BitmapFactory.decodeStream( null ); if( o.outHeight > xyDimension || o.outWidth > xyDimension ) { // Change the scale if the image is larger then desired image // max size scale = Math.pow( 2, (int) Math.round( Math.log( xyDimension / (double) Math.max( o.outHeight, o.outWidth ) ) / Math.log( 0.5 ) ) ); } // Decode with inSampleSize scale will either be 1 or calculated value o.inJustDecodeBounds = false; o.inSampleSize = (int) scale; // Decode the Uri for real with the inSampleSize in = new BufferedInputStream( fis ); bitmap = BitmapFactory.decodeStream( in, null, o ); } catch( OutOfMemoryError e ) { Log.e( DEBUG_TAG, "decode : OutOfMemoryError" ); e.printStackTrace(); } catch( NullPointerException e ) { Log.e( DEBUG_TAG, "decode : NullPointerException" ); e.printStackTrace(); } catch( RuntimeException e ) { Log.e( DEBUG_TAG, "decode : RuntimeException" ); e.printStackTrace(); } catch( FileNotFoundException e ) { Log.e( DEBUG_TAG, "decode : FileNotFoundException" ); e.printStackTrace(); } catch( IOException e ) { Log.e( DEBUG_TAG, "decode : IOException" ); e.printStackTrace(); } // Save memory file = null; fis = null; in = null; return bitmap; } // decode 

ПРИМЕЧАНИЕ. Методы не имеют ничего общего друг с другом, кроме описанного выше метода декодирования createScaledBitmap. Ширина и высота записи могут меняться от исходного изображения.

 /***************************************************************************** * public createScaledBitmap - Creates a new bitmap, scaled from an existing * bitmap. * * @param dstWidth * - Scale the width to this dimension * @param dstHeight * - Scale the height to this dimension * @param xyDimension * - The max XY Dimension before the original image is scaled * down - XY = 1080x1080 and Image = 2000x2000 image will be * scaled down to a value equal or less then set value. * @param bitmapConfig * - Bitmap.Config Valid values = ( Bitmap.Config.ARGB_4444, * Bitmap.Config.RGB_565, Bitmap.Config.ARGB_8888 ) * * @return Bitmap - Image scaled - a value of "null" if there is an issue * */ public Bitmap createScaledBitmap( int dstWidth, int dstHeight, int xyDimension, Bitmap.Config bitmapConfig ) { Bitmap scaledBitmap = null; try { Bitmap bitmap = this.decode( xyDimension, bitmapConfig ); // Create an empty Bitmap which will contain the new scaled bitmap // This scaled bitmap should be the size we want to scale the // original bitmap too scaledBitmap = Bitmap.createBitmap( dstWidth, dstHeight, bitmapConfig ); float ratioX = dstWidth / (float) bitmap.getWidth(); float ratioY = dstHeight / (float) bitmap.getHeight(); float middleX = dstWidth / 2.0f; float middleY = dstHeight / 2.0f; // Used to for scaling the image Matrix scaleMatrix = new Matrix(); scaleMatrix.setScale( ratioX, ratioY, middleX, middleY ); // Used to do the work of scaling Canvas canvas = new Canvas( scaledBitmap ); canvas.setMatrix( scaleMatrix ); canvas.drawBitmap( bitmap, middleX - bitmap.getWidth() / 2, middleY - bitmap.getHeight() / 2, new Paint( Paint.FILTER_BITMAP_FLAG ) ); } catch( IllegalArgumentException e ) { Log.e( DEBUG_TAG, "createScaledBitmap : IllegalArgumentException" ); e.printStackTrace(); } catch( NullPointerException e ) { Log.e( DEBUG_TAG, "createScaledBitmap : NullPointerException" ); e.printStackTrace(); } catch( FileNotFoundException e ) { Log.e( DEBUG_TAG, "createScaledBitmap : FileNotFoundException" ); e.printStackTrace(); } return scaledBitmap; } // End createScaledBitmap 

Измените размер растрового изображения, используя следующий код

  public static Bitmap decodeFile(File file, int reqWidth, int reqHeight){ // First decode with inJustDecodeBounds=true to check dimensions final BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; BitmapFactory.decodeFile(file.getPath(), options); // Calculate inSampleSize options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight); // Decode bitmap with inSampleSize set options.inJustDecodeBounds = false; return BitmapFactory.decodeFile(file.getPath(), options); } private static int calculateInSampleSize( BitmapFactory.Options options, int reqWidth, int reqHeight) { // Raw height and width of image final int height = options.outHeight; final int width = options.outWidth; int inSampleSize = 1; if (height > reqHeight || width > reqWidth) { // Calculate ratios of height and width to requested height and width final int heightRatio = Math.round((float) height / (float) reqHeight); final int widthRatio = Math.round((float) width / (float) reqWidth); // Choose the smallest ratio as inSampleSize value, this will guarantee // a final image with both dimensions larger than or equal to the // requested height and width. inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio; } return inSampleSize; } 

То же самое объясняется в следующем совете / трюке

http://www.codeproject.com/Tips/625810/Android-Image-Operations-Using-BitmapFactory