BitmapImage 载入到 Image 后无法更新 显示 原因

WPF BitmapImage更新问题及解决方案
在使用WPF开发模板编辑软件时,遇到BitmapImage加载到Image控件后无法更新显示的问题。当BitmapImage进行镜像或旋转操作后,Image仍然显示旧的图像。经过分析,发现原因是图片源路径相同且参数未改变。解决方案包括:1.更改图片的路径;2.修改BitmapImage的参数,如设置旋转角度。只有当BitmapImage发生变化时,Image的显示才会更新。

最近 使用WPF框架 做模板编辑软件开发,过程中遇到一个很奇怪的问题:

用  System.Windows.Controls.Image 显示 一张bmp图片后作镜像或旋转,却无法更新到Image中去,当时没能注意分析这个问题,改用的其它方式实现了,但后来改回来再看时,再次发现该问题。

具体操作和故障现象:

将bmp图片用BitmapImage载入,指定为Image控件的Sourcer显示 。将bmp图片镜像后,第二次再用BitampImage指定为Image的图片源。发现Image显示 的仍是上一张bmp图片,很奇怪该图片源已被镜像处理过,按正常来讲显示的是镜像后的图片。仔细核对后未并见代码有何异常:

尝试将BitmapImage旋转:bitmapImg.Rotation = Rotation.Rotate90 图片能正常显示 出刚刚更改的效果了。

多次尝试之后 ,发现是新指定的BitmapImage图片源(图片路径)与上次相同,且其它参数不做任何更改,程序会载入上一次保留的bmp图片。导致无论怎样修改 Image图片源 后重新载入,它都不更新到界面。

解决方法是

1.载入的路径 与上次的图片路径不同

2.BitmapImage 参数更改,如旋转等。

这样当BitmapImage参数有了变化 ,程序中Image的图片才更新显示 ,否则 显示 的仍是上一次的图片。

