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();
}
}