wpf BitmapImage缓存问题

情景描述:通过BitmapImage加载图片显示到Image控件上,然后删除图片后,重新生成同路径的全新图片,再加载显示到Image控件上;

限制:图片必须是同名,非同名可以无视此问题;需要频繁加载图片,所以缓存机制不可免;

问题描述:当我删除图片A后,重新生成同路径同名的图片B并通过BitmapImage加载到Image上时,显示出来的还是图片A;原因就出在这个缓存,因为图片B跟A同名,所以加载的时候直接读取了缓存中的图片A;

解决方法:1、图片不同名就是了;

                  2、不缓存就是了,将bitmap.CreateOptions 设置为 BitmapCreateOptions.IgnoreImageCache

                  3、由于限制条件,以上方法都不能用,所以借助uri的查询参数机制,使用文件的最后修改时间戳作为查询参数:

                               当文件未替换时,时间戳不变 → Uri 不变 → 复用缓存(保持缓存机制)。

                        当文件替换后,时间戳变化 → Uri 变化 → 视为新资源,重新加载并缓存新图。

 

 

方法2:

 

var bitmap = new BitmapImage();
bitmap.BeginInit();
bitmap.CacheOption = BitmapCacheOption.OnLoad; // 在加载后关闭流,跟源文件断开连接
bitmap.UriSource = new Uri(path, UriKind.RelativeOrAbsolute);
bitmap.CreateOptions = BitmapCreateOptions.IgnoreImageCache; // 忽视图片缓存,每次加载都从源文件获取
bitmap.EndInit();

 

方法3:

// 获取绝对路径(避免相对路径解析歧义)
string absolutePath = Path.GetFullPath(path);

//  获取文件时间戳(不变)
var lastWriteTime = File.GetLastWriteTimeUtc(absolutePath);
long timeStamp = lastWriteTime.Ticks;

// 构建标准 file:// Uri
var fileUri = new Uri(absolutePath, UriKind.Absolute); // 基础 file:// 协议 Uri
// 拼接片段标识符(?t=xxx)
string uriWithTimeStamp = $"{fileUri.ToString()}?t={timeStamp}";
var imageUri = new Uri(uriWithTimeStamp, UriKind.Absolute);
// 保持原缓存逻辑创建 BitmapImage
var bitmap = new BitmapImage();
bitmap.BeginInit();
bitmap.CacheOption = BitmapCacheOption.OnLoad; 
bitmap.UriSource = imageUri;
bitmap.EndInit();
bitmap.Freeze();

 

posted @ 2025-11-26 11:07  JustWantToStudy  阅读(10)  评论(0)    收藏  举报