Страницы

Поиск по вопросам

суббота, 29 декабря 2018 г.

Загрузить изображение в GoogleDrive

При загрузке изображения в google drive иногда он загружается нормально памяти хватает, но иногда вываливает java.lang.OutOfMemoryError: Failed to allocate a 63489036 byte allocation with 16777216 free bytes and 21MB until OOM в коде я декодирую его в изображение переворачиваю изображение если надо будет, и указываю content type и загружаю в Google Drive. Ошибка выходит при декодировании изображения. Как можно это обойти, мне обязательно нужно загружать изображение не обрезанное и полное.
BitmapFactory.Options bmOptions = new BitmapFactory.Options(); Bitmap image = BitmapFactory.decodeFile(mSettings.getString(Const.directory, "") + "/" + file.getName(), bmOptions); if (Picture.getCameraPhotoOrientation(file) !=0) { image = Picture.rotateBitmap(image, 270); } OutputStream outputStream = result.getDriveContents().getOutputStream(); ByteArrayOutputStream bitmapStream = new ByteArrayOutputStream(); image.compress(Bitmap.CompressFormat.PNG, 100, bitmapStream); try { outputStream.write(bitmapStream.toByteArray()); } catch (IOException e1) { log(e1 + ""); } MetadataChangeSet metadataChangeSet = new MetadataChangeSet.Builder().setMimeType("image/jpeg").setTitle(file.getName()).build(); DriveFolder folder = Drive.DriveApi.getFolder(mGoogleApiClient, DriveId.decodeFromString(stringFolderId)); folder.createFile(mGoogleApiClient, metadataChangeSet, driveContents).setResultCallback(fileCallback1);


Ответ

Это известная проблема возникающая при декодировании битмапа из файла. Проблемная строка BitmapFactory.decodeFile()
Чтобы ее решить, на старых версиях Android'а (до KitKat), достаточно было указывать битмап выгружаемым на диск:
BitmapFactory.Options bmOptions = new BitmapFactory.Options(); bmOptions.inPurgeable=true;
Для новых версий - этот фокус уже не работает и приходится извращаться по другому, например:
BitmapFactory.Options bmOptions = new BitmapFactory.Options(); bmOptions.inPreferredConfig = Config.RGB_565; //отводит на пиксель 2 байта, вместо 4-х по умолчанию bmOptions.inDither = true;
В итоге размер битмапа сокращается в 2 раза.
Update
Судя по логам у вас слишком большой размер битмапа (>60 мегов) - это очень много, явно больше разрешения девайса. Соответственно при декодировании я бы его смасштабировал, например так:
bmOptions.inSampleSize=4; //уменьшит размеры в 4 раза
то есть занимаемая память уменьшится в 16 раз, до 16 мегов. Если не поможет, то надо увеличивать до 5 или 6.
Почитайте эту статейку

Комментариев нет:

Отправить комментарий