content: package com.cjj.bb.utils;
  
  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 android.graphics.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 ? Config.ARGB_8888
  				: 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 ? Config.ARGB_8888
  				: 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();
  	}
  }
  