Android - Application crashes with Out Of Memory when selecting very large image -
this question has answer here:
in below code, getting exception "out of memory on byte allocation" large size images in function "getscaledbitmap" when processing decodefile second time in code. below function being called 4 times, processing 4 different images on screen.
please guide on this.
private bitmap processimage(string picturepath){ bitmap thumbnail =null; thumbnail=getscaledbitmap(picturepath,500,500); matrix matrix = null; try { exifinterface exif = new exifinterface(picturepath); int rotation = exif.getattributeint(exifinterface.tag_orientation, exifinterface.orientation_normal); int rotationindegrees = bal.exiftodegrees(rotation); matrix = new matrix(); if (rotation != 0f) { matrix.prerotate(rotationindegrees); thumbnail=bitmap.createbitmap(thumbnail, 0,0, thumbnail.getwidth(), thumbnail.getheight(), matrix, true); } } catch (ioexception e) { e.printstacktrace(); }catch (exception e) { e.printstacktrace(); } return thumbnail; } protected bitmap getscaledbitmap(string picturepath, int width, int height) { bitmap result=null; try{ bitmapfactory.options sizeoptions = new bitmapfactory.options(); sizeoptions.injustdecodebounds = true; bitmapfactory.decodefile(picturepath, sizeoptions); int insamplesize = calculateinsamplesize(sizeoptions, width, height); sizeoptions.injustdecodebounds = false; sizeoptions.insamplesize = insamplesize; result=bitmapfactory.decodefile(picturepath, sizeoptions); }catch(exception ex){ ex.printstacktrace(); } return result; } protected int calculateinsamplesize(bitmapfactory.options options, int reqwidth, int reqheight) { final int height = options.outheight; final int width = options.outwidth; int insamplesize = 1; if (height > reqheight || width > reqwidth) { final int halfheight = height / 2; final int halfwidth = width / 2; while ((halfheight / insamplesize) > reqheight || (halfwidth / insamplesize) > reqwidth) { insamplesize *= 2; } } return insamplesize; } public int exiftodegrees(int exiforientation) { if (exiforientation == exifinterface.orientation_rotate_90) { return 90; } else if (exiforientation == exifinterface.orientation_rotate_180) { return 180; } else if (exiforientation == exifinterface.orientation_rotate_270) { return 270; } return 0; }
to scale image , catch oom error use following code(but 1 image).i not sure if ok you..and include try catch oom in code avoid crash options options = new bitmapfactory.options(); try{ options.inscaled = false; options.indither = false; options.inpreferredconfig = bitmap.config.argb_8888; imgbitmap=decodefile(file); } catch(outofmemoryerror e){ system.out.println("out of memory"); flag=1; system.out.println("clearing bitmap????????????"); if (imgbitmap!=null) { this.setbackgroundresource(0); this.clearanimation(); imgbitmap.recycle(); imgbitmap = null;} // } }
method optimize imagefile
public bitmap decodefile(file f) { try { // decode image size bitmapfactory.options o = new bitmapfactory.options(); o.injustdecodebounds = true; o.indither=false; //disable dithering mode o.inpurgeable=true; //tell gc whether needs free memory, bitmap can cleared o.ininputshareable=true; o.inpreferredconfig = bitmap.config.argb_8888; //which kind of reference used recover bitmap data after being clear, when used in future o.intempstorage=new byte[16*1024]; bitmapfactory.decodestream(new fileinputstream(f), null, o); // find correct scale value. should power of 2. int required_size = 300; int width_tmp = o.outwidth, height_tmp = o.outheight; if(required_size > width_tmp) required_size = width_tmp; int scale = 1; while (true) { if (width_tmp / 2 < required_size || height_tmp / 2 < required_size) break; width_tmp /= 2; height_tmp /= 2; scale *= 2; system.out.println(scale+"______________________________-"); } // decode insamplesize bitmapfactory.options o2 = new bitmapfactory.options(); o2.indither=false; o2.inscaled = false; o2.inpurgeable=true; //tell gc whether needs free memory, bitmap can cleared o2.ininputshareable=true; //which kind of reference used recover bitmap data after being clear, when used in future o2.intempstorage=new byte[24*1024]; o2.insamplesize = 2; o2.outwidth = width_tmp; o2.outheight = height_tmp; o2.inpreferredconfig = bitmap.config.argb_8888; try { bitmapfactory.options.class.getfield("innativealloc").setboolean(o2,true); } catch (illegalargumentexception e) { e.printstacktrace(); } catch (securityexception e) { e.printstacktrace(); } catch (illegalaccessexception e) { e.printstacktrace(); } catch (nosuchfieldexception e) { e.printstacktrace(); } o2.injustdecodebounds = false; return bitmapfactory.decodestream(new fileinputstream(f), null, o2); } catch (filenotfoundexception e) { system.out.println("file not found"); } return null; }
Comments
Post a Comment