package com.xscm.moduleutil.utils; import static android.view.View.GONE; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.LinearGradient; import android.graphics.Paint; import android.graphics.PorterDuff; import android.graphics.RectF; import android.graphics.Shader; import android.graphics.drawable.AnimationDrawable; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; import android.os.Build; import android.text.TextUtils; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; import android.widget.LinearLayout; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.RequiresApi; import com.blankj.utilcode.util.ConvertUtils; import com.blankj.utilcode.util.Utils; import com.bumptech.glide.Glide; import com.bumptech.glide.load.DataSource; import com.bumptech.glide.load.engine.DiskCacheStrategy; import com.bumptech.glide.load.engine.GlideException; import com.bumptech.glide.load.resource.gif.GifDrawable; import com.bumptech.glide.request.FutureTarget; import com.bumptech.glide.request.RequestListener; import com.bumptech.glide.request.RequestOptions; import com.bumptech.glide.request.target.SimpleTarget; import com.bumptech.glide.request.target.Target; import com.bumptech.glide.request.transition.Transition; import com.bumptech.glide.signature.ObjectKey; import com.opensource.svgaplayer.SVGADrawable; import com.opensource.svgaplayer.SVGAImageView; import com.opensource.svgaplayer.SVGAParser; import com.opensource.svgaplayer.SVGAVideoEntity; import com.xscm.moduleutil.R; import com.xscm.moduleutil.utils.logger.Logger; import org.jetbrains.annotations.NotNull; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.net.MalformedURLException; import java.net.URL; import java.util.HashMap; import java.util.Map; /** *

图片加载工具类

* * @name ImageUtils */ public class ImageUtils { public static final int ANIM = -1; /** * 默认加载 */ public static void loadImageView(String path, ImageView mImageView) { Glide.with(mImageView).load(path).diskCacheStrategy(DiskCacheStrategy.ALL).into(mImageView); } /** * 默认加载 */ public static void loadIcon(String path, ImageView mImageView) { mImageView.setVisibility(TextUtils.isEmpty(path) ? GONE : View.VISIBLE); Glide.with(mImageView).load(path).diskCacheStrategy(DiskCacheStrategy.ALL).into(mImageView); } /** * 加载爵位动图 */ public static void loadVipWebp(String path, ImageView mImageView) { loadSample(path, mImageView, ConvertUtils.dp2px(200), ConvertUtils.dp2px(200)); } /** * 采样 * * @param path * @param mImageView * @param width * @param height */ public static void loadSample(String path, ImageView mImageView, int width, int height) { RequestOptions options = new RequestOptions().override(width, height).diskCacheStrategy(DiskCacheStrategy.ALL); Glide.with(mImageView).load(path).apply(options).into(mImageView); } /** * 默认加载 */ public static void loadDecorationAvatar(String path, SVGAImageView mImageView) { if (path.endsWith(".svga")) { try { SVGAParser.Companion.shareParser().decodeFromURL(new URL(path), new SVGAParser.ParseCompletion() { @Override public void onComplete(@NotNull SVGAVideoEntity svgaVideoEntity) { if (mImageView != null) { SVGADrawable svgaDrawable = new SVGADrawable(svgaVideoEntity); mImageView.setImageDrawable(svgaDrawable); mImageView.startAnimation(); } } @Override public void onError() { Logger.e("loadDecorationAvatar error"); } }); } catch (MalformedURLException e) { e.printStackTrace(); } } else { if (mImageView.isAnimating()) { mImageView.stopAnimation(); } Glide.with(mImageView).load(path).diskCacheStrategy(DiskCacheStrategy.ALL).into(mImageView); } } private static Map svgaCache = new HashMap<>(); // TODO: 2025/8/22 播放svga public static void loadDecorationAvatar2(int resourceId, SVGAImageView mImageView) { // 从资源文件夹加载SVGA文件 if (resourceId != 0) { // 检查缓存 SVGAVideoEntity cachedEntity = svgaCache.get(resourceId); if (cachedEntity != null) { // 使用缓存的实体 SVGADrawable svgaDrawable = new SVGADrawable(cachedEntity); mImageView.setImageDrawable(svgaDrawable); mImageView.startAnimation(); return; } try { // 没有缓存,正常加载 SVGAParser parser = SVGAParser.Companion.shareParser(); InputStream inputStream = mImageView.getContext().getResources().openRawResource(resourceId); parser.decodeFromAssets("heart_line_31.svga", new SVGAParser.ParseCompletion() { @Override public void onComplete(@NotNull SVGAVideoEntity svgaVideoEntity) { if (mImageView != null) { // 缓存实体 svgaCache.put(resourceId, svgaVideoEntity); SVGADrawable svgaDrawable = new SVGADrawable(svgaVideoEntity); mImageView.setImageDrawable(svgaDrawable); mImageView.startAnimation(); } } @Override public void onError() { Logger.e("loadDecorationAvatar2 error, resourceId: " + resourceId); } }); } catch (Exception e) { Logger.e("loadDecorationAvatar2 exception, resourceId: " + resourceId, e); } } else { Logger.e("Resource ID is 0 or invalid"); } } public static void loadHeadCC(String path, ImageView mImageView) { Glide.with(mImageView).load(path).error(R.mipmap.default_avatar).placeholder(R.mipmap.default_avatar).centerCrop().diskCacheStrategy(DiskCacheStrategy.ALL).into(mImageView); } public static void loadCompressImg(String path, ImageView mImageView, int width, int height) { Glide.with(mImageView) .load(path) .centerCrop() .override(width, height).diskCacheStrategy(DiskCacheStrategy.ALL) .into(mImageView); } public static void loadCenterCrop(String path, ImageView mImageView) { Glide.with(mImageView).load(path).centerCrop().diskCacheStrategy(DiskCacheStrategy.ALL).into(mImageView); } public static void loadRes(int path, ImageView mImageView) { Glide.with(mImageView).load(path).diskCacheStrategy(DiskCacheStrategy.ALL).into(mImageView); } /** * 加载图片(优先使用本地缓存,无缓存则下载) * * @param context 上下文 * @param url 图片 URL * @param imageView 目标 ImageView */ public static void loadImageWithCache(Context context, String url, ImageView imageView) { if (TextUtils.isEmpty(url)) return; // 去掉动态参数,提取稳定 URL String stableUrl = url.split("\\?")[0]; String signature = Md5Utils.getMD5String(stableUrl); // 使用 MD5 生成唯一签名 // Glide 加载配置 Glide.with(context) .load(stableUrl) .diskCacheStrategy(DiskCacheStrategy.ALL) // 缓存所有版本 .signature(new ObjectKey(signature)) // 使用签名确保缓存一致 .placeholder(R.mipmap.room_bj) // 加载中占位图 .error(R.mipmap.room_bj) // 加载失败占位图 .centerCrop() .into(imageView); } public static boolean isImageCached(Context context, String url) { FutureTarget future = Glide.with(context) .downloadOnly() .load(url) .submit(); try { File cacheFile = future.get(); return cacheFile != null && cacheFile.exists(); } catch (Exception e) { e.printStackTrace(); return false; } } public static void loadImageBlurBg(String url, ImageView imageView) { RequestOptions options = new RequestOptions().centerCrop().placeholder(R.mipmap.room_bg).error(R.mipmap.room_bg).diskCacheStrategy(DiskCacheStrategy.ALL); Glide.with(imageView).asBitmap().apply(options).load(url).into(new SimpleTarget(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL) { @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR1) @Override public void onResourceReady(@NonNull Bitmap resource, @Nullable Transition transition) { try { Drawable foregroundDrawable = FastBlurUtil.getForegroundDrawable(resource); imageView.setImageDrawable(foregroundDrawable); } catch (Exception e) { imageView.setImageResource(R.mipmap.room_bg); } } }); } public static void loadCoverBlurBg(Context context, String url, LinearLayout linearLayout) { RequestOptions options = new RequestOptions().centerCrop().placeholder(R.mipmap.default_avatar).error(R.mipmap.default_avatar).diskCacheStrategy(DiskCacheStrategy.ALL); Glide.with(context).asBitmap().apply(options).load(url).into(new SimpleTarget(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL) { @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR1) @Override public void onResourceReady(@NonNull Bitmap resource, @Nullable Transition transition) { try { setUpCoverBg(linearLayout, resource); } catch (Exception e) { linearLayout.setBackgroundResource(R.mipmap.index_bg_hot); } } }); } private static void setUpCoverBg(LinearLayout linearLayout, Bitmap resource) { // Palette.from(resource).generate(new Palette.PaletteAsyncListener() { // @Override // public void onGenerated(Palette palette) { // //记得判空 // if (palette == null) return; // //palette取色不一定取得到某些特定的颜色,这里通过取多种颜色来避免取不到颜色的情况 // if (palette.getDarkVibrantColor(Color.TRANSPARENT) != Color.TRANSPARENT) { // createLinearGradientBitmap(linearLayout, resource, palette.getDarkVibrantColor(Color.TRANSPARENT), palette.getVibrantColor(Color.TRANSPARENT)); // } else if (palette.getDarkMutedColor(Color.TRANSPARENT) != Color.TRANSPARENT) { // createLinearGradientBitmap(linearLayout, resource, palette.getDarkMutedColor(Color.TRANSPARENT), palette.getMutedColor(Color.TRANSPARENT)); // } else { // createLinearGradientBitmap(linearLayout, resource, palette.getLightMutedColor(Color.TRANSPARENT), palette.getLightVibrantColor(Color.TRANSPARENT)); // } // } // }); } //创建线性渐变背景色 private static void createLinearGradientBitmap(LinearLayout ivBg, Bitmap bgBitmap, int darkColor, int color) { int bgColors[] = new int[2]; bgColors[0] = darkColor; bgColors[1] = color; if (bgBitmap == null) { bgBitmap = Bitmap.createBitmap(ivBg.getWidth(), ivBg.getHeight(), Bitmap.Config.ARGB_4444); } Canvas mCanvas = new Canvas(); Paint mPaint = new Paint(); mCanvas.setBitmap(bgBitmap); mCanvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR); LinearGradient gradient = new LinearGradient(0, 0, 0, bgBitmap.getHeight(), bgColors[0], bgColors[1], Shader.TileMode.CLAMP); mPaint.setShader(gradient); RectF rectF = new RectF(0, 0, bgBitmap.getWidth(), bgBitmap.getHeight()); mCanvas.drawRoundRect(rectF, 16, 16, mPaint); // mCanvas.drawRect(rectF, mPaint); ivBg.setBackground(new BitmapDrawable(bgBitmap)); } public static void loadRoomBg(String url, ImageView imageView) { RequestOptions options = new RequestOptions().centerCrop().placeholder(R.mipmap.room_bg).error(R.mipmap.room_bg).diskCacheStrategy(DiskCacheStrategy.ALL); Glide.with(imageView).load(url).apply(options).into(imageView); } /** * 设置加载中以及加载失败图片 */ public static void loadImageWithLoading(String path, ImageView mImageView, int lodingImage, int errorRes) { Glide.with(mImageView).load(path).placeholder(lodingImage). error(errorRes).diskCacheStrategy(DiskCacheStrategy.ALL).into(mImageView); } /** * 加载为bitmap * * @param path 图片地址 * @param listener 回调 */ public static void loadBitmap(String path, final onLoadBitmap listener) { Glide.with(Utils.getApp()).asBitmap().load(path).into(new SimpleTarget() { @Override public void onResourceReady(@NonNull Bitmap resource, @Nullable Transition transition) { listener.onReady(resource); } }); } public static void loadGift(ImageView view, int res) { if (res == ANIM) { try { AnimationDrawable background = (AnimationDrawable) view.getBackground(); if (background != null) { background.start(); } } catch (Exception e) { e.printStackTrace(); } } else { Glide.with(view.getContext()).asGif().load(res).into(view); } } public static void loadIconByHeight(String path, ImageView mImageView) { mImageView.setVisibility(TextUtils.isEmpty(path) ? GONE : View.VISIBLE); Glide.with(mImageView).load(path).diskCacheStrategy(DiskCacheStrategy.ALL).into(new SimpleTarget() { @Override public void onResourceReady(@NonNull Drawable resource, @Nullable Transition transition) { mImageView.setImageDrawable(resource); ViewGroup.LayoutParams layoutParams = mImageView.getLayoutParams(); layoutParams.width = (int) (layoutParams.height * 1f / resource.getIntrinsicHeight() * resource.getIntrinsicWidth()); mImageView.setLayoutParams(layoutParams); } }); } public static void loadIconByHeight1(String path, ImageView mImageView,int height) { mImageView.setVisibility(TextUtils.isEmpty(path) ? GONE : View.VISIBLE); Glide.with(mImageView).load(path).diskCacheStrategy(DiskCacheStrategy.ALL).into(new SimpleTarget() { @Override public void onResourceReady(@NonNull Drawable resource, @Nullable Transition transition) { mImageView.setImageDrawable(resource); ViewGroup.LayoutParams layoutParams = mImageView.getLayoutParams(); layoutParams.width = (int) (layoutParams.height * 1f / resource.getIntrinsicHeight() * resource.getIntrinsicWidth()); layoutParams.height = height; mImageView.setLayoutParams(layoutParams); } }); } /** * 加载网络图片并高斯模糊,失败时加载默认图片并同样模糊 */ public static void loadBlurredImageWithDefault(String url, ImageView imageView, int defaultResId, int radius) { if (imageView == null) return; Glide.with(imageView.getContext()) .asBitmap() .load(url) .error(defaultResId) // 加载失败时显示默认图片 .into(new SimpleTarget() { @Override public void onResourceReady(@NonNull Bitmap resource, @Nullable Transition transition) { // 对网络图或默认图都进行模糊处理 Bitmap blurred = com.blankj.utilcode.util.ImageUtils.stackBlur(resource, radius); imageView.setImageBitmap(blurred); } @Override public void onLoadFailed(@Nullable Drawable errorDrawable) { // 如果 errorDrawable 不为空,也可以直接用它生成 Bitmap if (errorDrawable instanceof BitmapDrawable) { Bitmap bitmap = ((BitmapDrawable) errorDrawable).getBitmap(); Bitmap blurred = com.blankj.utilcode.util.ImageUtils.stackBlur(bitmap, radius); imageView.setImageBitmap(blurred); } else { // 如果不是 BitmapDrawable,尝试从资源中加载 Bitmap Bitmap defaultBitmap = BitmapFactory.decodeResource(imageView.getResources(), defaultResId); if (defaultBitmap != null) { Bitmap blurred = com.blankj.utilcode.util.ImageUtils.stackBlur(defaultBitmap, radius); imageView.setImageBitmap(blurred); } } } }); } /** * 加载bitmap回调 */ public interface onLoadBitmap { void onReady(Bitmap resource); } public static void loadOneTimeGif(Context context, Object model, final ImageView imageView) { Glide.with(context).asGif().load(model).listener(new RequestListener() { @Override public boolean onLoadFailed(@Nullable GlideException e, Object model, Target target, boolean isFirstResource) { return false; } @Override public boolean onResourceReady(GifDrawable resource, Object model, Target target, DataSource dataSource, boolean isFirstResource) { try { Field gifStateField = GifDrawable.class.getDeclaredField("state"); gifStateField.setAccessible(true); Class gifStateClass = Class.forName("com.bumptech.glide.load.resource.gif.GifDrawable$GifState"); Field gifFrameLoaderField = gifStateClass.getDeclaredField("frameLoader"); gifFrameLoaderField.setAccessible(true); Class gifFrameLoaderClass = Class.forName("com.bumptech.glide.load.resource.gif.GifFrameLoader"); Field gifDecoderField = gifFrameLoaderClass.getDeclaredField("gifDecoder"); gifDecoderField.setAccessible(true); Class gifDecoderClass = Class.forName("com.bumptech.glide.gifdecoder.GifDecoder"); Object gifDecoder = gifDecoderField.get(gifFrameLoaderField.get(gifStateField.get(resource))); Method getDelayMethod = gifDecoderClass.getDeclaredMethod("getDelay", int.class); getDelayMethod.setAccessible(true); //设置只播放一次 resource.setLoopCount(1); } catch (NoSuchFieldException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (NoSuchMethodException e) { e.printStackTrace(); } return false; } }).into(imageView); } // public static String getImagePath() { // String path = Constants.IMAGE_PATH; // File file = new File(path); // if (file.mkdirs()) { // return path; // } else { // return path; // } // } public static String getUrl(String url) { // url = EncodeUtils.htmlDecode(url).toString(); // if (!TextUtils.isEmpty(url) && !url.contains("http")) // url = BuildConfig.BASE_URL + url; return url; } public static void preload(String url) { // Glide.with(BaseApplication.getInstance()).download(url).preload(); } public static void preloadImgConstants() { // try { // ImgConstants constants = new ImgConstants(); // Field[] fields = ImgConstants.class.getDeclaredFields(); // for (Field field : fields) { // preload(field.get(constants).toString()); // } // } catch (Exception e) { // e.printStackTrace(); // } } /** * 将 assets 中的文件复制到指定路径 * * @param assetName assets 中的文件名,例如:"my_file.txt" * @param savePath 要保存的目录路径,例如:"/data/data/your.package/files/" * @param saveName 保存后的文件名 */ public static void copyAssetToFile(String assetName, String savePath, String saveName) { InputStream myInput = null; FileOutputStream myOutput = null; try { // 打开 assets 中的文件输入流 myInput = Utils.getApp().getAssets().open(assetName); // 创建目标目录(如果不存在) File dir = new File(savePath); if (!dir.exists()) { dir.mkdirs(); } // 创建目标文件 File outFile = new File(savePath + saveName); if (outFile.exists()) { outFile.delete(); // 如果已存在,先删除 } // 创建输出流 myOutput = new FileOutputStream(outFile); // 缓冲区读写 byte[] buffer = new byte[1024]; int length; while ((length = myInput.read(buffer)) > 0) { myOutput.write(buffer, 0, length); } // 刷新输出流 myOutput.flush(); } catch (Exception e) { e.printStackTrace(); } finally { // 关闭流 try { if (myInput != null) { myInput.close(); } if (myOutput != null) { myOutput.close(); } } catch (IOException e) { e.printStackTrace(); } } } public static void clearDiskCache(Context context){ Glide.get(context).clearDiskCache(); } }