Ответ 1
http://code.google.com/p/android/issues/detail?id=8488
http://mobi-solutions.blogspot.com/2010/08/how-to-if-you-want-to-create-and.html
Получение исключения в BitmapFactory. Не уверен, в чем проблема. (Ну, я могу догадаться, но не знаю, почему это происходит)
ERROR/AndroidRuntime(7906): java.lang.OutOfMemoryError: bitmap size exceeds VM budget ERROR/AndroidRuntime(7906): at android.graphics.BitmapFactory.decodeFile(BitmapFactory.java:295)
Мой код довольно прост. Я определил формат XML с изображением по умолчанию. Я пытаюсь загрузить bm на SDCard (если присутствует - это). Если нет, отображается изображение по умолчанию. В любом случае.. Вот код:
public class showpicture extends Activity {
public void onCreate(Bundle savedInstanceState) {
/** Remove menu/status bar **/
requestWindowFeature(Window.FEATURE_NO_TITLE);
final Window win = getWindow();
win.setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);
Bitmap bm;
super.onCreate(savedInstanceState);
setContentView(R.layout.showpicture);
try {
ImageView mImageButton = (ImageView)findViewById(R.id.displayPicture);
bm = Bitmap.createScaledBitmap(BitmapFactory.decodeFile("/sdcard/dcim/Camera/20091018203339743.jpg"),100, 100, true);
parkImageButton.setImageBitmap(bm);
}
catch (IllegalArgumentException ex) {
Log.d("MYAPP",ex.getMessage());
}
catch (IllegalStateException ex) {
Неужели на bm=Bitmap.createScaledBitmap
нет никаких мыслей? Я провел некоторое исследование на форумах, и он указал на этот пост
Я просто не знаю, почему он не работает. Любая помощь будет замечательной! Спасибо,
Крис.
http://code.google.com/p/android/issues/detail?id=8488
http://mobi-solutions.blogspot.com/2010/08/how-to-if-you-want-to-create-and.html
inSampleSize - хороший намек. Но фиксированное значение часто не работает нормально, поскольку большие растровые изображения из файлов обычно являются пользовательскими файлами, которые могут варьироваться от маленьких миниатюр до 12-мегапиксельных изображений из digicam.
Здесь быстрая и грязная загрузка. Я знаю, что есть место для улучшения, например, более качественный кодированный контур, использующий полномочия 2 для более быстрого декодирования и т.д. Но это рабочий старт...
public static Bitmap loadResizedBitmap( String filename, int width, int height, boolean exact ) {
Bitmap bitmap = null;
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile( filename, options );
if ( options.outHeight > 0 && options.outWidth > 0 ) {
options.inJustDecodeBounds = false;
options.inSampleSize = 2;
while ( options.outWidth / options.inSampleSize > width
&& options.outHeight / options.inSampleSize > height ) {
options.inSampleSize++;
}
options.inSampleSize--;
bitmap = BitmapFactory.decodeFile( filename, options );
if ( bitmap != null && exact ) {
bitmap = Bitmap.createScaledBitmap( bitmap, width, height, false );
}
}
return bitmap;
}
Btw, в новых API-интерфейсах также есть много BitmapFactory.Option для подгонки изображения к экранам DPI, но я не уверен, действительно ли они упрощают что-либо. Использование android.util.DisplayMetrics.density или просто фиксированный размер для меньшего потребления памяти, похоже, лучше работает imho.
Что касается ссылки , обратите внимание, что ошибка outOfMemory
может быть решена следующим образом:
public Bitmap decodeFile(String filePath) {
Bitmap bitmap = null;
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPurgeable = true;
try {
BitmapFactory.Options.class.getField("inNativeAlloc").setBoolean(options,true);
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
if(filePath != null)
{
bitmap = BitmapFactory.decodeFile(filePath, options);
}
return bitmap;
}
В результате я изменил размер растрового изображения, используя следующий код, который, похоже, решил проблему.
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 8;
Bitmap preview_bitmap = BitmapFactory.decodeFile(mPathName, options);
Обязательно защитите свое растровое изображение от ошибок из памяти! На большинстве платформ у Android не так много памяти, и он быстро заканчивается с растровыми изображениями. Кроме того, убедитесь, что вы как можно больше вручную переработали растровые изображения, я заметил, что сборка мусора может быть довольно медленной.
try{
Bitmap myFragileBitmap = Bitmap.createBitmap(500, 500, Bitmap.Config.ARGB_8888);
}
catch(IllegalArgumentException e){
Log.e(TAG,"Illegal argument exception.");
}
catch(OutOfMemoryError e){
Log.e(TAG,"Out of memory error :(");
}
Я думаю, что это - то, что он говорит. Ваше изображение слишком велико, и поскольку оно загружается в поток, когда память исчерпана, генерируется исключение. Это даже не вопрос о том, сколько памяти у вас в целом, но сколько доступно для вашей конкретной деятельности.
используйте эти параметры в файле decode. Надеюсь, что u может объединить растровое изображение, превысив бюджетную проблему vm.
BitmapFactory.Options bfOptions=new BitmapFactory.Options();
bfOptions.inDither=false; //Disable Dithering mode
bfOptions.inPurgeable=true; //Tell to gc that whether it needs free memory, the Bitmap can be cleared
bfOptions.inInputShareable=true; //Which kind of reference will be used to recover the Bitmap data after being clear, when it will be used in the future
bfOptions.inTempStorage=new byte[32 * 1024];
Вы проверили DDMS? С тем, с чем я сталкивался, это, вероятно, не размер изображений, потому что Android, похоже, отлично справляется с большими изображениями. Если вы отслеживаете кучу с помощью DDMS, вы обнаружите, что у вас много свободной памяти. Вы можете "развернуть" свою кучу, добавив эту
static { @SuppressWarnings("unused")
byte dummy[] = new byte[ 8*1024*1024 ]; }
к вашему коду, чтобы заставить кучу расшириться. Это может сделать его немного реже. К сожалению, за исключением того, что он утверждает, что он не может выделить некоторое количество байтов. Скажем 1M. Если вы посмотрите на "свободную" линию, вы увидите, что самый большой блок → > 1M. Там что-то странное, что я не могу понять. Это не связано даже со скоростью прокручивания изображений. Я видел в каком-то потоке, что вы можете назвать "переработать" или так для растровых изображений. Я все еще не понимаю, почему это должно помочь, если размер кучи выше установленного размера.
У меня возникла эта ошибка, когда я начал изменять размер изображения с 320x240 до примерно 64x240 (вниз), а затем импортировал в свой проект (так как я хотел улучшить скорость рендеринга, и до этого момента он содержал множество бесполезных альфа-областей).
теперь последний ответ имеет смысл:
Вы можете "развернуть" свою кучу, добавив этот статический {@SuppressWarnings ( "неиспользуемый" ) байтовый макет [] = новый байт [8 * 1024 * 1024]; } к вашему коду, чтобы заставить кучу расшириться. Это может сделать это немного меньше часто.
Я думаю, что это случилось со мной. Android автоматически расшифровывает чертежи в растровые изображения (а затем хранится в куче, все время компиляции?)
Я начал видеть ошибку, когда я использовал меньшую версию моего изображения во время выполнения (я масштабирую их во время выполнения, так как я программирую VGA-игру с ретро-графикой, используя BitmapFactory.decodeResource и Bitmap.createScaledBitmap).
это должно быть похоже на то, как Марве сказал: "Куча" недостаточно велика в моем случае после сокращения моего рисунка/изображения и импорта его в мой проект.
Мне удалось избавиться от моего OutOfMemoryException при изменении размера изображения до более крупного размера (320x240), который проверяет проблему, о которой я думаю?