c# - 处理程序在 BitmapEncoder.Frames.Add 调用中无效
问题描述
我正在使用此自定义方法将 Bitmapsource 转换为 Bitmap:
public Bitmap BitmapFromSource(BitmapSource bitmapsource) {
using (MemoryStream outStream = new MemoryStream()) {
BitmapEncoder enc = new BmpBitmapEncoder();
enc.Frames.Add(BitmapFrame.Create(bitmapsource));
enc.Save(outStream);
using (var tempBitmap = new Bitmap(outStream)) {
return new Bitmap(tempBitmap);
} } }
这个方法在我的代码中被调用了几次,效果很好。但是当我用鼠标单击事件或按键事件调用它时,我得到处理程序无效错误。
我不知道如何进行。有什么建议吗?
在代码中,我有一个位帧列表:
List<BitmapFrame> myImages = new List<BitmapFrame>();
最初,当我将每一帧显示到几个图片框中时,该方法有效:
var handler = new EventHandler(pictureBoxClick);
for (int i = 0; i < (decoder.Frames.Count); i++) {
var picture = new MyPictureBox {
Name = "pictureBoxFrame" + i,
Width = (int)newWidth,
Height = (int)newHeight,
SizeMode = PictureBoxSizeMode.Zoom,
Location= loc,
Image = BitmapFromSource(myImages[i]), };
Controls[i].Click += handler;
splitContainer1.Panel1.Controls.Add(picture);
}
然后当我单击这些图片框之一时:
void pictureBoxClick (object sender , EventArgs e) {
var selectedPictureBox = (PictureBox)sender;
int idx = Controls.IndexOf(selectedPictureBox);
pictureBox1.Image = BitmapFromSource(myImages[idx]);
}
我得到错误...
解决方案
从我从您的代码中可以看出,您很可能是“流”的受害者。
这意味着,当您从FileStream加载资源时,该流必须在该资源的生命周期内可用(未释放)。这也适用于BitmapDecoder
引用的图像资源。
如果您处理用于初始化的流,它的 Frames 集合将设置为 1x1 大小的 1 帧。
由于让流保持打开状态并不是一个好主意,因此通常会将其复制到MemoryStream(原始字节数组)并在之后立即处理。BitmapDecoder
无论您可能读过或听到什么,
MemoryStream
都不需要处理 a (至少不需要立即处理),因为它并没有真正使用任何重要资源。
从流中加载图像资源后,BitmapDecoder
可以这样初始化:
MemoryStream memstream = new MemoryStream();
stream.CopyTo(memstream);
memstream.Position = 0;
BitmapDecoder bitmapDecoder = BitmapDecoder.Create(memstream,
BitmapCreateOptions.PreservePixelFormat,
BitmapCacheOption.Default);
这样,BitmapFrames
的BitmapDecoder
将有一个有效的句柄,因为底层流仍然是活动的。
当您加载新图像时,MemoryStream
将使用新的FileStream
.
为了测试这里和评论中所写内容的结果(这些建议也很相关),我构建了一个测试表单类。
您可以从 PasteBin下载源代码。
推荐阅读
- spring - 如何使用来自 http://developer.nytimes.com 的 Spring Boot 获取当前最热门的故事
- html - 子 div 是可滚动的,但在子元素中添加内容时,主体的高度仍然会增加
- c# - 仅显示一次 Gameobject 统一
- android - Android:滚动时不调用 OnbindViewHolder
- reactjs - 为什么 react-native start 命令停留在“加载依赖关系图,完成”上。
- html - CSS - 添加文本时导航栏变得不模糊
- wcf - 从 Android 使用 WCF
- javascript - react-redux Reducer 不会将对象传递给商店
- scala - 在 spark scala 函数中将 List 作为参数传递会出错
- python - 在 Tkinter 中绑定 '<' 键