package com.ouwenjie.note.utils;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
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.Environment;
import android.provider.MediaStore;
import android.util.Log;
import java.io.BufferedOutputStream;
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.sql.Timestamp;
import java.text.SimpleDateFormat;
/**
* 图片处理工具类
* 包含以下方法:
* 1、Bitmap 和 byte 数组 的相互转换
* 2、Drawable 和 Bitmap 的相互转换
* 3、Drawable 和 byte 数组 的相互转换
* 4、按比例缩放 Bitmap
* 5、缩放Bitmap 到 固定大小
* 6、给Bitmap 添加 水印文字
* 7、将Bitmap 修改成 圆角
* 8、保存Bitmap 到SD卡 (记得开启相应的权限)
* 9、从文件、路径中获取Bitmap
* 10、使用当前时间戳拼接一个唯一的文件名
* 11、让Gallery上能马上看到该图
* 12、判断某文件是否jpeg\gif\png\bmp
* 13、获取图片的类型
*
* Created by 文杰 on 2015/3/26.
*/
public class ImageUtils {
public static final String SDCARD_MNT = "/mnt/sdcard";
/**
* 不要直接使用该 sdcard 目录,建议使用 Environment.getExternalStorageDirectory().getPath();
*/
public static final String SDCARD = Environment.getExternalStorageDirectory().getPath();
/**
* 私有化构造函数,不允许实例化
*/
private ImageUtils(){
/* cannot be instantiated */
throw new UnsupportedOperationException("cannot be instantiated");
}
/**
* convert Bitmap to byte array
* @param bitmap
* @return
*/
public static byte[] bitmapToByte(Bitmap bitmap) {
if (bitmap == null) {
return null;
}
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, baos);
return baos.toByteArray();
}
/**
* convert byte array to Bitmap
* @param b
* @return
*/
public static Bitmap byteToBitmap(byte[] b) {
return (b == null || b.length == 0) ? null : BitmapFactory.decodeByteArray(b, 0, b.length);
}
/**
* convert Bitmap to Drawable
* @param b
* @return
*/
public static Drawable bitmapToDrawable(Bitmap b) {
return b == null ? null : new BitmapDrawable(b);
}
/**
* convert Drawable to Bitmap
* @param d
* @return
*/
public static Bitmap drawableToBitmap(Drawable d) {
return d == null ? null : ((BitmapDrawable)d).getBitmap();
}
/**
* convert Drawable to byte array
* @param d
* @return
*/
public static byte[] drawableToByte(Drawable d) {
return bitmapToByte(drawableToBitmap(d));
}
/**
* convert byte array to Drawable
* @param b
* @return
*/
public static Drawable byteToDrawable(byte[] b) {
return bitmapToDrawable(byteToBitmap(b));
}
/**
* scale image
* @param org
* @param scaleWidth scale of width
* @param scaleHeight scale of height
* @return
*/
public static Bitmap scaleImage(Bitmap org, float scaleWidth, float scaleHeight) {
if (org == null) {
return null;
}
Matrix matrix = new Matrix();
matrix.postScale(scaleWidth, scaleHeight);
return Bitmap.createBitmap(org, 0, 0, org.getWidth(), org.getHeight(), matrix, true);
}
/**
* scale image
* @param org
* @param newWidth
* @param newHeight
* @return
*/
public static Bitmap scaleImageTo(Bitmap org, int newWidth, int newHeight) {
return scaleImage(org, (float) newWidth / org.getWidth(), (float) newHeight / org.getHeight());
}
/**
* 添加文字到图片,类似水印文字。
* 功能并不完善,修改字体颜色和大小,需要修改源代码
* @param gContext
* @param gResId
* @param gText
* @return
*/
public static Bitmap drawTextToBitmap(Context gContext, int gResId, String gText) {
Resources resources = gContext.getResources();
float scale = resources.getDisplayMetrics().density;
Bitmap bitmap = BitmapFactory.decodeResource(resources, gResId);
Bitmap.Config bitmapConfig = bitmap.getConfig();
// set default bitmap config if none
if (bitmapConfig == null) {
bitmapConfig = Bitmap.Config.ARGB_8888;
}
// resource bitmaps are imutable,
// so we need to convert it to mutable one
bitmap = bitmap.copy(bitmapConfig, true);
Canvas canvas = new Canvas(bitmap);
// new antialised Paint
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
// text color - #808080
paint.setColor(Color.rgb(127, 127, 127));
// text size in pixels
paint.setTextSize((int) (14 * scale*5));
// text shadow
paint.setShadowLayer(1f, 0f, 1f, Color.WHITE);
// draw text to the Canvas center
Rect bounds = new Rect();
paint.getTextBounds(gText, 0, gText.length(), bounds);
// int x = (bitmap.getWidth() - bounds.width()) / 2;
// int y = (bitmap.getHeight() + bounds.height()) / 2;
//draw text to the bottom
int x = (bitmap.getWidth() - bounds.width())/10*9 ;
int y = (bitmap.getHeight() + bounds.height())/10*9;
canvas.drawText(gText, x , y, paint);
return bitmap;
}
/**
* 获得圆角图片的方法
* @param bitmap
* @param roundPx 4脚幅度
* @return
*/
public static Bitmap getRoundedCornerBitmap(Bitmap bitmap, float roundPx) {
Bitmap output = Bitmap.createBitmap(bitmap.getWidth(),
bitmap.getHeight(), Bitmap.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(PorterDuff.Mode.SRC_IN));
canvas.drawBitmap(bitmap, rect, rect, paint);
return output;
}
/**
* 获得带倒影的图片方法
* @param bitmap
* @return
*/
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), Bitmap.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, Shader.TileMode.CLAMP);
paint.setShader(shader);
// Set the Transfer mode to be porter duff and destination in
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
// Draw a rectangle using the paint with our linear gradient
canvas.drawRect(0, height, width, bitmapWithReflection.getHeight()
+ reflectionGap, paint);
return bitmapWithReflection;
}
/**
* 从文件中获取bitmap
* @param context 上下文
* @param fileName 图片fileName
* @return Bitmap
*/
public static Bitmap getBitmap(Context context, String fileName) {
FileInputStream fis = null;
Bitmap bitmap = null;
try {
fis = context.openFileInput(fileName);
bitmap = BitmapFactory.decodeStream(fis);
} catch (FileNotFoundException | OutOfMemoryError e) {
e.printStackTrace();
} finally {
try {
if (fis != null) {
fis.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
return bitmap;
}
/**
* 获取Bitmap
*
* @param filePath 图片的路径
* @return Bitmap
*/
public static Bitmap getBitmapByPath(String filePath) {
return getBitmapByPath(filePath, null);
}
public static Bitmap getBitmapByPath(String filePath, BitmapFactory.Options opts) {
FileInputStream fis = null;
Bitmap bitmap = null;
try {
File file = new File(filePath);
fis = new FileInputStream(file);
bitmap = BitmapFactory.decodeStream(fis, null, opts);
} catch (FileNotFoundException | OutOfMemoryError e) {
e.printStackTrace();
} finally {
try {
if (fis != null) {
fis.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
return bitmap;
}
public static Bitmap getBitmapFromUri(Context context , Uri uri)
{
try {
// 读取uri所在的图片
return MediaStore.Images.Media.getBitmap(context.getContentResolver(), uri);
}catch (Exception e){
Log.e("[Android]", e.getMessage());
Log.e("[Android]", "目录为:" + uri);
e.printStackTrace();
return null;
}
}
/**
* 获取bitmap
* @param file
* @return
*/
public static Bitmap getBitmapByFile(File file) {
FileInputStream fis = null;
Bitmap bitmap = null;
try {
fis = new FileInputStream(file);
bitmap = BitmapFactory.decodeStream(fis);
} catch (FileNotFoundException | OutOfMemoryError e) {
e.printStackTrace();
} finally {
try {
if (fis != null) {
fis.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
return bitmap;
}
// 图片URI 的到 Path
public static String getAbsoluteImagePath(Context context,Uri uri) {
String[] proj = { MediaStore.Images.Media.DATA };
Cursor cursor = context.getContentResolver().query(uri, proj, null, null, null);
cursor.moveToFirst();
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
return cursor.getString(column_index);
}
/**
* 使用当前时间戳拼接一个唯一的文件名
* @return
*/
public static String getTempFileName() {
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd_HH-mm-ss_SS");
return format.format(new Timestamp(System
.currentTimeMillis()));
}
/**
* 写图片文在Android系统中,文件保存/data/data/PACKAGE_NAME/files 目录
* @throws IOException
*/
public static void saveImage(Context context, String fileName, Bitmap bitmap)
throws IOException {
saveImage(context, fileName, bitmap, 100);
}
/**
* 写图片文在Android系统中,文件保存/data/data/PACKAGE_NAME/files 目录
* @param quality 图片质量:0~100
* @throws IOException
*/
public static void saveImage(Context context, String fileName,
Bitmap bitmap, int quality) throws IOException {
if (bitmap == null || fileName == null || context == null)
return;
FileOutputStream fos = context.openFileOutput(fileName, Context.MODE_PRIVATE);
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, quality, stream);
byte[] bytes = stream.toByteArray();
fos.write(bytes);
fos.close();
}
/**
* 写图片文件到SD 卡
* @throws IOException
**/
public static void saveImageToSD(Context ctx, String filePath,
Bitmap bitmap, int quality) throws IOException {
if (bitmap != null) {
File file = new File(filePath);
File dir = new File(filePath.substring(0,filePath.lastIndexOf(File.separator)));
if (!dir.exists()) {
dir.mkdirs();
}
file.createNewFile();
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(file));
bitmap.compress(Bitmap.CompressFormat.JPEG, quality, bos);
bos.flush();
bos.close();
}
}
/**
* 让Gallery上能马上看到该图
**/
private static void scanPhoto(Context ctx, String imgFileName) {
Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
File file = new File(imgFileName);
Uri contentUri = Uri.fromFile(file);
mediaScanIntent.setData(contentUri);
ctx.sendBroadcast(mediaScanIntent);
}
private static boolean isJPEG(byte[] b) {
if (b.length < 2) {
return false;
}
return (b[0] == (byte) 0xFF) && (b[1] == (byte) 0xD8);
}
private static boolean isGIF(byte[] b) {
if (b.length < 6) {
return false;
}
return b[0] == 'G' && b[1] == 'I' && b[2] == 'F' && b[3] == '8'
&& (b[4] == '7' || b[4] == '9') && b[5] == 'a';
}
private static boolean isPNG(byte[] b) {
if (b.length < 8) {
return false;
}
return (b[0] == (byte) 137 && b[1] == (byte) 80 && b[2] == (byte) 78
&& b[3] == (byte) 71 && b[4] == (byte) 13 && b[5] == (byte) 10
&& b[6] == (byte) 26 && b[7] == (byte) 10);
}
private static boolean isBMP(byte[] b) {
if (b.length < 2) {
return false;
}
return (b[0] == 0x42) && (b[1] == 0x4d);
}
/**
* 获取图片类型
*
* @param file 图片文件
* @return 图片的类型信息
*/
public static String getImageType(File file) {
if (file == null || !file.exists()) {
return null;
}
InputStream in = null;
try {
in = new FileInputStream(file);
return getImageType(in);
} catch (IOException e) {
return null;
} finally {
try {
if (in != null) {
in.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 获取图片的类型信息
* @param in 图片的输入流
* @return 图片的类型信息
* @see #getImageType(byte[])
*/
public static String getImageType(InputStream in) {
if (in == null) {
return null;
}
try {
byte[] bytes = new byte[8];
in.read(bytes);
return getImageType(bytes);
} catch (IOException e) {
return null;
}
}
/**
* 获取图片的类型信
* @param bytes
* 2~8 byte at beginning of the image file
* @return image mimetype or null if the file is not image
*/
public static String getImageType(byte[] bytes) {
if (isJPEG(bytes)) {
return "image/jpeg";
}
if (isGIF(bytes)) {
return "image/gif";
}
if (isPNG(bytes)) {
return "image/png";
}
if (isBMP(bytes)) {
return "application/x-bmp";
}
return null;
}
}