package com.snail.travellingTrail.common.utils; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.math.BigDecimal; import java.math.RoundingMode; import java.nio.ByteBuffer; import java.nio.channels.Channels; import java.nio.channels.ReadableByteChannel; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; import android.content.Context; import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.Bitmap.CompressFormat; import android.graphics.BitmapFactory; import android.graphics.BitmapFactory.Options; import android.graphics.Matrix; import android.media.ExifInterface; import android.util.Log; public class BitmapHelper { /** * get the orientation of the bitmap {@link android.media.ExifInterface} * @param path * @return */ public final static int getDegress(String path) { int degree = 0; try { ExifInterface exifInterface = new ExifInterface(path); int orientation = exifInterface.getAttributeInt( ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL); switch (orientation) { case ExifInterface.ORIENTATION_ROTATE_90: degree = 90; break; case ExifInterface.ORIENTATION_ROTATE_180: degree = 180; break; case ExifInterface.ORIENTATION_ROTATE_270: degree = 270; break; } } catch (IOException e) { e.printStackTrace(); } return degree; } /** * rotate the bitmap * @param bitmap * @param degress * @return */ public static Bitmap rotateBitmap(Bitmap bitmap, int degress) { if (bitmap != null) { Matrix m = new Matrix(); m.postRotate(degress); bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), m, true); return bitmap; } return bitmap; } /** * caculate the bitmap sampleSize * @param path * @return */ public final static int caculateInSampleSize(BitmapFactory.Options options, int rqsW, int rqsH) { final int height = options.outHeight; final int width = options.outWidth; int inSampleSize = 1; if (rqsW == 0 || rqsH == 0) return 1; if (height > rqsH || width > rqsW) { final int heightRatio = Math.round((float) height/ (float) rqsH); final int widthRatio = Math.round((float) width / (float) rqsW); inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio; } return inSampleSize; } /** * 压缩指定路径的图片,并得到图片对象 * @param context * @param path bitmap source path * @return Bitmap {@link android.graphics.Bitmap} */ public final static Bitmap compressBitmap(String path, int rqsW, int rqsH) { final BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; BitmapFactory.decodeFile(path, options); options.inSampleSize = caculateInSampleSize(options, rqsW, rqsH); options.inJustDecodeBounds = false; return BitmapFactory.decodeFile(path, options); } /** * 此方法过期,该方法可能造成OutOfMemoryError,使用不含isAdjust参数的方法 * @param is * @param reqsW * @param reqsH * @param isAdjust * @return */ @Deprecated public final static Bitmap compressBitmap(InputStream is, int reqsW, int reqsH, boolean isAdjust) { Bitmap bitmap = BitmapFactory.decodeStream(is); return compressBitmap(bitmap, reqsW, reqsH, isAdjust); } /** * 压缩某个输入流中的图片,可以解决网络输入流压缩问题,并得到图片对象 * @param context * @param path bitmap source path * @return Bitmap {@link android.graphics.Bitmap} */ public final static Bitmap compressBitmap(InputStream is, int reqsW, int reqsH) { try { ByteArrayOutputStream baos = new ByteArrayOutputStream(); ReadableByteChannel channel = Channels.newChannel(is); ByteBuffer buffer = ByteBuffer.allocate(1024); while (channel.read(buffer) != -1) { buffer.flip(); while (buffer.hasRemaining()) baos.write(buffer.get()); buffer.clear(); } byte[] bts = baos.toByteArray(); Bitmap bitmap = compressBitmap(bts, reqsW, reqsH); is.close(); channel.close(); baos.close(); return bitmap; } catch (Exception e) { // TODO: handle exception e.printStackTrace(); return null; } } // /** // * 压缩某个输入流中的图片,可以解决网络输入流压缩问题,并得到图片对象 // * @param context // * @param path bitmap source path // * @return Bitmap {@link android.graphics.Bitmap} // */ // public final static Bitmap compressBitmap(InputStream is, int reqsW, int reqsH) { // try { // ByteArrayOutputStream baos = new ByteArrayOutputStream(); // ReadableByteChannel channel = Channels.newChannel(is); // ByteBuffer buffer = ByteBuffer.allocate(1024); // while (channel.read(buffer) != -1) { // buffer.flip(); // while (buffer.hasRemaining()) baos.write(buffer.get()); // buffer.clear(); // } // byte[] bts = baos.toByteArray(); // Bitmap bitmap = compressBitmap(bts, reqsW, reqsH); // is.close(); // channel.close(); // baos.close(); // return bitmap; // } catch (Exception e) { // // TODO: handle exception // e.printStackTrace(); // return null; // } // } /** * 压缩指定byte[]图片,并得到压缩后的图像 * @param bts * @param reqsW * @param reqsH * @return */ public final static Bitmap compressBitmap(byte[] bts, int reqsW, int reqsH) { final Options options = new Options(); options.inJustDecodeBounds = true; options.inPreferredConfig = Bitmap.Config.ARGB_8888;// optional options.inSampleSize = caculateInSampleSize(options, reqsW, reqsH); options.inJustDecodeBounds = false; return BitmapFactory.decodeByteArray(bts, 0, bts.length, options); } /** * 此方法已过期,该方法可能造成OutOfMemoryError,使用不含isAdjust参数的方法 * @param bitmap * @param reqsW * @param reqsH * @return */ @Deprecated public final static Bitmap compressBitmap(Bitmap bitmap, int reqsW, int reqsH, boolean isAdjust) { if (bitmap == null || reqsW == 0 || reqsH == 0) return bitmap; if (bitmap.getWidth() > reqsW || bitmap.getHeight() > reqsH) { float scaleX = new BigDecimal(reqsW).divide(new BigDecimal(bitmap.getWidth()), 4, RoundingMode.DOWN).floatValue(); float scaleY = new BigDecimal(reqsH).divide(new BigDecimal(bitmap.getHeight()), 4, RoundingMode.DOWN).floatValue(); if (isAdjust) { scaleX = scaleX < scaleY ? scaleX : scaleY; scaleY = scaleX; } Matrix matrix = new Matrix(); matrix.postScale(scaleX, scaleY); bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true); } return bitmap; } /** * 压缩已存在的图片对象,并返回压缩后的图片 * @param bitmap * @param reqsW * @param reqsH * @return */ public final static Bitmap compressBitmap(Bitmap bitmap, int reqsW, int reqsH) { try { ByteArrayOutputStream baos = new ByteArrayOutputStream(); bitmap.compress(CompressFormat.JPEG, 100, baos); byte[] bts = baos.toByteArray(); Bitmap res = compressBitmap(bts, reqsW, reqsH); baos.close(); return res; } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); return bitmap; } } /** * 此方法过期,该方法可能造成OutOfMemoryError,使用不含isAdjust参数的方法 * get bitmap form resource dictory, and then compress bitmap according to reqsW and reqsH * @param res {@link android.content.res.Resources} * @param resID * @param reqsW * @param reqsH * @return */ @Deprecated public final static Bitmap compressBitmap(Resources res, int resID, int reqsW, int reqsH, boolean isAdjust) { Bitmap bitmap = BitmapFactory.decodeResource(res, resID); return compressBitmap(bitmap, reqsW, reqsH, isAdjust); } /** * 压缩资源图片,并返回图片对象 * @param res {@link android.content.res.Resources} * @param resID * @param reqsW * @param reqsH * @return */ public final static Bitmap compressBitmap(Resources res, int resID, int reqsW, int reqsH) { final Options options = new Options(); options.inJustDecodeBounds = true; BitmapFactory.decodeResource(res, resID, options); options.inSampleSize = caculateInSampleSize(options, reqsW, reqsH); options.inJustDecodeBounds = false; return BitmapFactory.decodeResource(res, resID, options); } /** * 基于质量的压缩算法, 此方法未 解决压缩后图像失真问题 * <br> 可先调用比例压缩适当压缩图片后,再调用此方法可解决上述问题 * @param bts * @param maxBytes 压缩后的图像最大大小 单位为kb * @return */ public final static Bitmap compressBitmap(Bitmap bitmap, long maxBytes) { try { ByteArrayOutputStream baos = new ByteArrayOutputStream(); bitmap.compress(CompressFormat.JPEG, 100, baos); int options = 90; while (baos.toByteArray().length/1024 > maxBytes) { baos.reset(); bitmap.compress(CompressFormat.JPEG, options, baos); options -= 10; if(options<0) break; } byte[] bts = baos.toByteArray(); Bitmap bmp = BitmapFactory.decodeByteArray(bts, 0, bts.length); baos.close(); return bmp; } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); return null; } } // public final static Bitmap compressBitmap(InputStream is, long maxBytes) { // try { // ByteArrayOutputStream baos = new ByteArrayOutputStream(); // byte[] bts = new byte[1024]; // while (is.read(bts) != -1) baos.write(bts, 0, bts.length); // is.close(); // int options = 100; // while (baos.toByteArray().length > maxBytes) { // // } // } catch (Exception e) { // // TODO: handle exception // } // } /** * 得到指定路径图片的options * @param srcPath * @return Options {@link android.graphics.BitmapFactory.Options} */ public final static Options getBitmapOptions(String srcPath) { BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; BitmapFactory.decodeFile(srcPath, options); return options; } /*** * 压缩Zip * * @param data * @return */ public static byte[] zip(byte[] data) { byte[] b = null; try { ByteArrayOutputStream bos = new ByteArrayOutputStream(); ZipOutputStream zip = new ZipOutputStream(bos); ZipEntry entry = new ZipEntry("zip"); entry.setSize(data.length); zip.putNextEntry(entry); zip.write(data); zip.closeEntry(); zip.close(); b = bos.toByteArray(); bos.close(); } catch (Exception ex) { ex.printStackTrace(); } return b; } }