BitmapFactory.decodeFile из памяти с изображениями 2400×2400

Мне нужно отправить изображение из файла на сервер. Сервер запрашивает изображение в разрешении 2400×2400.

То, что я пытаюсь сделать, это:

1) Получите растровое изображение, используя BitmapFactory.decodeFile, используя правильный inSampleSize.

2) Сжатие изображения в формате JPEG с качеством 40%

3) Кодировать изображение в base64

4) Отправлено на сервер

Я не могу добиться первого шага, он выдает исключение из памяти. Я уверен, что inSampleSize верен, но я полагаю, что даже с inSampleSize битмап огромен (около 30 МБ в DDMS).

Любые идеи, как это сделать? Могу ли я выполнить эти действия без создания растрового объекта? Я имею в виду делать это в файловой системе вместо RAM-памяти.

Это текущий код:

// The following function calculate the correct inSampleSize Bitmap image = Util.decodeSampledBitmapFromFile(imagePath, width,height); // compressing the image ByteArrayOutputStream baos = new ByteArrayOutputStream(); image.compress(Bitmap.CompressFormat.JPEG, 40, baos); // encode image String encodedImage = Base64.encodeToString(baos.toByteArray(),Base64.DEFAULT)); public 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; } public static Bitmap decodeSampledBitmapFromFile(String path,int reqWidth, int reqHeight) { // First decode with inJustDecodeBounds=true to check dimensions final BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; BitmapFactory.decodeFile(path, options); // Calculate inSampleSize options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight); // Decode bitmap with inSampleSize set options.inJustDecodeBounds = false; return BitmapFactory.decodeFile(path,options); } 

Solutions Collecting From Web of "BitmapFactory.decodeFile из памяти с изображениями 2400×2400"

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

  BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = false; options.inPreferredConfig = Config.RGB_565; options.inDither = true; 

Вы должны использовать BitmapFactory.Options с inJustDecodeBounds установленным в true. Таким образом, вы можете загружать информацию о растровом изображении и вычислять значение для понижающей дискретизации (например, inSampleSize )

НЕ загружайте изображение в растровое изображение, преобразовывайте его в массив и отправляйте его.

вместо:

Прочитайте его как файл в формате JPG. Используйте массив байтов файлов, чтобы закодировать его и отправить файл.

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

На стороне сервера вам также нужно будет обработать его как файл. А не растровое изображение.

Вот ссылка на загрузку файла на байт []: Элегантный способ чтения файла в массив byte [] в Java