android - How to prevent memory increase on Image Compression -
i trying capture image, compress file & upload server. but, when doing that, memory size increases 60 mb.
i doing following approach compress image file path. during process only,memory size increases & getting out of memory issue also.
public string getscaledpic(string path) { bitmap img; try { string filepath =path;; string foldername = filepath.substring(0, filepath.lastindexof("/")+1); string tmpfilename = (filepath.substring(filepath.lastindexof("/")+1)).split("\\.")[0]+"_tmp.jpg"; file = new file(filepath); foldername=getactivity().getfilesdir()+"/"; file = new file(foldername+tmpfilename); try { copy(from, to); compress(foldername+tmpfilename); } catch (ioexception io){ return path; } return foldername+tmpfilename; } catch(exception e) { return path; } } public void copy(file src, file dst) throws ioexception { inputstream in = new fileinputstream(src); outputstream out = new fileoutputstream(dst); // transfer bytes in out byte[] buf = new byte[1024]; int len; while ((len = in.read(buf)) > 0) { out.write(buf, 0, len); } in.close(); out.close(); } public void compress(string comp) { try { string path = comp; bitmapfactory.options buffer = new bitmapfactory.options(); bitmap bmp = bitmapfactory.decodefile(path, buffer); if (bmp.getwidth() > 768 && bmp.getheight() > 768){ float widthcompression = 768.0f/bmp.getwidth(); float heightcompression = 768.0f/bmp.getheight(); if (widthcompression>=heightcompression) { bitmap resized = bitmap.createscaledbitmap(bmp,(int)(bmp.getwidth()*widthcompression), (int)(bmp.getheight()*widthcompression), true); bmp.recycle(); fileoutputstream out = new fileoutputstream(path); resized.compress(compressformat.jpeg, 100, out); resized.recycle(); out.flush(); out.close(); } else { bitmap resized = bitmap.createscaledbitmap(bmp,(int)(bmp.getwidth()*heightcompression), (int)(bmp.getheight()*heightcompression), true); bmp.recycle(); fileoutputstream out = new fileoutputstream(path); resized.compress(compressformat.jpeg, 100, out); resized.recycle(); out.flush(); out.close(); } } } catch (exception e) { e.printstacktrace(); } }
is there mistake approach? also, image, how handle memory leaks or heavy memory usage caused bitmaps?
hey use following code reduce file size.
===================== add class ================================
public class scalingutilities { /** * utility function decoding image resource. decoded bitmap * optimized further scaling requested destination dimensions * , scaling logic. * * @param res resources object containing image data * @param resid resource id of image data * @param dstwidth width of destination area * @param dstheight height of destination area * @param scalinglogic logic use avoid image stretching * @return decoded bitmap */ public static bitmap decoderesource(resources res, int resid, int dstwidth, int dstheight, scalinglogic scalinglogic) { options options = new options(); options.injustdecodebounds = true; bitmapfactory.decoderesource(res, resid, options); options.injustdecodebounds = false; options.insamplesize = calculatesamplesize(options.outwidth, options.outheight, dstwidth, dstheight, scalinglogic); bitmap unscaledbitmap = bitmapfactory.decoderesource(res, resid, options); return unscaledbitmap; } public static bitmap decodefile(string path, int dstwidth, int dstheight, scalinglogic scalinglogic) { options options = new options(); options.injustdecodebounds = true; bitmapfactory.decodefile(path, options); options.injustdecodebounds = false; options.insamplesize = calculatesamplesize(options.outwidth, options.outheight, dstwidth, dstheight, scalinglogic); bitmap unscaledbitmap = bitmapfactory.decodefile(path, options); return unscaledbitmap; } /** * utility function creating scaled version of existing bitmap * * @param unscaledbitmap bitmap scale * @param dstwidth wanted width of destination bitmap * @param dstheight wanted height of destination bitmap * @param scalinglogic logic use avoid image stretching * @return new scaled bitmap object */ public static bitmap createscaledbitmap(bitmap unscaledbitmap, int dstwidth, int dstheight, scalinglogic scalinglogic) { rect srcrect = calculatesrcrect(unscaledbitmap.getwidth(), unscaledbitmap.getheight(), dstwidth, dstheight, scalinglogic); rect dstrect = calculatedstrect(unscaledbitmap.getwidth(), unscaledbitmap.getheight(), dstwidth, dstheight, scalinglogic); bitmap scaledbitmap = bitmap.createbitmap(dstrect.width(), dstrect.height(), config.argb_8888); canvas canvas = new canvas(scaledbitmap); canvas.drawbitmap(unscaledbitmap, srcrect, dstrect, new paint(paint.filter_bitmap_flag)); return scaledbitmap; } /** * scalinglogic defines how scaling should carried out if source , * destination image has different aspect ratio. * * crop: scales image minimum amount while making sure @ least * 1 of 2 dimensions fit inside requested destination area. * parts of source image cropped realize this. * * fit: scales image minimum amount while making sure both * dimensions fit inside requested destination area. resulting * destination dimensions might adjusted smaller size * requested. */ public static enum scalinglogic { crop, fit } /** * calculate optimal down-sampling factor given dimensions of source * image, dimensions of destination area , scaling logic. * * @param srcwidth width of source image * @param srcheight height of source image * @param dstwidth width of destination area * @param dstheight height of destination area * @param scalinglogic logic use avoid image stretching * @return optimal down scaling sample size decoding */ public static int calculatesamplesize(int srcwidth, int srcheight, int dstwidth, int dstheight, scalinglogic scalinglogic) { if (scalinglogic == scalinglogic.fit) { final float srcaspect = (float)srcwidth / (float)srcheight; final float dstaspect = (float)dstwidth / (float)dstheight; if (srcaspect > dstaspect) { return srcwidth / dstwidth; } else { return srcheight / dstheight; } } else { final float srcaspect = (float)srcwidth / (float)srcheight; final float dstaspect = (float)dstwidth / (float)dstheight; if (srcaspect > dstaspect) { return srcheight / dstheight; } else { return srcwidth / dstwidth; } } } /** * calculates source rectangle scaling bitmap * * @param srcwidth width of source image * @param srcheight height of source image * @param dstwidth width of destination area * @param dstheight height of destination area * @param scalinglogic logic use avoid image stretching * @return optimal source rectangle */ public static rect calculatesrcrect(int srcwidth, int srcheight, int dstwidth, int dstheight, scalinglogic scalinglogic) { if (scalinglogic == scalinglogic.crop) { final float srcaspect = (float)srcwidth / (float)srcheight; final float dstaspect = (float)dstwidth / (float)dstheight; if (srcaspect > dstaspect) { final int srcrectwidth = (int)(srcheight * dstaspect); final int srcrectleft = (srcwidth - srcrectwidth) / 2; return new rect(srcrectleft, 0, srcrectleft + srcrectwidth, srcheight); } else { final int srcrectheight = (int)(srcwidth / dstaspect); final int scrrecttop = (int)(srcheight - srcrectheight) / 2; return new rect(0, scrrecttop, srcwidth, scrrecttop + srcrectheight); } } else { return new rect(0, 0, srcwidth, srcheight); } } /** * calculates destination rectangle scaling bitmap * * @param srcwidth width of source image * @param srcheight height of source image * @param dstwidth width of destination area * @param dstheight height of destination area * @param scalinglogic logic use avoid image stretching * @return optimal destination rectangle */ public static rect calculatedstrect(int srcwidth, int srcheight, int dstwidth, int dstheight, scalinglogic scalinglogic) { if (scalinglogic == scalinglogic.fit) { final float srcaspect = (float)srcwidth / (float)srcheight; final float dstaspect = (float)dstwidth / (float)dstheight; if (srcaspect > dstaspect) { return new rect(0, 0, dstwidth, (int)(dstwidth / srcaspect)); } else { return new rect(0, 0, (int)(dstheight * srcaspect), dstheight); } } else { return new rect(0, 0, dstwidth, dstheight); } }
}
============= use method resize image ==================
private string decodefile(string path, int desiredwidth, int desiredheight) { string strmyimagepath = null; bitmap scaledbitmap = null; try { // part 1: decode image bitmap unscaledbitmap = scalingutilities.decodefile(path, desiredwidth, desiredheight, scalinglogic.fit); if (!(unscaledbitmap.getwidth() <= desiredwidth && unscaledbitmap.getheight() <= desiredheight)) { // part 2: scale image scaledbitmap = scalingutilities.createscaledbitmap(unscaledbitmap, desiredwidth, desiredheight, scalinglogic.fit); } else { unscaledbitmap.recycle(); return path; } // store tmp file string extr = environment.getexternalstoragedirectory().tostring(); file mfolder = new file(extr + "/tmmfolder"); if (!mfolder.exists()) { mfolder.mkdir(); } string s = "tmp.png"; file f = new file(mfolder.getabsolutepath(), s); strmyimagepath = f.getabsolutepath(); fileoutputstream fos = null; try { fos = new fileoutputstream(f); scaledbitmap.compress(bitmap.compressformat.jpeg, 75, fos); fos.flush(); fos.close(); } catch (filenotfoundexception e) { e.printstacktrace(); } catch (exception e) { e.printstacktrace(); } scaledbitmap.recycle(); } catch (throwable e) { } if (strmyimagepath == null) { return path; } return strmyimagepath; }
Comments
Post a Comment