package com.vanco.abplayer.util; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import android.annotation.TargetApi; import android.content.Context; import android.graphics.Bitmap; import android.graphics.Bitmap.Config; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Matrix; import android.graphics.Paint; import android.graphics.PixelFormat; import android.graphics.PorterDuff.Mode; import android.graphics.PorterDuffXfermode; import android.graphics.Rect; import android.graphics.RectF; import android.graphics.drawable.Drawable; import android.net.Uri; import android.os.Build; public class ImageUtils { // http://zhuixinjian.javaeye.com/blog/743672 // 图片圆角 // 图片叠加 // 图片缩放 // 图片旋转 @TargetApi(Build.VERSION_CODES.HONEYCOMB_MR1) public static int getBitmapSize(Bitmap bitmap) { if (DeviceUtils.hasHoneycombMR1()) { return bitmap.getByteCount(); } // Pre HC-MR1 return bitmap.getRowBytes() * bitmap.getHeight(); } /** 旋转图片 */ public static Bitmap rotate(Bitmap b, int degrees) { if (degrees != 0 && b != null) { Matrix m = new Matrix(); m.setRotate(degrees, (float) b.getWidth() / 2, (float) b.getHeight() / 2); try { Bitmap b2 = Bitmap.createBitmap(b, 0, 0, b.getWidth(), b.getHeight(), m, true); if (b != b2) { b.recycle(); b = b2; } } catch (OutOfMemoryError ex) { Logger.e(ex); } catch (Exception ex) { Logger.e(ex); } } return b; } /** * Decode and sample down a bitmap from a file to the requested width and * height. * * @param filename * The full path of the file to decode * @param reqWidth * The requested width of the resulting bitmap * @param reqHeight * The requested height of the resulting bitmap * @return A bitmap sampled down from the original with the same aspect * ratio and dimensions that are equal to or greater than the * requested width and height */ public static synchronized Bitmap decodeSampledBitmapFromFile( String filename, int reqWidth, int reqHeight) { // First decode with inJustDecodeBounds=true to check dimensions final BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; BitmapFactory.decodeFile(filename, options); // Calculate inSampleSize options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight); // Decode bitmap with inSampleSize set options.inJustDecodeBounds = false; return BitmapFactory.decodeFile(filename, options); } /** * Calculate an inSampleSize for use in a * {@link android.graphics.BitmapFactory.Options} object when decoding * bitmaps using the decode* methods from {@link BitmapFactory}. This * implementation calculates the closest inSampleSize that will result in * the final decoded bitmap having a width and height equal to or larger * than the requested width and height. This implementation does not ensure * a power of 2 is returned for inSampleSize which can be faster when * decoding but results in a larger bitmap which isn't as useful for caching * purposes. * * @param options * An options object with out* params already populated (run * through a decode* method with inJustDecodeBounds==true * @param reqWidth * The requested width of the resulting bitmap * @param reqHeight * The requested height of the resulting bitmap * @return The value to be used for inSampleSize */ public static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) { // Raw height and width of image final int height = options.outHeight; final int width = options.outWidth; int inSampleSize = 1; if (height > reqHeight || width > reqWidth) { if (width > height) { inSampleSize = Math.round((float) height / (float) reqHeight); } else { inSampleSize = Math.round((float) width / (float) reqWidth); } // This offers some additional logic in case the image has a strange // aspect ratio. For example, a panorama may have a much larger // width than height. In these cases the total pixels might still // end up being too large to fit comfortably in memory, so we should // be more aggressive with sample down the image (=larger // inSampleSize). final float totalPixels = width * height; // Anything more than 2x the requested pixels we'll sample down // further. final float totalReqPixelsCap = reqWidth * reqHeight * 2; while (totalPixels / (inSampleSize * inSampleSize) > totalReqPixelsCap) { inSampleSize++; } } return inSampleSize; } public static boolean saveBitmap(String path, Bitmap bitmap) { return saveBitmap(new File(path), bitmap); } /** 保存图片到文件 */ public static boolean saveBitmap(File f, Bitmap bitmap) { if (bitmap == null || bitmap.isRecycled()) return false; FileOutputStream fOut = null; try { if (f.exists()) f.createNewFile(); fOut = new FileOutputStream(f); bitmap.compress(Bitmap.CompressFormat.PNG, 100, fOut); fOut.flush(); return true; } catch (FileNotFoundException e) { Logger.e(e); } catch (IOException e) { Logger.e(e); } catch (Exception e) { Logger.e(e); } finally { if (fOut != null) { try { fOut.close(); } catch (IOException e) { Logger.e(e); } } } return false; } public static Bitmap decodeUriAsBitmap(Context ctx, Uri uri) { Bitmap bitmap = null; try { final BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; // options.outWidth = reqWidth; // options.outHeight = reqHeight; BitmapFactory.decodeStream(ctx.getContentResolver() .openInputStream(uri), null, options); Logger.i("orgi:" + options.outWidth + "x" + options.outHeight); int be = (int) (options.outHeight / (float) 350); if (be <= 0) be = 1; options.inSampleSize = be;// calculateInSampleSize(options, // reqWidth, reqHeight); Logger.i("inSampleSize:" + options.inSampleSize); options.inJustDecodeBounds = false; bitmap = BitmapFactory.decodeStream(ctx.getContentResolver() .openInputStream(uri), null, options); } catch (FileNotFoundException e) { Logger.e(e); } catch (OutOfMemoryError e) { Logger.e(e); } return bitmap; } public static Bitmap zoomBitmap(Bitmap bitmap, int w, int h) { int width = bitmap.getWidth(); int height = bitmap.getHeight(); Matrix matrix = new Matrix(); float scaleWidht = ((float) w / width); float scaleHeight = ((float) h / height); matrix.postScale(scaleWidht, scaleHeight); Bitmap newbmp = Bitmap.createBitmap(bitmap, 0, 0, width, height, matrix, true); return newbmp; } public static Bitmap drawableToBitmap(Drawable drawable) { int width = drawable.getIntrinsicWidth(); int height = drawable.getIntrinsicHeight(); Bitmap bitmap = Bitmap.createBitmap(width, height, drawable .getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888 : Bitmap.Config.RGB_565); Canvas canvas = new Canvas(bitmap); drawable.setBounds(0, 0, width, height); drawable.draw(canvas); return bitmap; } /** * 获取图片圆角 * * @param bitmap * @param roundPx * 圆角度数 * @return */ public static Bitmap getRoundedCornerBitmap(Bitmap bitmap, float roundPx) { Bitmap output = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Config.ARGB_8888); Canvas canvas = new Canvas(output); final int color = 0xff424242; final Paint paint = new Paint(); final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight()); final RectF rectF = new RectF(rect); paint.setAntiAlias(true); canvas.drawARGB(0, 0, 0, 0); paint.setColor(color); canvas.drawRoundRect(rectF, roundPx, roundPx, paint); paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN)); canvas.drawBitmap(bitmap, rect, rect, paint); return output; } /** * 转行Drawable为Bitmap对象 * * @param drawable * @return */ public static Bitmap toBitmap(Drawable drawable) { int width = drawable.getIntrinsicWidth(); int height = drawable.getIntrinsicHeight(); Bitmap bitmap = Bitmap.createBitmap(width, height, drawable .getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888 : Bitmap.Config.RGB_565); Canvas canvas = new Canvas(bitmap); drawable.setBounds(0, 0, width, height); drawable.draw(canvas); return bitmap; } /** * 缩放图片 * * @param src * 缩放原图 * @param dstWidth * 缩放后宽 * @param dstHeight * 缩放后高 * @return */ public static Bitmap scaledBitmap(Bitmap src, int dstWidth, int dstHeight) { // 原图不能为空也不能已经被回收掉了 Bitmap result = null; if (src != null && !src.isRecycled()) { if (src.getWidth() == dstWidth && src.getHeight() == dstHeight) { result = src; } else { result = Bitmap.createScaledBitmap(src, dstWidth, dstHeight, true); } } // ThumbnailUtils.extractThumbnail(source, width, height) return result; } /** * 按比例缩放图片 * * @param src * @param scale * 例如2 就是二分之一 * @return */ public static Bitmap scaledBitmap(Bitmap src, int scale) { if (src == null || src.isRecycled()) { return null; } int dstWidth = src.getWidth() / scale; int dstHeight = src.getHeight() / scale; return Bitmap.createScaledBitmap(src, dstWidth, dstHeight, true); } /** * 将图片转换成字节数组 * * @param bitmap * @return */ public static byte[] toBytes(Bitmap bitmap) { ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); bitmap.compress(Bitmap.CompressFormat.PNG, 100, outputStream); return outputStream.toByteArray(); } }