package com.streamlet.common.util;
import android.app.Activity;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
import android.graphics.BitmapFactory.Options;
import android.graphics.BlurMaskFilter;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.LinearGradient;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Shader;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.util.DisplayMetrics;
import android.view.Display;
import android.view.View;
import android.view.WindowManager;
import com.streamlet.base.Constant;
import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.util.Calendar;
import java.util.Date;
public class BitmapUtil {
private final static String TAG = BitmapUtil.class.getSimpleName();
public static Uri uri;
public static String fileName = "";
/**
* 计算缩放比例
*
* filename 图片路径 maxWidth 目标宽度 maxHeight 目标高度
*/
public static Bitmap scalePicture(String filename, int maxWidth, int maxHeight) {
Bitmap bitmap = null;
try {
Options opts = new Options();
opts.inJustDecodeBounds = true;
BitmapFactory.decodeFile(filename, opts);
int srcWidth = opts.outWidth;
int srcHeight = opts.outHeight;
int desWidth = 0;
int desHeight = 0;
// 缩放比例
double ratio = 0.0;
if (srcWidth > srcHeight) {
ratio = srcWidth / maxWidth;
desWidth = maxWidth;
desHeight = (int) (srcHeight / ratio);
} else {
ratio = srcHeight / maxHeight;
desHeight = maxHeight;
desWidth = (int) (srcWidth / ratio);
}
// 设置输出宽度、高度
Options newOpts = new Options();
newOpts.inSampleSize = (int) (ratio) + 1;
newOpts.inJustDecodeBounds = false;
newOpts.outWidth = desWidth;
newOpts.outHeight = desHeight;
bitmap = BitmapFactory.decodeFile(filename, newOpts);
} catch (Throwable e) {
e.printStackTrace();
}
return bitmap;
}
/**
* 计算缩放比例
*
* srcBitmap 原图 目标宽度 目标高度
*/
public static Bitmap scalePicture(Bitmap srcBitmap, int maxWidth, int maxHeight) {
try {
Bitmap bitmap = null;
int srcWidth = srcBitmap.getWidth();
int srcHeight = srcBitmap.getHeight();
// 计算缩放率,新尺寸除原始尺寸
float scaleWidth = ((float) maxWidth) / srcWidth;
float scaleHeight = ((float) maxHeight) / srcHeight;
// 创建操作图片用的matrix对象
Matrix matrix = new Matrix();
// 缩放图片动作
matrix.postScale(scaleWidth, scaleHeight);
// 创建新的图片
bitmap = Bitmap.createBitmap(srcBitmap, 0, 0, srcWidth, srcHeight, matrix, true);
return bitmap;
} catch (Throwable t) {
t.printStackTrace();
System.gc();
}
return srcBitmap;
}
public static Bitmap createBitmap(String bmPath, Options opt) {
try {
opt.inPreferredConfig = Config.RGB_565;
opt.inPurgeable = true;
opt.inInputShareable = true;
FileInputStream fis = new FileInputStream(bmPath);
return BitmapFactory.decodeStream(fis, null, opt);
} catch (Throwable t) {
LogUtil.log(t);
}
return null;
}
public static Bitmap createBitmap(Context context, int resId) {
Bitmap bmp;
Resources res = context.getResources();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
bmp = BitmapFactory.decodeResource(res, resId);
} else {
BitmapFactory.Options opt = new BitmapFactory.Options();
opt.inPreferredConfig = Bitmap.Config.RGB_565;
/**
* 如果 inPurgeable 设为True的话表示使用BitmapFactory创建的Bitmap 用于存储Pixel的内存空间在系统内存不足时可以被回收,
* 在应用需要再次访问Bitmap的Pixel时(如绘制Bitmap或是调用getPixel), 系统会再次调用BitmapFactory decoder重新生成Bitmap的Pixel数组。
* 为了能够重新解码图像,bitmap要能够访问存储Bitmap的原始数据。
*
* 在inPurgeable为false时表示创建的Bitmap的Pixel内存空间不能被回收, 这样BitmapFactory在不停decodeByteArray创建新的Bitmap对象,
* 不同设备的内存不同,因此能够同时创建的Bitmap个数可能有所不同, 200个bitmap足以使大部分的设备重新OutOfMemory错误。 当isPurgable设为true时,系统中内存不足时,
* 可以回收部分Bitmap占据的内存空间,这时一般不会出现OutOfMemory 错误。
* API 21 时被忽略
*/
opt.inPurgeable = true;
/**
* 配合inPurgeable使用,决定bitmap是否可以共享加载图片数据的引用,如果是false重新创建时会使用深层拷贝
*/
opt.inInputShareable = true;
bmp = BitmapFactory.decodeResource(res, resId, opt);
}
return bmp;
}
public static Bitmap createBitmap(Bitmap oriBm) {
try {
return Bitmap.createBitmap(oriBm);
} catch (OutOfMemoryError e) {
System.gc();
LogUtil.log(e);
try {
LogUtil.e("System.out", "try to creat the bitmap again");
return Bitmap.createBitmap(oriBm);
} catch (Throwable t) {
LogUtil.log(t);
}
} catch (Throwable t) {
LogUtil.log(t);
} finally {
System.gc();
}
return null;
}
public static Bitmap createBitmap(Bitmap source, int x, int y, int width, int height, Matrix m, boolean filter) {
try {
return Bitmap.createBitmap(source, x, y, width, height, m, filter);
} catch (OutOfMemoryError e) {
System.gc();
LogUtil.log(e);
try {
LogUtil.e("System.out", "try to creat the bitmap again");
return Bitmap.createBitmap(source, x, y, width, height, m, filter);
} catch (Throwable t) {
LogUtil.log(t);
}
} catch (Throwable t) {
LogUtil.log(t);
} finally {
System.gc();
}
return null;
}
public static Bitmap createBitmap(int width, int height, Config config) {
try {
return Bitmap.createBitmap(width, height, config);
} catch (OutOfMemoryError e) {
System.gc();
LogUtil.log(e);
try {
LogUtil.e("System.out", "try to creat the bitmap again");
return Bitmap.createBitmap(width, height, config);
} catch (Throwable t) {
LogUtil.log(t);
}
} catch (Throwable t) {
LogUtil.log(t);
} finally {
System.gc();
}
return null;
}
public static Bitmap createBitmap(Bitmap source, int x, int y, int width, int height) {
try {
return Bitmap.createBitmap(source, x, y, width, height);
} catch (OutOfMemoryError e) {
System.gc();
LogUtil.log(e);
try {
LogUtil.e("System.out", "try to creat the bitmap again");
return Bitmap.createBitmap(source, x, y, width, height);
} catch (Throwable t) {
LogUtil.log(t);
}
} catch (Throwable t) {
LogUtil.log(t);
} finally {
System.gc();
}
return null;
}
public static Bitmap createBitmap(InputStream is) {
Options opt = new Options();
opt.inPreferredConfig = Config.RGB_565;
opt.inPurgeable = true;
opt.inInputShareable = true;
// opt.inSampleSize = 2;
return BitmapFactory.decodeStream(is, null, opt);
}
/** 使用c层代码早图片 */
public static Bitmap createBitmap(String path) {
FileInputStream fis = null;
try {
fis = new FileInputStream(path);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
return createBitmap(fis);
}
/** 回收不使用的bitmap */
public static void recyledBitmap(Bitmap bitmap) {
try {
if (bitmap != null) {
if (!bitmap.isRecycled()) {
bitmap.recycle();
bitmap = null;
}
}
System.gc();
} catch (Throwable e) {
e.printStackTrace();
}
}
/** 获取指定View的截图 */
public static Bitmap captureView(View view) throws Throwable {
view.setDrawingCacheEnabled(true);
view.buildDrawingCache();
Bitmap bmShare = view.getDrawingCache();
if (bmShare == null) {
// 使用反射,强制将mViewFlags设置为正确的数值
Field mViewFlagsField = View.class.getDeclaredField("mViewFlags");
mViewFlagsField.setAccessible(true);
mViewFlagsField.set(view, Integer.valueOf(402685952));
bmShare = view.getDrawingCache();
}
return bmShare;
}
/** 获取屏幕的截图 */
public static String captureView(Context context, String filename) {
String path = Constant.TEMPORARY_FILE_PATH + filename;
try {
WindowManager windowManager = ((Activity) context).getWindowManager();
Display display = windowManager.getDefaultDisplay();
int w = display.getWidth();
int h = display.getHeight();
Bitmap bmShare = Bitmap.createBitmap(w, h, Config.ARGB_8888);
// 2.获取屏幕
View decorview = ((Activity) context).getWindow().getDecorView();
decorview.setDrawingCacheEnabled(true);
bmShare = decorview.getDrawingCache();
CompressFormat format = CompressFormat.JPEG;
OutputStream stream = new FileOutputStream(path);
bmShare.compress(format, 100, stream);
} catch (Exception e) {
e.printStackTrace();
}
return path;
}
/**
* 创建指定bitmap的倒影bitmap
*
* @param bitmap
* 原始的图片
* @param refMargin
* 倒影和原图之间的距离
* @param refLeng
* 倒影的长度
*/
public static Bitmap getInvertedImage(Bitmap bitmap, int refMargin, int refLeng) {
int width = bitmap.getWidth();
int bmHeight = bitmap.getHeight();
int height = bmHeight + refMargin + refLeng;
Bitmap bm = Bitmap.createBitmap(width, height, Config.ARGB_8888);
Canvas canvas = new Canvas();
canvas.setBitmap(bm);
Paint paint = new Paint();
canvas.drawBitmap(bitmap, 0, 0, paint);
if (refLeng > 0) {
Matrix matrix = new Matrix();
matrix.preScale(1, -1);
Bitmap refBm = Bitmap.createBitmap(bitmap, 0, bmHeight - refLeng, width, refLeng, matrix, false);
canvas.drawBitmap(refBm, 0, bmHeight + refMargin, paint);
refBm.recycle();
paint.setAntiAlias(true);
LinearGradient gradient = new LinearGradient(0, bmHeight + refMargin, 0, height, 0xff000000, 0x0000000, Shader.TileMode.CLAMP);
paint.setShader(gradient);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
canvas.drawRect(0, bmHeight + refMargin, width, height, paint);
}
return bm;
}
public static Bitmap getImageReflectionPart(Bitmap bitmap, int refLeng) {
int width = bitmap.getWidth();
int bmHeight = bitmap.getHeight();
Bitmap bm = Bitmap.createBitmap(width, refLeng, Config.ARGB_8888);
Canvas canvas = new Canvas();
canvas.setBitmap(bm);
Paint paint = new Paint();
Matrix matrix = new Matrix();
matrix.preScale(1, -1);
Bitmap refBm = createBitmap(bitmap, 0, 0, width, bmHeight, matrix, true);
canvas.drawBitmap(refBm, 0, 0, paint);
refBm.recycle();
paint.setAntiAlias(true);
LinearGradient gradient = new LinearGradient(0, 0, 0, refLeng, 0xc0000000, 0x00000000, Shader.TileMode.CLAMP);
paint.setShader(gradient);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
canvas.drawRect(0, 0, width, refLeng, paint);
return bm;
}
/**
* 生成阴影
*
* @param bitmap
* @param shadow
* @return
*/
public static Bitmap getShadowBitmap(Bitmap bitmap, int shadow) {
if (shadow <= 0) {
return bitmap;
}
BlurMaskFilter filter = new BlurMaskFilter(shadow, BlurMaskFilter.Blur.OUTER);
Paint shadowPaint = new Paint();
shadowPaint.setMaskFilter(filter);
int[] offsetXY = new int[] { shadow, shadow };
return bitmap.extractAlpha(shadowPaint, offsetXY);
}
/**
* 获取图片的分辨率
*
* @param path
* @return
* @throws Throwable
*/
public static int[] getBitmapSize(String path) throws Throwable {
Options opt = new Options();
opt.inJustDecodeBounds = true;
opt.inPreferredConfig = Config.RGB_565;
opt.inPurgeable = true;
opt.inInputShareable = true;
FileInputStream fis = new FileInputStream(path);
BitmapFactory.decodeStream(fis, null, opt);
int[] size = new int[] { opt.outWidth, opt.outHeight };
return size;
}
/**
* TODO 图片按比例大小压缩方法(根据路径获取图片并压缩)
*
* @param srcPath
* SD卡路径
* @param reqWidth
* 需要的宽度
* @param reqHeight
* 需要的高度
* @return Bitmap
*/
public static Bitmap CompressImageByPath(String srcPath, int reqWidth, int reqHeight) {
Options op = new Options();
op.inJustDecodeBounds = true;// 只是读图片的属性
BitmapFactory.decodeFile(srcPath, op);
if (reqWidth == 0 && reqHeight == 0) {
reqWidth = op.outWidth;
reqHeight = op.outHeight;
}
op.inSampleSize = computeSampleSize(op, -1, reqWidth * reqHeight);// 设置缩放比例
op.inJustDecodeBounds = false;
op.inPreferredConfig = Config.RGB_565;
return compressImage(BitmapFactory.decodeFile(srcPath, op), 80);// 压缩好比例大小后再进行质量压缩
}
/**
* 动态计算图片缩放大小的方法
*
* @param options
* @param minSideLength
* @param maxNumOfPixels
* @return
*/
public static int computeSampleSize(Options options, int minSideLength, int maxNumOfPixels) {
int initialSize = computeInitialSampleSize(options, minSideLength, maxNumOfPixels);
int roundedSize;
if (initialSize <= 8) {
roundedSize = 1;
while (roundedSize < initialSize) {
roundedSize <<= 1;
}
} else {
roundedSize = (initialSize + 7) / 8 * 8;
}
return roundedSize;
}
private static int computeInitialSampleSize(Options options, int minSideLength, int maxNumOfPixels) {
double w = options.outWidth;
double h = options.outHeight;
int lowerBound = (maxNumOfPixels == -1) ? 1 : (int) Math.ceil(Math.sqrt(w * h / maxNumOfPixels));
int upperBound = (minSideLength == -1) ? 128 : (int) Math.min(Math.floor(w / minSideLength), Math.floor(h / minSideLength));
if (upperBound < lowerBound) {
// return the larger one when there is no overlapping zone.
return lowerBound;
}
if ((maxNumOfPixels == -1) && (minSideLength == -1)) {
return 1;
} else if (minSideLength == -1) {
return lowerBound;
} else {
return upperBound;
}
}
/**
*
* 质量压缩方法
*
* bitmap源 options开始压缩的质量 《=100
*
* @return 压缩之后的bitmap
*/
public static Bitmap compressImage(Bitmap bitmap, int options) {
Bitmap bit = null;
try {
if (null == bitmap) {
return bit;
}
ByteArrayOutputStream bout = new ByteArrayOutputStream();
bitmap.compress(CompressFormat.JPEG, options, bout);// 质量压缩
// 100
// 表示不压缩
System.out.println("*****************大少****************:" + bout.toByteArray().length / 1024);
ByteArrayInputStream isBm = new ByteArrayInputStream(bout.toByteArray());// 把压缩后的数据baos存放到ByteArrayInputStream中
bit = BitmapFactory.decodeStream(isBm, null, null);// 把ByteArrayInputStream数据生成图片
bout.flush();
bout.close();
isBm.close();
if (!bitmap.isRecycled()) {
bitmap.recycle();// 记得释放资源,否则会内存溢出
}
} catch (IOException e) {
e.printStackTrace();
}
return bit;
}
public static boolean storageState() {
String status = Environment.getExternalStorageState();
if (status.equals(Environment.MEDIA_MOUNTED)) {
return true;
} else {
return false;
}
}
// 压缩并获得流用于上传
public static InputStream getISByBitmap(Bitmap bitmap) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
// 得到输出流
bitmap.compress(CompressFormat.PNG, 100, baos);
// 转输入流
InputStream isBm = new ByteArrayInputStream(baos.toByteArray());
return isBm;
}
// 根据时间创建名字
public static String callTime() {
long backTime = new Date().getTime();
Calendar cal = Calendar.getInstance();
cal.setTime(new Date(backTime));
int year = cal.get(Calendar.YEAR);
int month = cal.get(Calendar.MONTH) + 1;
int date = cal.get(Calendar.DAY_OF_MONTH);
int hour = cal.get(Calendar.HOUR_OF_DAY);
int minute = cal.get(Calendar.MINUTE);
int second = cal.get(Calendar.SECOND);
String time = "" + year + month + date + hour + minute + second;
return time;
}
public static Bitmap getScreenBitmap(View v) {
View view = v.getRootView();
view.setDrawingCacheEnabled(true);
view.buildDrawingCache();
Bitmap bitmap = view.getDrawingCache();
bitmap = compressImage(bitmap);
return bitmap;
}
/**
* 将Bitmap压缩到一定程度
*
* @param image
* @return
*/
public static Bitmap compressImage(Bitmap image) {
Bitmap bitmap;
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
image.compress(CompressFormat.JPEG, 100, baos);// 质量压缩方法,这里100表示不压缩,把压缩后的数据存放到baos中
int options = 100;
while (baos.toByteArray().length / 1024 > 100) { // 循环判断如果压缩后图片是否大于100kb,大于继续压缩
baos.reset();// 重置baos即清空baos
image.compress(CompressFormat.JPEG, options, baos);// 这里压缩options%,把压缩后的数据存放到baos中
options -= 10;// 每次都减少10
}
ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());// 把压缩后的数据baos存放到ByteArrayInputStream中
bitmap = BitmapFactory.decodeStream(isBm, null, null);// 把ByteArrayInputStream数据生成图片
isBm.reset();
isBm.close();
} catch (Exception e) {
bitmap = image;
}
return bitmap;
}
/**
* 截图功能
*
* View v 返回byte[]
*/
public static byte[] shotScreen(View v) {
byte[] buff = null;
Bitmap bitmap = getScreenBitmap(v);
if (bitmap != null) {
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(CompressFormat.JPEG, 100, stream);// (0 -
// 100)压缩文件
buff = stream.toByteArray();
System.out.println("bitmap got!");
return buff;
} else {
return null;
}
}
public static byte[] bmpToByteArray(final Bitmap bmp, final boolean needRecycle) {
ByteArrayOutputStream output = new ByteArrayOutputStream();
bmp.compress(CompressFormat.PNG, 100, output);
if (needRecycle) {
bmp.recycle();
}
byte[] result = output.toByteArray();
try {
output.close();
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
// byte(字节)根据长度转成kb(千字节)和mb(兆字节)
public static int bytes2kb(long bytes) {
BigDecimal filesize = new BigDecimal(bytes);
BigDecimal megabyte = new BigDecimal(1024 * 1024);
float returnValue = filesize.divide(megabyte, 2, BigDecimal.ROUND_UP).floatValue();
if (returnValue > 2) {
return 8;
} else if (returnValue > 1) {
return 6;
}
BigDecimal kilobyte = new BigDecimal(1024);
returnValue = filesize.divide(kilobyte, 2, BigDecimal.ROUND_UP).floatValue();
if (returnValue >= 700) {
return 4;
} else if (returnValue >= 500) {
return 3;
} else if (returnValue >= 300) {
return 2;
} else {
return 1;
}
}
public static Bitmap compressImage(Bitmap image, int reqWidth, int reqHeight) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
image.compress(CompressFormat.JPEG, 100, baos);
if (baos.toByteArray().length / 1024 > 1024) {// 判断如果图片大于1M,进行压缩避免在生成图片(BitmapFactory.decodeStream)时溢出
baos.reset();// 重置baos即清空baos
image.compress(CompressFormat.JPEG, 50, baos);// 这里压缩50%,把压缩后的数据存放到baos中
}
ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());
Options newOpts = new Options();
// 开始读入图片,此时把options.inJustDecodeBounds 设回true了
newOpts.inJustDecodeBounds = true;
Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, newOpts);
newOpts.inJustDecodeBounds = false;
int w = newOpts.outWidth;
int h = newOpts.outHeight;
// 现在主流手机比较多是800*480分辨率,所以高和宽我们设置为
float hh = reqHeight;// 这里设置高度为800f
float ww = reqWidth;// 这里设置宽度为480f
// 缩放比。由于是固定比例缩放,只用高或者宽其中一个数据进行计算即可
int be = 1;// be=1表示不缩放
if (w > h && w > ww) {// 如果宽度大的话根据宽度固定大小缩放
be = (int) (newOpts.outWidth / ww);
} else if (w < h && h > hh) {// 如果高度高的话根据宽度固定大小缩放
be = (int) (newOpts.outHeight / hh);
}
if (be <= 0)
be = 1;
newOpts.inSampleSize = be;// 设置缩放比例
// 重新读入图片,注意此时已经把options.inJustDecodeBounds 设回false了
isBm = new ByteArrayInputStream(baos.toByteArray());
bitmap = BitmapFactory.decodeStream(isBm, null, newOpts);
return compressImage(bitmap);// 压缩好比例大小后再进行质量压缩
}
// 写到sdcard中
public static void write(Bitmap bm) throws IOException {
if (bm == null) {
return;
}
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bm.compress(CompressFormat.PNG, 100, baos);// png类型
FileOutputStream out = new FileOutputStream(new File(Environment.getExternalStorageDirectory() + File.separator + "tesstttt.png"));
out.write(baos.toByteArray());
out.flush();
out.close();
}
/**
*
* @param x
* 图像的宽度
* @param y
* 图像的高度
* @param image
* 源图片
* @param outerRadiusRat
* 圆角的大小
* @return 圆角图片
*/
public static Bitmap createFramedPhoto(int x, int y, Bitmap image, float outerRadiusRat) {
// 根据源文件新建一个darwable对象
Drawable imageDrawable = new BitmapDrawable(image);
// 新建一个新的输出图片
Bitmap output = Bitmap.createBitmap(x, y, Config.ARGB_8888);
Canvas canvas = new Canvas(output);
// 新建一个矩形
RectF outerRect = new RectF(0, 0, x, y);
// 产生一个红色的圆角矩形
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setColor(Color.RED);
canvas.drawRoundRect(outerRect, outerRadiusRat, outerRadiusRat, paint);
// 将源图片绘制到这个圆角矩形上
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
imageDrawable.setBounds(0, 0, x, y);
canvas.saveLayer(outerRect, paint, Canvas.ALL_SAVE_FLAG);
imageDrawable.draw(canvas);
canvas.restore();
return output;
}
public static Bitmap revitionImageSize(String path) throws IOException {
BufferedInputStream in = new BufferedInputStream(new FileInputStream(new File(path)));
Options options = new Options();
options.inJustDecodeBounds = true;
// Bitmap btBitmap=BitmapFactory.decodeFile(path);
// System.out.println("原尺寸高度:"+btBitmap.getHeight());
// System.out.println("原尺寸宽度:"+btBitmap.getWidth());
BitmapFactory.decodeStream(in, null, options);
in.close();
int i = 0;
Bitmap bitmap = null;
while (true) {
if ((options.outWidth >> i <= 800) && (options.outHeight >> i <= 800)) {
in = new BufferedInputStream(new FileInputStream(new File(path)));
options.inSampleSize = (int) Math.pow(2.0D, i);
options.inJustDecodeBounds = false;
bitmap = BitmapFactory.decodeStream(in, null, options);
break;
}
i += 1;
}
// 当机型为三星时图片翻转
// bitmap = Photo.photoAdapter(path, bitmap);
// System.out.println("-----压缩后尺寸高度:" + bitmap.getHeight());
// System.out.println("-----压缩后尺寸宽度度:" + bitmap.getWidth());
return bitmap;
}
public static Bitmap getLoacalBitmap(String url) {
try {
FileInputStream fis = new FileInputStream(url);
return BitmapFactory.decodeStream(fis); // /把流转化为Bitmap图片
} catch (FileNotFoundException e) {
e.printStackTrace();
return null;
}
}
/** 手机截屏 */
public static Bitmap takeScreenShot(Activity activity) {
// View是你需要截图的View
View view = activity.getWindow().getDecorView();
view.setDrawingCacheEnabled(true);
view.buildDrawingCache();
Bitmap b1 = view.getDrawingCache();
// 获取状态栏高度
Rect frame = new Rect();
activity.getWindow().getDecorView().getWindowVisibleDisplayFrame(frame);
int statusBarHeight = frame.top;
System.out.println(statusBarHeight);// 获取屏幕长和高
int width = activity.getWindowManager().getDefaultDisplay().getWidth();
int height = activity.getWindowManager().getDefaultDisplay().getHeight();// 去掉标题栏
// Bitmap b = Bitmap.createBitmap(b1, 0, 25, 320, 455);
Bitmap b = Bitmap.createBitmap(b1, 0, statusBarHeight, width, height - statusBarHeight);
view.destroyDrawingCache();
return b;
}
/**
* @param context
* @return
*/
public static int getScreenHeight(Context context) {
if (null == context) {
return 0;
}
DisplayMetrics dm = new DisplayMetrics();
dm = context.getApplicationContext().getResources().getDisplayMetrics();
return dm.heightPixels;
}
//api4.2以上才能使用的毛玻璃效果图
/*private void blur(Context context,Bitmap bkg, View view, float radius) {
Bitmap overlay = Bitmap.createBitmap(view.getMeasuredWidth(), view.getMeasuredHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(overlay);
canvas.drawBitmap(bkg, -view.getLeft(), -view.getTop(), null);
RenderScript rs = RenderScript.create(context);
Allocation overlayAlloc = Allocation.createFromBitmap(rs, overlay);
ScriptIntrinsicBlur blur = ScriptIntrinsicBlur.create(rs, overlayAlloc.getElement());
blur.setInput(overlayAlloc);
blur.setRadius(radius);
blur.forEach(overlayAlloc);
overlayAlloc.copyTo(overlay);
view.setBackground(new BitmapDrawable(context.getResources(), overlay));
rs.destroy();
} */
/**毛玻璃效果图*/
public static Bitmap fastblur(Bitmap sentBitmap, int radius) {
// Stack Blur v1.0 from
// http://www.quasimondo.com/StackBlurForCanvas/StackBlurDemo.html
//
// Java Author: Mario Klingemann <mario at quasimondo.com>
// http://incubator.quasimondo.com
// created Feburary 29, 2004
// Android port : Yahel Bouaziz <yahel at kayenko.com>
// http://www.kayenko.com
// ported april 5th, 2012
// This is a compromise between Gaussian Blur and Box blur
// It creates much better looking blurs than Box Blur, but is
// 7x faster than my Gaussian Blur implementation.
//
// I called it Stack Blur because this describes best how this
// filter works internally: it creates a kind of moving stack
// of colors whilst scanning through the image. Thereby it
// just has to add one new block of color to the right side
// of the stack and remove the leftmost color. The remaining
// colors on the topmost layer of the stack are either added on
// or reduced by one, depending on if they are on the right or
// on the left side of the stack.
//
// If you are using this algorithm in your code please add
// the following line:
//
// Stack Blur Algorithm by Mario Klingemann <mario@quasimondo.com>
Bitmap bitmap = sentBitmap.copy(sentBitmap.getConfig(), true);
if (radius < 1) {
return (null);
}
int w = bitmap.getWidth();
int h = bitmap.getHeight();
int[] pix = new int[w * h];
bitmap.getPixels(pix, 0, w, 0, 0, w, h);
int wm = w - 1;
int hm = h - 1;
int wh = w * h;
int div = radius + radius + 1;
int r[] = new int[wh];
int g[] = new int[wh];
int b[] = new int[wh];
int rsum, gsum, bsum, x, y, i, p, yp, yi, yw;
int vmin[] = new int[Math.max(w, h)];
int divsum = (div + 1) >> 1;
divsum *= divsum;
int dv[] = new int[256 * divsum];
for (i = 0; i < 256 * divsum; i++) {
dv[i] = (i / divsum);
}
yw = yi = 0;
int[][] stack = new int[div][3];
int stackpointer;
int stackstart;
int[] sir;
int rbs;
int r1 = radius + 1;
int routsum, goutsum, boutsum;
int rinsum, ginsum, binsum;
for (y = 0; y < h; y++) {
rinsum = ginsum = binsum = routsum = goutsum = boutsum = rsum = gsum = bsum = 0;
for (i = -radius; i <= radius; i++) {
p = pix[yi + Math.min(wm, Math.max(i, 0))];
sir = stack[i + radius];
sir[0] = (p & 0xff0000) >> 16;
sir[1] = (p & 0x00ff00) >> 8;
sir[2] = (p & 0x0000ff);
rbs = r1 - Math.abs(i);
rsum += sir[0] * rbs;
gsum += sir[1] * rbs;
bsum += sir[2] * rbs;
if (i > 0) {
rinsum += sir[0];
ginsum += sir[1];
binsum += sir[2];
} else {
routsum += sir[0];
goutsum += sir[1];
boutsum += sir[2];
}
}
stackpointer = radius;
for (x = 0; x < w; x++) {
r[yi] = dv[rsum];
g[yi] = dv[gsum];
b[yi] = dv[bsum];
rsum -= routsum;
gsum -= goutsum;
bsum -= boutsum;
stackstart = stackpointer - radius + div;
sir = stack[stackstart % div];
routsum -= sir[0];
goutsum -= sir[1];
boutsum -= sir[2];
if (y == 0) {
vmin[x] = Math.min(x + radius + 1, wm);
}
p = pix[yw + vmin[x]];
sir[0] = (p & 0xff0000) >> 16;
sir[1] = (p & 0x00ff00) >> 8;
sir[2] = (p & 0x0000ff);
rinsum += sir[0];
ginsum += sir[1];
binsum += sir[2];
rsum += rinsum;
gsum += ginsum;
bsum += binsum;
stackpointer = (stackpointer + 1) % div;
sir = stack[(stackpointer) % div];
routsum += sir[0];
goutsum += sir[1];
boutsum += sir[2];
rinsum -= sir[0];
ginsum -= sir[1];
binsum -= sir[2];
yi++;
}
yw += w;
}
for (x = 0; x < w; x++) {
rinsum = ginsum = binsum = routsum = goutsum = boutsum = rsum = gsum = bsum = 0;
yp = -radius * w;
for (i = -radius; i <= radius; i++) {
yi = Math.max(0, yp) + x;
sir = stack[i + radius];
sir[0] = r[yi];
sir[1] = g[yi];
sir[2] = b[yi];
rbs = r1 - Math.abs(i);
rsum += r[yi] * rbs;
gsum += g[yi] * rbs;
bsum += b[yi] * rbs;
if (i > 0) {
rinsum += sir[0];
ginsum += sir[1];
binsum += sir[2];
} else {
routsum += sir[0];
goutsum += sir[1];
boutsum += sir[2];
}
if (i < hm) {
yp += w;
}
}
yi = x;
stackpointer = radius;
for (y = 0; y < h; y++) {
// Preserve alpha channel: ( 0xff000000 & pix[yi] )
pix[yi] = ( 0xff000000 & pix[yi] ) | ( dv[rsum] << 16 ) | ( dv[gsum] << 8 ) | dv[bsum];
rsum -= routsum;
gsum -= goutsum;
bsum -= boutsum;
stackstart = stackpointer - radius + div;
sir = stack[stackstart % div];
routsum -= sir[0];
goutsum -= sir[1];
boutsum -= sir[2];
if (x == 0) {
vmin[y] = Math.min(y + r1, hm) * w;
}
p = x + vmin[y];
sir[0] = r[p];
sir[1] = g[p];
sir[2] = b[p];
rinsum += sir[0];
ginsum += sir[1];
binsum += sir[2];
rsum += rinsum;
gsum += ginsum;
bsum += binsum;
stackpointer = (stackpointer + 1) % div;
sir = stack[stackpointer];
routsum += sir[0];
goutsum += sir[1];
boutsum += sir[2];
rinsum -= sir[0];
ginsum -= sir[1];
binsum -= sir[2];
yi += w;
}
}
bitmap.setPixels(pix, 0, w, 0, 0, w, h);
return (bitmap);
}
/**将制定的Bitmap保存到文件*/
public static void savePic(Bitmap b, String strFileName){
FileOutputStream fos = null;
try {
fos = new FileOutputStream(strFileName);
if (null != fos)
{
b.compress(CompressFormat.PNG, 90, fos);
fos.flush();
fos.close();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}