android - How whatsapp/Instagram or other compresses the image before uploading it to server? -
i used below method compress image before uploading server.
to summarize below code, take image phone/sdcard, convert bitmap , carryout scaling , compression on bitmap. save compressed bitmap on disk image in new location.
this method compress image 3mb - 5mb in 30-100kb. (when check compressed image size on sdcard)
then send newly compressed image of 30-100kb upload on server converting bitmap string ( base64.encodetostring() )
i thought work fine. when check uploaded image on server, size of image same original image size (original size before compressed) instead of compressed 30-100kb size image.
here code:
public string compressimage(string imageuri) { string filepath = getrealpathfromuri(imageuri); bitmap scaledbitmap = null; bitmapfactory.options options = new bitmapfactory.options(); options.injustdecodebounds = true; bitmap bmp = bitmapfactory.decodefile(filepath, options); int actualheight = options.outheight; int actualwidth = options.outwidth; float maxheight = 816.0f; float maxwidth = 612.0f; float imgratio = actualwidth / actualheight; float maxratio = maxwidth / maxheight; if (actualheight > maxheight || actualwidth > maxwidth) { if (imgratio < maxratio) { imgratio = maxheight / actualheight; actualwidth = (int) (imgratio * actualwidth); actualheight = (int) maxheight; } else if (imgratio > maxratio) { imgratio = maxwidth / actualwidth; actualheight = (int) (imgratio * actualheight); actualwidth = (int) maxwidth; } else { actualheight = (int) maxheight; actualwidth = (int) maxwidth; } } options.insamplesize = calculateinsamplesize(options, actualwidth, actualheight); options.injustdecodebounds = false; options.inpurgeable = true; options.ininputshareable = true; options.intempstorage = new byte[16 * 1024]; try { bmp = bitmapfactory.decodefile(filepath, options); } catch (outofmemoryerror exception) { exception.printstacktrace(); } try { scaledbitmap = bitmap.createbitmap(actualwidth, actualheight,bitmap.config.argb_8888); } catch (outofmemoryerror exception) { exception.printstacktrace(); } float ratiox = actualwidth / (float) options.outwidth; float ratioy = actualheight / (float) options.outheight; float middlex = actualwidth / 2.0f; float middley = actualheight / 2.0f; matrix scalematrix = new matrix(); scalematrix.setscale(ratiox, ratioy, middlex, middley); canvas canvas = new canvas(scaledbitmap); canvas.setmatrix(scalematrix); canvas.drawbitmap(bmp, middlex - bmp.getwidth() / 2, middley - bmp.getheight() / 2, new paint(paint.filter_bitmap_flag)); exifinterface exif; try { exif = new exifinterface(filepath); int orientation = exif.getattributeint( exifinterface.tag_orientation, 0); log.d("exif", "exif: " + orientation); matrix matrix = new matrix(); if (orientation == 6) { matrix.postrotate(90); log.d("exif", "exif: " + orientation); } else if (orientation == 3) { matrix.postrotate(180); log.d("exif", "exif: " + orientation); } else if (orientation == 8) { matrix.postrotate(270); log.d("exif", "exif: " + orientation); } scaledbitmap = bitmap.createbitmap(scaledbitmap, 0, 0, scaledbitmap.getwidth(), scaledbitmap.getheight(), matrix, true); } catch (ioexception e) { e.printstacktrace(); } fileoutputstream out = null; string filename = getfilename(); try { out = new fileoutputstream(filename); scaledbitmap.compress(bitmap.compressformat.jpeg, 80, out); } catch (filenotfoundexception e) { e.printstacktrace(); } return filename; } public string getfilename() { file file = new file(environment.getexternalstoragedirectory().getpath(), "myfolder/images"); if (!file.exists()) { file.mkdirs(); } string uristing = (file.getabsolutepath() + "/" + system.currenttimemillis() + ".jpg"); return uristing;} private string getrealpathfromuri(string contenturi) { uri contenturi = uri.parse(contenturi); cursor cursor = getcontentresolver().query(contenturi, null, null, null, null); if (cursor == null) { return contenturi.getpath(); } else { cursor.movetofirst(); int index = cursor.getcolumnindex(mediastore.images.imagecolumns.data); return cursor.getstring(index); } } public 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 heightratio = math.round((float) height/ (float) reqheight); final int widthratio = math.round((float) width / (float) reqwidth); insamplesize = heightratio < widthratio ? heightratio : widthratio; } final float totalpixels = width * height; final float totalreqpixelscap = reqwidth * reqheight * 2; while (totalpixels / (insamplesize * insamplesize) > totalreqpixelscap) { insamplesize++; } return insamplesize;
}
am going wrong somewhere in above code ? there better method compress image. wondering how can uncompressed image(bitmap) getting uploaded instead of compressed one.
how whatsapp/instagram/facebook compresses image before uploading on server. there library it. thank you.
try this:
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; }
scalingutilities.java
import android.content.res.resources; import android.graphics.bitmap; import android.graphics.bitmap.config; import android.graphics.bitmapfactory; import android.graphics.bitmapfactory.options; import android.graphics.canvas; import android.graphics.paint; import android.graphics.rect; /** * class containing static utility methods bitmap decoding , scaling * * @author */ 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); } } }
Comments
Post a Comment