开发中图片加载是个问题,我们图片加载通常使用Glide来进行加载,因为Glide可以实现图片的三级缓存,比较简单
的工具类在图片的加载上省去很多开发中不必要的工作。
功能如下:
1:无加载中的图片。
2:获取图片的旋转角度。
3:将图片按照某个角度进行旋转。
4:通过uri获取图片并进行压缩。
5:获取HTML中的图片src地址。
6:保存图片到本地。
7:创建图片file对象。
工具类封装如下:
/** * Created by AndyYuan317 on 2020/7/27. * 图片加载工具类 */ public class ImageUtil { /** * 无加载中图片 * * @param context * @param imageView * @param url */ public static void loadNotPlace(Context context, ImageView imageView, String url) { if (TextUtils.isEmpty(url)) { imageView.setImageResource(R.drawable.ic_placeholder); return; } if (url.length() > 3 && "gif".equals(url.substring(url.length() - 3, url.length()))) { Glide.with(context) .load(url) .asGif() .error(R.drawable.ic_placeholder) .dontAnimate() .diskCacheStrategy(DiskCacheStrategy.NONE) .into(imageView); } else { Glide.with(context) .load(url) .error(R.drawable.ic_placeholder) .dontAnimate() .diskCacheStrategy(DiskCacheStrategy.NONE) .into(imageView); } } @SuppressLint("NewApi") public static void load(Context context, ImageView imageView, String url) { if (TextUtils.isEmpty(url)) { imageView.setImageResource(R.drawable.ic_placeholder); return; } if (url.length() > 3 && "gif".equals(url.substring(url.length() - 3, url.length()))) { Glide.with(context) .load(url) .asGif() .placeholder(R.drawable.ic_placeholder) .error(R.drawable.ic_placeholder) .dontAnimate() .diskCacheStrategy(DiskCacheStrategy.NONE) .into(imageView); } else if(!((Activity)context).isFinishing() && !((Activity)context).isDestroyed()){ Glide.with(context) .load(url) .placeholder(R.drawable.ic_placeholder) .error(R.drawable.ic_placeholder) .dontAnimate() .skipMemoryCache(true) .into(imageView); } } public static void loadBitmap(Context context, final ImageView imageView, String url, RequestListenerlistener){ if (TextUtils.isEmpty(url)) { imageView.setImageResource(R.drawable.ic_placeholder); return; } Glide.with(context) .load(url) .asBitmap() .listener(listener) .placeholder(R.drawable.ic_placeholder) .error(R.drawable.ic_placeholder) //.override(640, 360) .dontAnimate().preload(); //.into(imageView); } public static void loadFixSize(Context context, ImageView imageView, String url) { if (TextUtils.isEmpty(url)) { imageView.setImageResource(R.drawable.ic_placeholder); return; } if (url.length() > 3 && "gif".equals(url.substring(url.length() - 3, url.length()))) { Glide.with(context) .load(url) .asGif() .placeholder(R.drawable.ic_placeholder) .error(R.drawable.ic_placeholder) .dontAnimate() .diskCacheStrategy(DiskCacheStrategy.NONE) .into(imageView); } else { Glide.with(context) .load(url) .placeholder(R.drawable.ic_placeholder) .error(R.drawable.ic_placeholder) .override(640, 360) .dontAnimate() .into(imageView); } } public static void load(Fragment fragment, ImageView imageView, String url) { if (TextUtils.isEmpty(url)) { imageView.setImageResource(R.drawable.ic_placeholder); return; } if (url.length() > 3 && "gif".equals(url.substring(url.length() - 3, url.length()))) { Glide.with(fragment) .load(url) .asGif() .placeholder(R.drawable.ic_placeholder) .error(R.drawable.ic_placeholder) .dontAnimate() .diskCacheStrategy(DiskCacheStrategy.NONE) .into(imageView); } else { Glide.with(fragment) .load(url) .placeholder(R.drawable.ic_placeholder) .error(R.drawable.ic_placeholder) .dontAnimate() .into(imageView); } } public static void loadLocalFile(Context context, ImageView imageView, String url) { if (TextUtils.isEmpty(url)) { imageView.setImageResource(R.drawable.ic_placeholder); return; } Glide.with(context) .load(new File(url)) .placeholder(R.drawable.ic_placeholder) .error(R.drawable.ic_placeholder) .dontAnimate() .into(imageView); } /** * 加载头像 * * @param context * @param imageView * @param url */ public static void loadAvator(Context context, ImageView imageView, String url) { // if (TextUtils.isEmpty(url)) { // imageView.setImageResource(R.drawable.ic_avator); // return; // } Glide.with(context) .load(url) .placeholder(R.drawable.ic_avator) .error(R.drawable.ic_avator) .dontAnimate() .into(imageView); } /** * 读取图片的旋转的角度 * * @param path 图片绝对路径 * @return 图片的旋转角度 */ public static int getBitmapDegree(String path) { int degree = 0; try { // 从指定路径下读取图片,并获取其EXIF信息 ExifInterface exifInterface = new ExifInterface(path); // 获取图片的旋转信息 int orientation = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL); switch (orientation) { case ExifInterface.ORIENTATION_ROTATE_90: degree = 90; break; case ExifInterface.ORIENTATION_ROTATE_180: degree = 180; break; case ExifInterface.ORIENTATION_ROTATE_270: degree = 270; break; } } catch (IOException e) { e.printStackTrace(); } return degree; } /** * 将图片按照某个角度进行旋转 * * @param bm 需要旋转的图片 * @param degree 旋转角度 * @return 旋转后的图片 */ public static Bitmap rotateBitmapByDegree(Bitmap bm, int degree) { Bitmap returnBm = null; // 根据旋转角度,生成旋转矩阵 Matrix matrix = new Matrix(); matrix.postRotate(degree); try { // 将原始图片按照旋转矩阵进行旋转,并得到新的图片 returnBm = Bitmap.createBitmap(bm, 0, 0, bm.getWidth(), bm.getHeight(), matrix, true); } catch (OutOfMemoryError e) { } if (returnBm == null) { returnBm = bm; } if (bm != returnBm) { bm.recycle(); } return returnBm; } /** * 通过uri获取图片并进行压缩 * * @param uri */ public static Bitmap getBitmapFormUri(Activity ac, Uri uri, float width, float height, int maxSize) throws FileNotFoundException, IOException { InputStream input = ac.getContentResolver().openInputStream(uri); BitmapFactory.Options onlyBoundsOptions = new BitmapFactory.Options(); onlyBoundsOptions.inJustDecodeBounds = true; onlyBoundsOptions.inDither = true;//optional onlyBoundsOptions.inPreferredConfig = Bitmap.Config.ARGB_8888;//optional BitmapFactory.decodeStream(input, null, onlyBoundsOptions); input.close(); int originalWidth = onlyBoundsOptions.outWidth; int originalHeight = onlyBoundsOptions.outHeight; if ((originalWidth == -1) || (originalHeight == -1)) return null; //图片分辨率以480x800为标准 float hh = height == 0 ? 800f : height;//这里设置高度为800f float ww = width == 0 ? 480f : width;//这里设置宽度为480f //缩放比。由于是固定比例缩放,只用高或者宽其中一个数据进行计算即可 int be = 1;//be=1表示不缩放 if (originalWidth > originalHeight && originalWidth > ww) {//如果宽度大的话根据宽度固定大小缩放 be = (int) (originalWidth / ww); } else if (originalWidth < originalHeight && originalHeight > hh) {//如果高度高的话根据宽度固定大小缩放 be = (int) (originalHeight / hh); } if (be <= 0) be = 1; //比例压缩 BitmapFactory.Options bitmapOptions = new BitmapFactory.Options(); bitmapOptions.inSampleSize = be;//设置缩放比例 bitmapOptions.inDither = true;//optional bitmapOptions.inPreferredConfig = Bitmap.Config.ARGB_8888;//optional input = ac.getContentResolver().openInputStream(uri); Bitmap bitmap = BitmapFactory.decodeStream(input, null, bitmapOptions); input.close(); return compressImage(bitmap, maxSize);//再进行质量压缩 } /** * 质量压缩方法 * * @param image * @return */ public static Bitmap compressImage(Bitmap image, int maxSize) { ByteArrayOutputStream baos = new ByteArrayOutputStream(); image.compress(Bitmap.CompressFormat.JPEG, 100, baos);//质量压缩方法,这里100表示不压缩,把压缩后的数据存放到baos中 int options = 100; while (baos.toByteArray().length / 1024 > maxSize) { //循环判断如果压缩后图片是否大于200kb,大于继续压缩 baos.reset();//重置baos即清空baos //第一个参数 :图片格式 ,第二个参数: 图片质量,100为最高,0为最差 ,第三个参数:保存压缩后的数据的流 image.compress(Bitmap.CompressFormat.JPEG, options, baos);//这里压缩options%,把压缩后的数据存放到baos中 options -= 10;//每次都减少10 } ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());//把压缩后的数据baos存放到ByteArrayInputStream中 Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, null);//把ByteArrayInputStream数据生成图片 return bitmap; } /** * 获取html中的src地址 * * @param htmlStr * @return */ public static List getImgStr(String htmlStr) { List pics = new ArrayList<>(); String img = ""; Pattern p_image; Matcher m_image; String regEx_img = " ]*?>"; p_image = Pattern.compile(regEx_img, Pattern.CASE_INSENSITIVE); m_image = p_image.matcher(htmlStr); while (m_image.find()) { // 得到数据 img = m_image.group(); // 匹配中的src数据 Matcher m = Pattern.compile("src\\s*=\\s*\"?(.*?)(\"|>|\\s+)").matcher(img); while (m.find()) { pics.add(m.group(1)); } } return pics; } public static Observable observableSaveImageToExternal(final Context context, final Bitmap cropBitmap) { return Observable.create(new Observable.OnSubscribe () { @Override public void call(Subscriber super String> subscriber) { subscriber.onNext(saveImageToExternal(context, cropBitmap, createImageFile())); subscriber.onCompleted(); } }); } public static Observable observableImagePath(final File file){ return Observable.create(new Observable.OnSubscribe () { @Override public void call(Subscriber super File> subscriber) { subscriber.onNext(file); subscriber.onCompleted(); } }); } /** * 保存图片到本地 * * @param bm * @return */ public static String saveImageToExternal(Context context, Bitmap bm, File imageFile) { try { FileOutputStream out = new FileOutputStream(imageFile); bm.compress(Bitmap.CompressFormat.PNG, 100, out); out.flush(); out.close(); //TODO 还不能马上刷新 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE); Uri contentUri = Uri.fromFile(imageFile); mediaScanIntent.setData(contentUri); context.sendBroadcast(mediaScanIntent); } else { context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse("file://" + imageFile.getAbsoluteFile()))); } if (imageFile.exists()) { return imageFile.getAbsolutePath(); } else { return null; } } catch (Exception e) { e.printStackTrace(); } return null; } /** * 创建图片File对象 * * @return */ public static File createImageFile() { File imageFile = null; String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date()); try { if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { File path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES + "/PudongNews"); path.mkdirs(); imageFile = File.createTempFile(timeStamp, ".jpg", path); } else { imageFile = File.createTempFile(timeStamp, ".jpg", App.getInstance().getExternalFilesDir(null)); } } catch (IOException e) { e.printStackTrace(); } return imageFile; } public static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) { 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); } return inSampleSize + 1; } return inSampleSize; } public static Bitmap decodeImage(String path, int showWidth, int showHeight) { final BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; BitmapFactory.decodeFile(path, options); options.inJustDecodeBounds = false; if (showWidth != 0 && showHeight != 0) options.inSampleSize = calculateInSampleSize(options, showWidth, showHeight); options.inPreferredConfig = Bitmap.Config.ARGB_8888; return BitmapFactory.decodeFile(path, options); } public static ByteArrayOutputStream getSmallBitmap(String filePath) { Bitmap bm = decodeImage(filePath, 600, 800); long fileLength = new File(filePath).length(); int scale = 60; if (fileLength > 2097152) scale = 20; if (fileLength <= 2097152 && fileLength > 1572864) scale = 40; if (fileLength <= 1572864 && fileLength > 1048576) scale = 60; if (fileLength <= 1048576 && fileLength > 524288) scale = 70; if (fileLength <= 524288 && fileLength > 262144) scale = 80; if (fileLength <= 262144) scale = 60; ByteArrayOutputStream baos = new ByteArrayOutputStream(); if (filePath.endsWith(".jpg") || filePath.endsWith(".JPG")) bm.compress(Bitmap.CompressFormat.JPEG, scale, baos); if (filePath.endsWith(".jpeg") || filePath.endsWith(".JPEG")) bm.compress(Bitmap.CompressFormat.JPEG, scale, baos); if (filePath.endsWith(".png") || filePath.endsWith(".PNG")) bm.compress(Bitmap.CompressFormat.JPEG, scale, baos); return baos; } public static ByteArrayOutputStream getBitmapStream(String filePath){ Bitmap bmp = decodeImage(filePath, 0, 0); ByteArrayOutputStream baos = new ByteArrayOutputStream(); bmp.compress(Bitmap.CompressFormat.JPEG, 100, baos); return baos; } }