gpt4 book ai didi

c# - 从 PictureBox 解锁图像

转载 作者:行者123 更新时间:2023-12-02 01:16:46 36 4
gpt4 key购买 nike

我目前正在开发一个应用程序来帮助在我的工作中扫描和显示图像。

我的应用程序是用多个表单构建的,这里最重要的表单是我的mainForm,用于显示有关当前扫描的统计信息和具有不同功能的菜单条。我还有 ImageViewerForm 和一个 PictureBox,它显示在辅助监视器上以查看当前扫描的图像。

我正在使用 Timer 轮询图像扫描到的文件夹。扫描新图像并解锁图像后,我会将其抓取到 FileStream 中并将其显示在 PictureBox 中,如下所示:

public static void SetPicture(string filename, PictureBox pb)
{
try
{
Image currentImage;

//currentImage = ImageFast.FromFile(filename);
using (FileStream fsImage = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
currentImage = ScaleImage(Image.FromStream(fsImage), new Size(pb.Width, pb.Height));

if (pb.InvokeRequired)
{
pb.Invoke(new MethodInvoker(
delegate()
{
pb.Image = currentImage;
}));
}
else
{
pb.Image = currentImage;
}
}
}
catch (Exception imageEx)
{
throw new ExceptionHandler("Error when showing image", imageEx);
}
}

public static Image ScaleImage(Image imgToResize, Size size)
{
int sourceWidth = imgToResize.Width;
int sourceHeight = imgToResize.Height;

float nPercent = 0;
float nPercentW = 0;
float nPercentH = 0;

nPercentW = ((float)size.Width / (float)sourceWidth);
nPercentH = ((float)size.Height / (float)sourceHeight);

if (nPercentH < nPercentW)
nPercent = nPercentH;
else
nPercent = nPercentW;

int destWidth = (int)(sourceWidth * nPercent);
int destHeight = (int)(sourceHeight * nPercent);

Bitmap b = new Bitmap(destWidth, destHeight);

using (Graphics g = Graphics.FromImage(b))
{
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
g.DrawImage(imgToResize, 0, 0, destWidth, destHeight);
}

return b;
}

这样,PictureBox 中显示的图像不应被锁定,但它确实被锁定了。问题是扫描的图像可能必须重新扫描,如果我这样做,我将在尝试从扫描软件覆盖图像文件时遇到共享冲突错误。

有人知道我能做什么吗?

解决方案

感谢@SPFiredrake,我找到了创建临时文件以显示在 PictureBox 中的解决方案,同时保持原始图像解锁。

public static void SetPicture(string filename, PictureBox pb)
{
try
{
Image currentImage;

//currentImage = ImageFast.FromFile(filename);
using (FileStream fsImage = new FileStream(CreateTempFile(filename), FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
currentImage = ScaleImage(Image.FromStream(fsImage), new Size(pb.Width, pb.Height));

if (pb.InvokeRequired)
{
pb.Invoke(new MethodInvoker(
delegate()
{
pb.Image = currentImage;
}));
}
else
{
pb.Image = currentImage;
}
}
}
catch (Exception imageEx)
{
throw new ExceptionHandler("Error when showing image", imageEx);
}
}

public static string CreateTempFile(string fileName)
{
if (string.IsNullOrEmpty(fileName))
throw new ArgumentNullException("fileName");
if (!File.Exists(fileName))
throw new ArgumentException("Specified file must exist!", "fileName");
string tempFile = Path.Combine(Path.GetTempPath(), Guid.NewGuid() + Path.GetExtension(fileName));
File.Copy(fileName, tempFile);

Log.New("Temp file created: " + tempFile);

return tempFile;
}

最佳答案

这里的问题是图像是从 FileStream 加载的,它被 PictureBox 锁定,因为它持有对流的引用。您应该做的是首先将图片加载到本地内存(通过 byte[] 数组),然后从 MemoryStream 加载图像。在您的 SetPicture 方法中,您应该尝试以下更改并查看它是否有效:

public static void SetPicture(string filename, PictureBox pb)
{
try
{
Image currentImage;
byte[] imageBytes = File.ReadAllBytes(filename);
using(MemoryStream msImage = new MemoryStream(imageBytes))
{
currentImage = ScaleImage(Image.FromStream(msImage), new Size(pb.Width, pb.Height));
....
}

编辑:在我们在 Chat 中进行对话后,更新您最终使用的修复:

public static void SetPicture(string filename, PictureBox pb)
{
try
{
Image currentImage;
string tempFile = Path.Combine(Path.GetTempDirectory(), Guid.NewGuid().ToString() + Path.GetExtension(filename));
File.Copy(filename, tempFile);
//currentImage = ImageFast.FromFile(filename);
using (FileStream fsImage = new FileStream(tempFile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
...

通过这种方式,您可以使用临时文件实际加载图片框,而不会影响原始文件(在初始副本之外)。

关于c# - 从 PictureBox 解锁图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10431868/

36 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com