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