C# - 在运行时更新 pictureBox.Image 导致错误
C# - Updating pictureBox.Image during Runtime causes Error
我正在尝试在运行时更改 pictureBox.Image。我有几个存储图片的模型 classes,每当我单击 MenuStripItem 时,我都会调用方法 "ChangePictureBoxImages"。直到那时没有错误(pB 是不可见的!)但是一旦我调用使 pB 可见的方法我得到一个错误。错误代码:"An unhandled exception of type 'System.ArgumentException' occurred in System.Drawing.dll"。
研究表明我应该处理图片框并将其设置为 "null",但这没有帮助。
我的代码:
using (Image current = BitmapManipulator.EvaluateMesurement(CSV_Name1, max_Rows, max_Col, var.TopImage, var.BitmapToManipulate, pB_ColourScale_Evaluation.Image, var.BitmapToManipulate, var.Filepath, var.FoldID))
{
var.LastEvaluationImage = current;
BitmapManipulator.CombineImagesAndSaveThem_Evaluation(var.TopImage, var.BitmapToManipulate, pB_ColourScale_Evaluation.Image, var.Filepath, var.FoldID); //saves the Files as jpg
if (var.CurrentlyShownToUser) //checks if the MenuStripItem is the active one
{
if (var.LastEvaluationImage == null) { MessageBox.Show("the image is null");} //only for debugging purpose -> does never call
ChangePictureBoxImages();
}
}
和 ChangePictureBoxImages():
public void ChangePictureBoxImages()
{
foreach (Fold fold in FoldExisting)
{
if (fold.FoldID == LastSelectedMenuStripItem_Name) //the clicked item is the last Selected MenuStripItem
{
if (fold.LastEvaluationImage != null)
{
Debug.WriteLine(pB_Evaluation_Bottom.Image.ToString() + " " + fold.LastEvaluationImage.ToString());
pB_Evaluation_Bottom.Image = fold.LastEvaluationImage;
}
pB_Evaluation_Top.Image = fold.TopImage;
}
}
}
到此为止没有错误,调用"pB_Evaluation_Bottom.visible = true"后出现错误。 (或者如果我首先调用可见方法,则在更改图像时会出现错误!)在 MenuStripItem 上单击 2 次时也会出现错误。我从 Class 中加载图片如下:
这将在折叠中设置一个图像 class,然后将对该图像进行操作并存储在 LastEvaluationImage
private void setTheImages(string PictureToManipulate, string PathToTopImage)
{
try
{
this.BitmapToManipulate_intern = (Image)Image.FromFile(@PictureToManipulate, true);
this.TopImage_intern = (Image)Image.FromFile(@PathToTopImage, true);
}
catch (ArgumentNullException ex)
{
Debug.WriteLine("The BitMap for the manipulation process and the top image is not created.");
}
}
和存储最后一张图片的 LastEvaluationImage -> 这将被称为新的 pb.Image
private Image LastEvaluationImage_intern;
public Image LastEvaluationImage
{
get
{
return this.LastEvaluationImage_intern;
}
set
{
if (LastEvaluationImage_intern != null) { LastEvaluationImage_intern.Dispose(); LastEvaluationImage_intern = null; }
this.LastEvaluationImage_intern = value;
this.LastEvaluationTime_intern = DateTime.Now;
}
}
我知道这有点复杂,但我希望有人能帮助我。
提前致谢!
更新:错误必须在以下代码中:
BitmapManipulator.EvaluateMeasurement 代码:
public Image EvaluateMesurement(double[][] MeasuredValues, int max_Rows, int max_Col, Image pB_Evaluation_Top, Image pB_Evaluation_Bottom, Image pB_EvaluationColourScale, Image ManipulatedBitmap, string PathMeasurementFiles, string Foldname)
{
using (Bitmap bitmap = new Bitmap(ManipulatedBitmap))
{
// the data array sizes:
int number_nio = 0;
int number_total = 0;
List<FileInfo> LastFiles;
int got_number_for_trends = Properties.Settings.Default.TrendNumber;
SolidBrush myBrush = new SolidBrush(red);
using (Graphics g = Graphics.FromImage(bitmap))
{
Random rnd = new Random(8);
int[,] data = new int[max_Col, max_Rows];
// scale the tile size:
float sx = 1f * bitmap.Width / data.GetLength(0);
float sy = 1f * bitmap.Height / data.GetLength(1);
LastFiles = FM.GetLastFiles_Trend(ref got_number_for_trends, PathMeasurementFiles);
double[][] CSV_Statistiken = FM.LastFilesToCSV(got_number_for_trends, true, LastFiles, PathMeasurementFiles);
for (int x = 0; x < max_Col; x++)
{
for (int y = max_Rows - 1; y >= 0; y--)
{
number_total++;
RectangleF r = new RectangleF(x * sx, y * sy, sx, sy);
if (MeasuredValues[y][x] < Properties.Settings.Default.Threshhold)
{
number_nio++;
if (CSV_Statistiken[y][x] == Properties.Settings.Default.TrendNumber)
{
myBrush.Color = Color.FromArgb(150, black);
g.FillRectangle(myBrush, r);
}
else
{
myBrush.Color = Color.FromArgb(150, red);
g.FillRectangle(myBrush, r);
}
}
else
{
myBrush.Color = Color.FromArgb(150, green);
g.FillRectangle(myBrush, r);
}
}
}
}
return bitmap;
}
}
此返回的位图将存储在 fold.LastEvaluationImage 中,如下所示:
using (Image current = BitmapManipulator.EvaluateMesurement(CSV_Name1, max_Rows, max_Col, var.TopImage, var.BitmapToManipulate, pB_ColourScale_Evaluation.Image, var.BitmapToManipulate, var.Filepath, var.FoldID))
{
var.LastEvaluationImage = current;
}
您正在返回已处置的位图。你不能画出不复存在的东西也就不足为奇了:)
在这种情况下,using (bitmap)
是您最不想要的。 bitmap
必须 存活时间超过使用范围。调用者中的 using (current)
也有同样的问题——你又过早地处理了图像。你只能在很明显它不会再被使用时处理它——例如当您用新图片替换它时。
详细来说,using
在您离开其作用域时除了调用 Dispose
之外什么都不做。在 Bitmap
的情况下(它只是 GDI 位图的 "thin" 包装器),这将释放存储实际图像数据的内存。没有什么有趣的东西了,所以没有什么可画的(就 GDI 而言,你基本上会调用 DrawBitmap(NULL)
)。
我正在尝试在运行时更改 pictureBox.Image。我有几个存储图片的模型 classes,每当我单击 MenuStripItem 时,我都会调用方法 "ChangePictureBoxImages"。直到那时没有错误(pB 是不可见的!)但是一旦我调用使 pB 可见的方法我得到一个错误。错误代码:"An unhandled exception of type 'System.ArgumentException' occurred in System.Drawing.dll"。
研究表明我应该处理图片框并将其设置为 "null",但这没有帮助。
我的代码:
using (Image current = BitmapManipulator.EvaluateMesurement(CSV_Name1, max_Rows, max_Col, var.TopImage, var.BitmapToManipulate, pB_ColourScale_Evaluation.Image, var.BitmapToManipulate, var.Filepath, var.FoldID))
{
var.LastEvaluationImage = current;
BitmapManipulator.CombineImagesAndSaveThem_Evaluation(var.TopImage, var.BitmapToManipulate, pB_ColourScale_Evaluation.Image, var.Filepath, var.FoldID); //saves the Files as jpg
if (var.CurrentlyShownToUser) //checks if the MenuStripItem is the active one
{
if (var.LastEvaluationImage == null) { MessageBox.Show("the image is null");} //only for debugging purpose -> does never call
ChangePictureBoxImages();
}
}
和 ChangePictureBoxImages():
public void ChangePictureBoxImages()
{
foreach (Fold fold in FoldExisting)
{
if (fold.FoldID == LastSelectedMenuStripItem_Name) //the clicked item is the last Selected MenuStripItem
{
if (fold.LastEvaluationImage != null)
{
Debug.WriteLine(pB_Evaluation_Bottom.Image.ToString() + " " + fold.LastEvaluationImage.ToString());
pB_Evaluation_Bottom.Image = fold.LastEvaluationImage;
}
pB_Evaluation_Top.Image = fold.TopImage;
}
}
}
到此为止没有错误,调用"pB_Evaluation_Bottom.visible = true"后出现错误。 (或者如果我首先调用可见方法,则在更改图像时会出现错误!)在 MenuStripItem 上单击 2 次时也会出现错误。我从 Class 中加载图片如下:
这将在折叠中设置一个图像 class,然后将对该图像进行操作并存储在 LastEvaluationImage
private void setTheImages(string PictureToManipulate, string PathToTopImage)
{
try
{
this.BitmapToManipulate_intern = (Image)Image.FromFile(@PictureToManipulate, true);
this.TopImage_intern = (Image)Image.FromFile(@PathToTopImage, true);
}
catch (ArgumentNullException ex)
{
Debug.WriteLine("The BitMap for the manipulation process and the top image is not created.");
}
}
和存储最后一张图片的 LastEvaluationImage -> 这将被称为新的 pb.Image
private Image LastEvaluationImage_intern;
public Image LastEvaluationImage
{
get
{
return this.LastEvaluationImage_intern;
}
set
{
if (LastEvaluationImage_intern != null) { LastEvaluationImage_intern.Dispose(); LastEvaluationImage_intern = null; }
this.LastEvaluationImage_intern = value;
this.LastEvaluationTime_intern = DateTime.Now;
}
}
我知道这有点复杂,但我希望有人能帮助我。
提前致谢!
更新:错误必须在以下代码中: BitmapManipulator.EvaluateMeasurement 代码:
public Image EvaluateMesurement(double[][] MeasuredValues, int max_Rows, int max_Col, Image pB_Evaluation_Top, Image pB_Evaluation_Bottom, Image pB_EvaluationColourScale, Image ManipulatedBitmap, string PathMeasurementFiles, string Foldname)
{
using (Bitmap bitmap = new Bitmap(ManipulatedBitmap))
{
// the data array sizes:
int number_nio = 0;
int number_total = 0;
List<FileInfo> LastFiles;
int got_number_for_trends = Properties.Settings.Default.TrendNumber;
SolidBrush myBrush = new SolidBrush(red);
using (Graphics g = Graphics.FromImage(bitmap))
{
Random rnd = new Random(8);
int[,] data = new int[max_Col, max_Rows];
// scale the tile size:
float sx = 1f * bitmap.Width / data.GetLength(0);
float sy = 1f * bitmap.Height / data.GetLength(1);
LastFiles = FM.GetLastFiles_Trend(ref got_number_for_trends, PathMeasurementFiles);
double[][] CSV_Statistiken = FM.LastFilesToCSV(got_number_for_trends, true, LastFiles, PathMeasurementFiles);
for (int x = 0; x < max_Col; x++)
{
for (int y = max_Rows - 1; y >= 0; y--)
{
number_total++;
RectangleF r = new RectangleF(x * sx, y * sy, sx, sy);
if (MeasuredValues[y][x] < Properties.Settings.Default.Threshhold)
{
number_nio++;
if (CSV_Statistiken[y][x] == Properties.Settings.Default.TrendNumber)
{
myBrush.Color = Color.FromArgb(150, black);
g.FillRectangle(myBrush, r);
}
else
{
myBrush.Color = Color.FromArgb(150, red);
g.FillRectangle(myBrush, r);
}
}
else
{
myBrush.Color = Color.FromArgb(150, green);
g.FillRectangle(myBrush, r);
}
}
}
}
return bitmap;
}
}
此返回的位图将存储在 fold.LastEvaluationImage 中,如下所示:
using (Image current = BitmapManipulator.EvaluateMesurement(CSV_Name1, max_Rows, max_Col, var.TopImage, var.BitmapToManipulate, pB_ColourScale_Evaluation.Image, var.BitmapToManipulate, var.Filepath, var.FoldID))
{
var.LastEvaluationImage = current;
}
您正在返回已处置的位图。你不能画出不复存在的东西也就不足为奇了:)
在这种情况下,using (bitmap)
是您最不想要的。 bitmap
必须 存活时间超过使用范围。调用者中的 using (current)
也有同样的问题——你又过早地处理了图像。你只能在很明显它不会再被使用时处理它——例如当您用新图片替换它时。
详细来说,using
在您离开其作用域时除了调用 Dispose
之外什么都不做。在 Bitmap
的情况下(它只是 GDI 位图的 "thin" 包装器),这将释放存储实际图像数据的内存。没有什么有趣的东西了,所以没有什么可画的(就 GDI 而言,你基本上会调用 DrawBitmap(NULL)
)。