Now mobile phone photos are several trillion, directly to the original image uploaded to the server, for users, directly collapsed, in the case of WiFi is OK. But when other users look at the list, it is estimated that the phone will owe you a fee. So when uploading pictures, you want to compress the pictures.
Note: Compression here refers to mass compression, not size compression.
For example, when we take a picture, upload it to the server. We need to first take this picture, read into memory, and then compress, and finally the compressed file output.
About the memory of the picture, how to load save memory, here is not to say
Recommend the reader to read this article: http://www.jcodecraeer.com/plus/view.php?aid=3874
The following code comes from the Imageloader framework, and I drew it out of the decoder picture code and made a little change
Using code
public class Mainactivity extends Appcompatactivity {String ImagePath = Environment.getexternalstoragedirectory (). g
Etabsolutepath () + "/" + "123.jpg";
String Outpath = Environment.getexternalstoragedirectory (). GetAbsolutePath () + "/" + "new.jpg";
@Override protected void OnCreate (Bundle savedinstancestate) {super.oncreate (savedinstancestate);
Setcontentview (R.layout.activity_main);
Final Imagedecoder decoder = new Imagedecoder ();
Final ImageSize imagesize = new ImageSize (400, 800);
Final file File = new file (ImagePath);
if (file.exists ()) {new Thread () {@Override public void run () {
Super.run ();
try {Bitmap Bitmap = decoder.decode (file, imagesize);
Imageutils.compressbmptofile (Bitmap, New File (Outpath)); catch (IOException e) {E.printstacKtrace ();
}}.start (); }
}
}
Imagedecoder class is responsible for the picture decode into the target size, and then imageutils.compressbmptofile the image compression, after compression (compressed to less than 100K), output file
Imagedecoder.java
public class Imagedecoder {public Bitmap decode (file file, ImageSize targetsize) throws IOException {Bitmap
Decodedbitmap;
Imagefileinfo Imageinfo;
InputStream ImageStream = getimagestream (file);
try {imageinfo = defineimagesizeandrotation (imagestream, file);
ImageStream = Resetstream (imagestream, file);
Bitmapfactory.options decodingoptions = preparedecodingoptions (imageinfo.imagesize, targetSize);
Decodedbitmap = Bitmapfactory.decodestream (ImageStream, NULL, decodingoptions);
finally {closesilently (imagestream); } if (Decodedbitmap!= null) {Decodedbitmap = Considerexactscaleandorientatiton (Decodedbitmap, Targe
Tsize, ImageInfo.exif.rotation, imageInfo.exif.flipHorizontal);
return decodedbitmap; Private InputStream Getimagestream (File res) throws ioexception{return new FileInputStream (res); /** * Defines the size of the image and the degree of rotation/protected Imagefileinfo defineimagesizeandrotation (InputStream imagestream,
File file) throws IOException {bitmapfactory.options Options = new Bitmapfactory.options ();
Options.injustdecodebounds = true;
Bitmapfactory.decodestream (ImageStream, NULL, options);
Exifinfo Exif;
if (Candefineexifparams (Options.outmimetype)) {exif = defineexiforientation (file);
else {exif = new exifinfo ();
Return to New Imagefileinfo (new ImageSize (Options.outwidth, Options.outheight, exif.rotation), EXIF);
Private Boolean Candefineexifparams (String mimetype) {return "Image/jpeg". Equalsignorecase (MimeType);
} protected Exifinfo defineexiforientation (File imageuri) {int rotation = 0;
Boolean flip = false;
try {exifinterface exif = new Exifinterface (Imageuri.getabsolutepath ()); INT Exiforientation = Exif.getattributeint (exifinterface.tag_orientation, exifinterface.orientation_normal); Switch (exiforientation) {Case ExifInterface.ORIENTATION_FLIP_HORIZONTAL:flip = True
;
Case ExifInterface.ORIENTATION_NORMAL:rotation = 0;
Break
Case ExifInterface.ORIENTATION_TRANSVERSE:flip = true;
Case ExifInterface.ORIENTATION_ROTATE_90:rotation = 90;
Break
Case ExifInterface.ORIENTATION_FLIP_VERTICAL:flip = true;
Case ExifInterface.ORIENTATION_ROTATE_180:rotation = 180;
Break
Case ExifInterface.ORIENTATION_TRANSPOSE:flip = true;
Case ExifInterface.ORIENTATION_ROTATE_270:rotation = 270; Break; catch (IOException e) {LOG.W ("decoder", "Can" T read EXIF tags from file [%s] "+ Imageuri.getabsol
Utepath ());
Return to new Exifinfo (rotation, flip); /** * If ImageStream support Reset, then return the reset ImageStream, otherwise return {@link #getImageStream (File)} * * Protected Inpu Tstream Resetstream (InputStream imagestream, File res) throws IOException {//http://zhangbo-peipei-163-com.iteye.
com/blog/2022460 if (imagestream.marksupported ()) {try {imagestream.reset ();
return imagestream;
The catch (IOException ignored) {}} closesilently (ImageStream);
Return Getimagestream (RES); /** * Returns the option/protected bitmapfactory.options preparedecodingoptions that calculates the simple size (imagesize I
Magesize, ImageSize targetsize) {int scale = Imageutils.computeimagesamplesize (ImageSize, targetsize); BitmapfactorY.options decodingoptions = new Bitmapfactory.options ();
Decodingoptions.insamplesize = scale;
return decodingoptions;
} protected Bitmap Considerexactscaleandorientatiton (Bitmap subsampledbitmap, ImageSize targetsize,
int rotation, Boolean fliphorizontal) {matrix M = new Matrix (); Shrink to exact size if required imagesize srcsize = new ImageSize (Subsampledbitmap.getwidth (), Subsampledbitmap.getheight (), Rota
tion);
Float scale = Imageutils.computeimagescale (Srcsize, targetsize, false);
if (Float.compare (scale, 1f)!= 0) {M.setscale (scale, scale);
}//Flip bitmap if required if (fliphorizontal) {M.postscale (-1, 1);
//Select Bitmap if required if (rotation!= 0) {m.postrotate (rotation); Bitmap Finalbitmap = Bitmap.createbitmap (subsampledbitmap, 0, 0, subsampledbitmap.getwidth (), SubsampledbitmaP. getheight (), M, true);
if (Finalbitmap!= subsampledbitmap) {subsampledbitmap.recycle ();
return finalbitmap;
} protected static class Exifinfo {public final int rotation;
Public final Boolean fliphorizontal;
Protected Exifinfo () {this.rotation = 0;
This.fliphorizontal = false;
} protected Exifinfo (int rotation, Boolean fliphorizontal) {this.rotation = rotation;
This.fliphorizontal = FlipHorizontal;
} protected static class Imagefileinfo {public final imagesize imagesize;
Public final exifinfo Exif;
Protected Imagefileinfo (ImageSize imagesize, Exifinfo exif) {this.imagesize = ImageSize;
This.exif = EXIF;
}} public static void closesilently (Closeable closeable) {if (closeable!= null) {try { Closeable.cloSE ();
The catch (Exception ignored) {}}}
Imageutils. Java
public class Imageutils {private static final int default_max_bitmap_dimension = 2048;
private static ImageSize maxbitmapsize;
static {int[] maxtexturesize = new Int[1];
Gles10.glgetintegerv (gl10.gl_max_texture_size, maxtexturesize, 0);
int maxbitmapdimension = Math.max (maxtexturesize[0], default_max_bitmap_dimension);
Maxbitmapsize = new ImageSize (maxbitmapdimension, maxbitmapdimension); Private Imageutils () {} public static int computeimagesamplesize (ImageSize srcsize, ImageSize targetsize)
{Final int srcwidth = Srcsize.getwidth ();
Final int srcheight = Srcsize.getheight ();
Final int targetwidth = Targetsize.getwidth ();
Final int targetheight = Targetsize.getheight ();
int scale = 1; Scale = Math.min (Srcwidth/targetwidth, srcheight/targetheight);
Min if (Scale < 1) {scale = 1; } scale = Considermaxtexturesize (srcwidth, SRCHeight, scale, false);
return scale; /** * If the width and height/scale greater than max texture size will continue to shrink * @return Sample size/private static int considerm axtexturesize (int srcwidth, int srcheight, int scale, Boolean powerOf2) {final int maxwidth = Maxbitmapsize.getwi
DTH ();
Final int maxheight = Maxbitmapsize.getheight (); while ((Srcwidth/scale) > MaxWidth | |
(Srcheight/scale) > MaxHeight) {if (POWEROF2) {scale *= 2;
else {scale++;
} return scale;
public static float Computeimagescale (ImageSize srcsize, ImageSize targetsize,
Boolean stretch) {final int srcwidth = Srcsize.getwidth ();
Final int srcheight = Srcsize.getheight ();
Final int targetwidth = Targetsize.getwidth ();
Final int targetheight = Targetsize.getheight (); Final float Widthscale = (float)Srcwidth/targetwidth;
Final float Heightscale = (float) srcheight/targetheight;
final int destwidth;
final int destheight;
if (Widthscale < Heightscale) {destwidth = Targetwidth;
Destheight = (int) (Srcheight/widthscale);
else {destwidth = (int) (Srcwidth/heightscale);
Destheight = Targetheight;
float scale = 1; if ((!stretch && destwidth < srcwidth && destheight < srcheight) | | (Stretch && destwidth!= srcwidth && destheight!= srcheight))
{scale = (float) destwidth/srcwidth;
return scale; public static void Compressbmptofile (Bitmap bmp, File file) {Bytearrayoutputstream BAOs = new Bytearrayout
Putstream ();
int options = 80;
Bmp.compress (Bitmap.CompressFormat.JPEG, Options, BAOs);
while (Baos.tobytearray (). length/1024 > 100) { options = 10;
if (Options > 0) {baos.reset ();
Bmp.compress (Bitmap.CompressFormat.JPEG, Options, BAOs);
} else {break;
} try {FileOutputStream fos = new FileOutputStream (file);
byte[] bytes = Baos.tobytearray ();
Fos.write (bytes);
Fos.flush ();
Fos.close ();
LOG.I ("tag", "File.length" + file.length ());
catch (Exception e) {e.printstacktrace (); }
}
}
Imagesize.java
public class ImageSize {
private final int width;
private final int height;
Public imagesize (int width, int height) {
this.width = width;
this.height = height;
}
Public imagesize (int width, int height, int rotation) {
if (rotation% 180 = = 0) {
this.width = width;
this.height = height;
} else {
this.width = height;
This.height = width;
}
}
public int getwidth () {return
width;
}
public int getheight () {return
height;
}
}
GitHub Address
Https://github.com/wu-liao-de-ren-sheng/ImageCompress