private const double MaxImageWidth = 300; // 最大显示宽度 private const double MaxImageHeight = 150; // 最大显示高度 private void PasteImageToRichTextBox() { if (!Clipboard.ContainsImage()) { MessageBox.Show("剪贴板中没有图片,请使用任意截图工具进行截图"); return; } Dispatcher.Invoke(() => { try { // 清除提示文本 RemoveHintText(); // 图片保存路径 string ImageSavePath = "C:/ProgramData/EasyBIM/Proofread/"; // 确保目录存在 if (!Directory.Exists(ImageSavePath)) { Directory.CreateDirectory(ImageSavePath); } // 生成唯一文件名 string timestamp = DateTime.Now.ToString("yyyyMMddHHmmss"); string fileName = $"Image_{timestamp}.png"; string filePath = System.IO.Path.Combine(ImageSavePath, fileName); // 直接从剪贴板获取BitmapSource BitmapSource clipboardImage = Clipboard.GetImage(); if (clipboardImage == null) return; // 直接使用BitmapFrame创建BitmapImage BitmapImage bitmapImage; using (MemoryStream stream = new MemoryStream()) { // 使用BmpBitmapEncoder替代PngBitmapEncoder解决兼容性问题 BmpBitmapEncoder encoder = new BmpBitmapEncoder(); encoder.Frames.Add(BitmapFrame.Create(clipboardImage)); encoder.Save(stream); stream.Position = 0; bitmapImage = new BitmapImage(); bitmapImage.BeginInit(); bitmapImage.CacheOption = BitmapCacheOption.OnLoad; bitmapImage.StreamSource = stream; bitmapImage.EndInit(); } // 计算缩放比例 double scaleRatio = Math.Min( MaxImageWidth / bitmapImage.PixelWidth, MaxImageHeight / bitmapImage.PixelHeight ); scaleRatio = Math.Min(scaleRatio, 1.0); // 确保放大图片 // 创建图像控件 var imageControl = new System.Windows.Controls.Image { Source = bitmapImage, Width = bitmapImage.PixelWidth * scaleRatio, Height = bitmapImage.PixelHeight * scaleRatio, Stretch = Stretch.Uniform, Margin = new Thickness(0, 5, 0, 5) }; // 创建容器 Border imageBorder = new Border { Child = imageControl, BorderBrush = Brushes.LightGray, BorderThickness = new Thickness(1), CornerRadius = new CornerRadius(4), Background = Brushes.White, Padding = new Thickness(2) }; // 创建InlineUIContainer InlineUIContainer container = new InlineUIContainer(imageBorder) { BaselineAlignment = BaselineAlignment.Center // 确保垂直居中 }; // 获取当前段落 Paragraph currentParagraph = rtbImages3.CaretPosition.Paragraph ?? new Paragraph(); // 如果是空文档则添加新段落 if (rtbImages3.Document.Blocks.Count == 0) { rtbImages3.Document.Blocks.Add(currentParagraph); } // 添加图片到段落 currentParagraph.Inlines.Add(container); // 设置新光标位置 rtbImages3.CaretPosition = container.ElementEnd; //将路径关联到当前选中的行后保存图片 if (pfDataGrid.SelectedItem != null) { var selectedItem = pfDataGrid.SelectedItem as ProofreadListModel; if (selectedItem != null) { selectedItem.ImagePath = filePath; // 使用高保真方式保存原始图片 using (FileStream fileStream = new FileStream(filePath, FileMode.Create)) { PngBitmapEncoder encoder = new PngBitmapEncoder(); encoder.Frames.Add(BitmapFrame.Create(clipboardImage)); //使用原始剪贴板图片 encoder.Save(fileStream); } //// 检查ImagePath是否存在,并载入对应图片 //if (!string.IsNullOrEmpty(selectedItem.ImagePath) && File.Exists(selectedItem.ImagePath)) //{ // foreach (var item in pfDataGrid.ItemsSource) // { // var model = item as ProofreadListModel; // if (model != null && model.ImagePath == selectedItem.ImagePath) // { // Dispatcher.Invoke(() => LoadImageIntoRichTextBox(selectedItem.ImagePath)); // } // } //} //// 如果没有图片,清空RichTextBox //else //{ // Dispatcher.Invoke(() => rtbImages3.Document.Blocks.Clear()); //} } } else { rtbImages3.Document.Blocks.Clear(); MessageBox.Show("请先选择列表内意见内容以关联截图"); } } catch (Exception ex) { MessageBox.Show($"图片粘贴失败: {ex.Message}"); } }); } /// <summary> /// 读取截图到富文本 /// </summary> /// <param name="imagePath"></param> private void LoadImageIntoRichTextBox(string imagePath) { try { rtbImages3.Document.Blocks.Clear(); // 创建BitmapImage BitmapImage bitmap = new BitmapImage(); bitmap.BeginInit(); bitmap.CacheOption = BitmapCacheOption.OnLoad; // 缓存图片,关闭流后仍可用 bitmap.UriSource = new Uri(imagePath); bitmap.EndInit(); // 计算缩放比例(与之前粘贴图片时的逻辑一致) double scaleRatio = Math.Min( MaxImageWidth / bitmap.PixelWidth, MaxImageHeight / bitmap.PixelHeight ); scaleRatio = Math.Min(scaleRatio, 1.0); // 确保放大 // 创建图像控件 var imageControl = new System.Windows.Controls.Image { Source = bitmap, Width = bitmap.PixelWidth * scaleRatio, Height = bitmap.PixelHeight * scaleRatio, Stretch = Stretch.Uniform, Margin = new Thickness(0, 5, 0, 5) }; // 创建容器 Border imageBorder = new Border { Child = imageControl, BorderBrush = Brushes.LightGray, BorderThickness = new Thickness(1), CornerRadius = new CornerRadius(4), Background = Brushes.White, Padding = new Thickness(2) }; // 创建InlineUIContainer InlineUIContainer container = new InlineUIContainer(imageBorder) { BaselineAlignment = BaselineAlignment.Center }; // 创建段落并添加图片 Paragraph para = new Paragraph(); para.Inlines.Add(container); // 添加到RichTextBox rtbImages3.Document.Blocks.Add(para); } catch (Exception ex) { MessageBox.Show($"图片加载失败: {ex.Message}"); AddHintText(); } }上述代码为截图粘贴保存读取到富文本的代码,为什么截图保存到文件夹内的图片完整
最新发布
09-11
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值