1. 获取本机图片的路径:
public static String handleImageOnKitKat(Context context, Intent data) {
Uri uri = data.getData();
if (DocumentsContract.isDocumentUri(context, uri)) {
String docId = DocumentsContract.getDocumentId(uri);
if ("com.android.providers.media.documents".equals(uri.getAuthority())) {
String id = docId.split(":")[1];
String selection = MediaStore.Images.Media._ID + "=" + id;
String type = docId.split(":")[0];
Uri contentUri = null;
if (type.equalsIgnoreCase("image")) {
contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
} else if (type.equalsIgnoreCase("audio")) {
contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
} else if (type.equalsIgnoreCase("video")) {
contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
}
return getImagePath(context, contentUri, selection);
} else if ("com.android.providers.media.downloads.documents".equals(uri.getAuthority())) {
Uri contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"),
Long.valueOf(docId));
return getImagePath(context, contentUri, null);
} else if ("content".equals(uri.getAuthority())) {
return getImagePath(context, uri, null);
} else if ("file".equals(uri.getAuthority())) {
return uri.getPath();
}
}
return "";
}
private static String getImagePath(Context context, Uri uri, String selection) {
String path = null;
Cursor cursor = context.getContentResolver().query(uri, null, selection, null, null);
if (cursor != null) {
if (cursor.moveToFirst()) {
path = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA));
}
cursor.close();
}
return path;
}
2. 根据图片路径获取Bitmap对象,并进行压缩:
public static Bitmap getImage(String srcPath) {
BitmapFactory.Options newOpts = new BitmapFactory.Options();
//开始读入图片,此时把options.inJustDecodeBounds 设回true了
newOpts.inJustDecodeBounds = true;
Bitmap bitmap = BitmapFactory.decodeFile(srcPath,newOpts);//此时返回bm为空
newOpts.inJustDecodeBounds = false;
int w = newOpts.outWidth;
int h = newOpts.outHeight;
//现在主流手机比较多是800*480分辨率,所以高和宽我们设置为
float hh = 800f;//这里设置高度为800f
float ww = 480f;//这里设置宽度为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;//设置缩放比例
Log.e(TAG,"inSampleSize="+be);
//重新读入图片,注意此时已经把options.inJustDecodeBounds 设回false了
bitmap = BitmapFactory.decodeFile(srcPath, newOpts);
return compressImage(bitmap);//压缩好比例大小后再进行质量压缩
}
public static Bitmap compressImage(Bitmap image) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
image.compress(Bitmap.CompressFormat.JPEG, 100, baos);
int options = 90;
int length = baos.toByteArray().length / 1024;
Log.e(TAG,"length="+length);
if (length>5000){
//重置baos即清空baos
baos.reset();
//质量压缩方法,这里100表示不压缩,把压缩后的数据存放到baos中
image.compress(Bitmap.CompressFormat.JPEG, 10, baos);
}else if (length>4000){
baos.reset();
image.compress(Bitmap.CompressFormat.JPEG, 20, baos);
}else if (length>3000){
baos.reset();
image.compress(Bitmap.CompressFormat.JPEG, 50, baos);
}else if (length>2000){
baos.reset();
image.compress(Bitmap.CompressFormat.JPEG, 70, baos);
}
Log.e(TAG,"baos.toByteArray().length="+baos.toByteArray().length);
//循环判断如果压缩后图片是否大于1M,大于继续压缩
while (baos.toByteArray().length / 1024>1024) {
//重置baos即清空baos
baos.reset();
//这里压缩options%,把压缩后的数据存放到baos中
image.compress(Bitmap.CompressFormat.JPEG, options, baos);
//每次都减少10
options -= 10;
}
//把压缩后的数据baos存放到ByteArrayInputStream中
ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());
//把ByteArrayInputStream数据生成图片
Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, null);
return bitmap;
}
3.保存bitmap到本地
public static String saveBitmap(Context context, Bitmap mBitmap) {
String savePath = Environment.getExternalStorageDirectory().toString() + "/nmpaapp/";
File filePic;
try {
filePic = new File(savePath + System.currentTimeMillis() + ".jpg");
Log.d("LUO", "图片地址====" + filePic);
if (!filePic.exists()) {
filePic.getParentFile().mkdirs();
filePic.createNewFile();
}
FileOutputStream fos = new FileOutputStream(filePic);
//不压缩,保存本地
mBitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos);
fos.flush();
fos.close();
} catch (IOException e) {
e.printStackTrace();
return null;
}
return filePic.getAbsolutePath();
}
4. 拍照后保存图片并返回路径:
public static String getCameraData(Intent data) {
String path = null;
Bitmap photo = null;
if (data.getData() != null || data.getExtras() != null) { // 防止没有返回结果
Uri uri = data.getData();
if (uri != null) {
photo = BitmapFactory.decodeFile(uri.getPath()); // 拿到图片
}
if (photo == null) {
Bundle bundle = data.getExtras();
if (bundle != null) {
photo = (Bitmap) bundle.get("data");
String saveDir = Environment.getExternalStorageDirectory().toString() + "/nmpaapp/";
String filename = System.currentTimeMillis() + ".jpg";
File file = new File(saveDir, filename);
FileOutputStream fileOutputStream = null;
// 打开文件输出流
try {
fileOutputStream = new FileOutputStream(file);
// 生成图片文件
photo.compress(Bitmap.CompressFormat.JPEG,
100, fileOutputStream);
path = file.getPath();
Log.e("FileLoadUtils", "str=" + path);
} catch (FileNotFoundException e) {
e.printStackTrace();
} finally {
if (fileOutputStream != null) {
try {
fileOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
}
return path;
}
5. 获取视频文件的缩略图
public static String getThumnailPath(String fromUser,String videoPath) {
String fileName = "thvideo" + System.currentTimeMillis();
// File file = new File(getMSNBasePath("5",fromUser), fileName);
File file = createFileEm("5",fileName,fromUser);
try {
FileOutputStream fos = new FileOutputStream(file);
Bitmap ThumbBitmap = ThumbnailUtils.createVideoThumbnail(videoPath, 3);
ThumbBitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos);
fos.close();
} catch (Exception e) {
e.printStackTrace();
}
return file.getAbsolutePath();
}
6. 保存文件:
public static void getFile(byte[] bfile, String fileName) {
BufferedOutputStream bos = null;
FileOutputStream fos = null;
File file = null;
try {
file = createFileEm("3",fileName,"");
fos = new FileOutputStream(file);
bos = new BufferedOutputStream(fos);
bos.write(bfile);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (bos != null) {
try {
bos.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
if (fos != null) {
try {
fos.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
}
7. 创建文件:
public static File createFile(String FileName) {
String path = Environment.getExternalStorageDirectory().toString() + "/1nmpaapp";
File file = new File(path);
/**
*如果文件夹不存在就创建
*/
if (!file.exists()) {
file.mkdirs();
}
return new File(path, FileName);
}
public static File createFileEm(String type,String FileName,String toUser) {
String path = null;
if (toUser != null && !toUser.equals("") ) {
if (type.equals("3")) {
path = BASE_PATH + toUser + "/voice/" ;
} else if (type.equals("4")) {
path = BASE_PATH + toUser + "/video/";
}else if (type.equals("6")) {
path = BASE_PATH + toUser + "/file/";
} else {
path = BASE_PATH + toUser + "/image/";
}
} else {
if (type.equals("3")) {
path = PathUtil.getInstance().getVoicePath() + "/" ;
} else if (type.equals("4")) {
path = PathUtil.getInstance().getVideoPath() + "/";
}else if (type.equals("6")) {
path = PathUtil.getInstance().getFilePath() + "/";
} else {
path = PathUtil.getInstance().getImagePath() + "/";
}
}
File file = new File(path);
/**
*如果文件夹不存在就创建
*/
if (!file.exists()) {
file.mkdirs();
}
return new File(path, FileName);
}
8. 采样率压缩(设置图片的采样率,降低图片像素)
public static void samplingRateCompress(String filePath, File file) {
// 数值越高,图片像素越低
int inSampleSize = 8;
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = false;
// options.inJustDecodeBounds = true;//为true的时候不会真正加载图片,而是得到图片的宽高信息。
//采样率
options.inSampleSize = inSampleSize;
Bitmap bitmap = BitmapFactory.decodeFile(filePath, options);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
// 把压缩后的数据存放到baos中
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);
try {
if (file.exists()) {
file.delete();
} else {
file.createNewFile();
}
FileOutputStream fos = new FileOutputStream(file);
fos.write(baos.toByteArray());
fos.flush();
fos.close();
} catch (Exception e) {
e.printStackTrace();
}
}
9. 将字节数转换为对应单位的大小
public static float formatFileSize(long size, int unit) {
if (size < 0) {
return -1;
}
switch (unit) {
case ConstUtils.KB:
return size / ConstUtils.KB;
case ConstUtils.MB:
return size / ConstUtils.MB;
case ConstUtils.GB:
return size / ConstUtils.GB;
default:
return size / ConstUtils.MB;
}
}
10. 将彩色图片转化为灰图
/**
* 将彩色图转换为灰度图
* @param img 位图
* @return 返回转换好的位图
*/
public Bitmap convertGreyImg(Bitmap img) {
int width = img.getWidth(); //获取位图的宽
int height = img.getHeight(); //获取位图的高
int[] pixels = new int[width * height]; //通过位图的大小创建像素点数组
img.getPixels(pixels, 0, width, 0, 0, width, height);
int alpha = 0xFF << 24;
for(int i = 0; i < height; i++) {
for(int j = 0; j < width; j++) {
int grey = pixels[width * i + j];
int red = ((grey & 0x00FF0000 ) >> 16);
int green = ((grey & 0x0000FF00) >> 8);
int blue = (grey & 0x000000FF);
grey = (int)((float) red * 0.3 + (float)green * 0.59 + (float)blue * 0.11);
grey = alpha | (grey << 16) | (grey << 8) | grey;
pixels[width * i + j] = grey;
}
}
Bitmap result = Bitmap.createBitmap(width, height, Config.RGB_565);
result.setPixels(pixels, 0, width, 0, 0, width, height);
return result;
}
11. 将图片转成圆角图
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;
}
12. 图片添加倒影效果
/**
* 获得带倒影的图片方法
*/
public static Bitmap createReflectionImageWithOrigin(Bitmap bitmap) {
final int reflectionGap = 4;
int width = bitmap.getWidth();
int height = bitmap.getHeight();
Matrix matrix = new Matrix();
matrix.preScale(1, -1);
Bitmap reflectionImage = Bitmap.createBitmap(bitmap, 0, height / 2,
width, height / 2, matrix, false);
Bitmap bitmapWithReflection = Bitmap.createBitmap(width,
(height + height / 2), Config.ARGB_8888);
Canvas canvas = new Canvas(bitmapWithReflection);
canvas.drawBitmap(bitmap, 0, 0, null);
Paint deafalutPaint = new Paint();
canvas.drawRect(0, height, width, height + reflectionGap, deafalutPaint);
canvas.drawBitmap(reflectionImage, 0, height + reflectionGap, null);
Paint paint = new Paint();
LinearGradient shader = new LinearGradient(0, bitmap.getHeight(), 0,
bitmapWithReflection.getHeight() + reflectionGap, 0x70ffffff,
0x00ffffff, TileMode.CLAMP);
paint.setShader(shader);
// Set the Transfer mode to be porter duff and destination in
paint.setXfermode(new PorterDuffXfermode(Mode.DST_IN));
// Draw a rectangle using the paint with our linear gradient
canvas.drawRect(0, height, width, bitmapWithReflection.getHeight()
+ reflectionGap, paint);
return bitmapWithReflection;
}
13. 添加水印
/**
* create the bitmap from a byte array 生成水印图片
*
* @param src
* 要添加水印的图片
* @param 水印
* @return 添加了水印的图片
*/
private Bitmap createBitmap(Bitmap src, Bitmap watermark) {
String tag = "createBitmap";
Log.d(tag, "create a new bitmap");
if (src == null) {
return null;
}
int w = src.getWidth();
int h = src.getHeight();
int ww = watermark.getWidth();
int wh = watermark.getHeight();
// create the new blank bitmap
Bitmap newb = Bitmap.createBitmap(w, h, Config.ARGB_8888);// 创建一个新的和SRC长度宽度一样的位图
Canvas cv = new Canvas(newb);
// draw src into
cv.drawBitmap(src, 0, 0, null);// 在 0,0坐标开始画入src
// draw watermark into
cv.drawBitmap(watermark, w - ww + 5, h - wh + 5, null);// 在src的右下角画入水印
// save all clip
cv.save(Canvas.ALL_SAVE_FLAG);// 保存
// store
cv.restore();// 存储
return newb;
}
14. View转成Bitmap
/**
* 把一个View的对象转换成bitmap
*/
static Bitmap getViewBitmap(View v) {
v.clearFocus();
v.setPressed(false);
// 能画缓存就返回false
boolean willNotCache = v.willNotCacheDrawing();
v.setWillNotCacheDrawing(false);
int color = v.getDrawingCacheBackgroundColor();
v.setDrawingCacheBackgroundColor(0);
if (color != 0) {
v.destroyDrawingCache();
}
v.buildDrawingCache();
Bitmap cacheBitmap = v.getDrawingCache();
if (cacheBitmap == null) {
Log.e(TAG, "failed getViewBitmap(" + v + ")",
new RuntimeException());
return null;
}
Bitmap bitmap = Bitmap.createBitmap(cacheBitmap);
// Restore the view
v.destroyDrawingCache();
v.setWillNotCacheDrawing(willNotCache);
v.setDrawingCacheBackgroundColor(color);
return bitmap;
}
15. drawable to bitmap
public static Bitmap drawable2Bitmap(Drawable drawable){
int width = drawable.getIntrinsicHeight();
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;
}
16. 缩略图生成
/**
* 获取缩略图
* @param imagePath:文件路径
* @param width:缩略图宽度
* @param height:缩略图高度
* @return
*/
public static Bitmap getImageThumbnail(String imagePath, int width, int height) {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true; //关于inJustDecodeBounds的作用将在下文叙述
Bitmap bitmap = BitmapFactory.decodeFile(imagePath, options);
int h = options.outHeight;//获取图片高度
int w = options.outWidth;//获取图片宽度
int scaleWidth = w / width; //计算宽度缩放比
int scaleHeight = h / height; //计算高度缩放比
int scale = 1;//初始缩放比
if (scaleWidth < scaleHeight) {//选择合适的缩放比
scale = scaleWidth;
} else {
scale = scaleHeight;
}
if (scale <= 0) {//判断缩放比是否符合条件
be = 1;
}
options.inSampleSize = scale;
// 重新读入图片,读取缩放后的bitmap,注意这次要把inJustDecodeBounds 设为 false
options.inJustDecodeBounds = false;
bitmap = BitmapFactory.decodeFile(imagePath, options);
// 利用ThumbnailUtils来创建缩略图,这里要指定要缩放哪个Bitmap对象
bitmap = ThumbnailUtils.extractThumbnail(bitmap, width, height,ThumbnailUtils.OPTIONS_RECYCLE_INPUT);
return bitmap;
}
通过上述代码加载图片的缩略图,将会有效的避免OOM异常。在这里需要解释下options.inJustDecodeBounds这个属性,当options.inJustDecodeBounds设置为true时,通过BitmapFactory.decodeFile去加载图片,将不会正真地返回bitmap,也就是说此时的bitmap为null。它的作用是将图片的相关信息,例如图片宽高,大小等信息带到options中,方便我们后续计算图片的宽高比。
当我们计算好宽高比后,通过options.inSampleSize来设置缩放比例,然后将options.inJustDecodeBounds的值设置为false,再通过BitmapFactory.decodeFile去加载图片就能获取真正的bitmap对象了。最后通过ThumbnailUtils.extractThumbnail来获取最终的缩略图。需要说明的是,ThumbnailUtils.OPTIONS_RECYCLE_INPUT表示回收创建缩略图时的资源。
17. 设置bitmap四周白边
/**
*
* 设置bitmap四周白边
*
* @param bitmap 原图
* @return
*/
public static Bitmap bg2WhiteBitmap(Bitmap bitmap)
{
int size = bitmap.getWidth() < bitmap.getHeight() ? bitmap.getWidth() : bitmap.getHeight();
int num = 14;
int sizebig = size + num;
// 背图
Bitmap newBitmap = Bitmap.createBitmap(sizebig, sizebig, Config.ARGB_8888);
Canvas canvas = new Canvas(newBitmap);
Paint paint = new Paint();
paint.setAntiAlias(true);
canvas.drawARGB(0, 0, 0, 0);
// 生成白色的
paint.setColor(Color.WHITE);
canvas.drawBitmap(bitmap, num / 2, num / 2, paint);
paint.setXfermode(new PorterDuffXfermode(Mode.DST_ATOP));
// 画正方形的
canvas.drawRect(0, 0, sizebig, sizebig, paint);
return newBitmap;
}