c# - 为什么在图像列表上循环计时器滴答事件时抛出异常参数无效?
问题描述
System.ArgumentException:“参数无效。”
private void timer1_Tick(object sender, EventArgs e)
{
for (int i = 0; i < myGifList.Count; i++)
{
Bitmap bmp = new Bitmap(myGifList[i]);
pictureBox1.Image = bmp;
bmp.Dispose();
}
}
循环结束后抛出异常。
在此之前我做过:
private void timer1_Tick(object sender, EventArgs e)
{
for (int i = 0; i < myGifList.Count; i++)
{
pictureBox1.Image = new Bitmap(myGifList[i]);
}
}
但随后它抛出了内存异常。
在这之前我第一次尝试这个:
int counter = 0;
private void timer1_Tick(object sender, EventArgs e)
{
if(counter == 10)
{
counter = 0;
}
for (int i = 0; i < myGifList.Count; i++)
{
Bitmap bmp = new Bitmap(myGifList[counter]);
pictureBox1.Image = bmp;
}
counter++;
}
这是工作图像在pictureBox1中循环,但一段时间后它抛出了内存不足异常。
完整代码:
我正在下载图像,然后将图像读回列表,然后尝试将它们显示在 picutreBox1 中,并使用 trackBar1 通过计时器更改 pictureBox1 中图像的循环速度。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Extract
{
public partial class Form1 : Form
{
List<string> myGifList = new List<string>();
public Form1()
{
List<string> times = new List<string>();
string t = "";
InitializeComponent();
using (WebClient client = new WebClient()) // WebClient class inherits IDisposable
{
client.Headers.Add("user-agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.61 Safari/537.36");
client.DownloadFile("https://myimages/", @"D:\localfile.html");
var file = File.ReadAllText(@"D:\localfile.html");
int idx = file.IndexOf("arrayImageTimes.push");
int idx1 = file.IndexOf("</script>", idx);
string results = file.Substring(idx, idx1 - idx);
var statements = results.Split(new string[] { ";" }, StringSplitOptions.RemoveEmptyEntries);
for (int i = 0; i < statements.Length; i++)
{
if (i == 10)
{
break;
}
string number = statements[i].Split('\'')[1];
times.Add(number); // add to a list instead
var link = "https://myimages" + number;
client.DownloadFile(link, @"D:\Images\Image" + i + ".jpeg");
}
}
FileInfo[] fi;
DirectoryInfo dir1 = new DirectoryInfo(@"D:\Images");
fi = dir1.GetFiles("*.jpeg");
for (int i = 0; i < fi.Length; i++)
{
myGifList.Add(fi[i].FullName);
}
}
private void Form1_Load(object sender, EventArgs e)
{
}
int counter = 0;
private void timer1_Tick(object sender, EventArgs e)
{
if(counter == 10)
{
counter = 0;
}
for (int i = 0; i < myGifList.Count; i++)
{
Bitmap bmp = new Bitmap(myGifList[counter]);
pictureBox1.Image = bmp;
}
counter++;
}
private void button1_Click(object sender, EventArgs e)
{
timer1.Enabled = true;
}
private void trackBar1_Scroll(object sender, EventArgs e)
{
timer1.Interval = 100 * trackBar1.Value;
}
}
}
解决方案
您似乎正在尝试循环myGifList
,但是您已经10
在方法中硬编码了一个值。
然而,更大的问题是你甚至没有使用i
由循环定义的,所以你只是覆盖了相同的Bitmap
myGifList.Count
时间,没有任何意义 - 使你的代码效率低下。
尝试:
private void timer1_Tick(object sender, EventArgs e)
{
if (counter == myGifList.Count)
counter = 0;
pictureBox1.Image?.Dispose();
Bitmap bmp = new Bitmap(myGifList[counter]);
pictureBox1.Image = bmp;
counter++;
}
请注意,您应该在调用时使用null 条件运算符 ?
来防止可能发生的情况:NullReferenceException
.Dispose()
pictureBox1.Image?.Dispose();
这会在第一次设置图像时发生pictureBox1.Image
,null
导致.Dispose()
抛出异常。
更好的是使用PictureBox.ImageLocation
允许您显示图像而无需Bitmap
每次都创建对象的属性:
private void timer1_Tick(object sender, EventArgs e)
{
if (counter == myGifList?.Count)
counter = 0;
pictureBox1.ImageLocation = myGifList[counter];
counter++;
}
旁注:该Timer.Interval
属性也以毫秒为单位,因此如果您希望真正能够看到图像循环,我会提高100
您的值。trackBar1_Scroll(...)
推荐阅读
- python - 如何使用 Python 从 AWS Lambda 检索格式正确的 JSON
- java - 在 Kotlin 中读取 ZipInputStream
- sql - Postgres:带有 GROUP BY 的子查询
- c# - 检测是否发送了 EventHub 消息
- mysql - MySQL 对文本字段按问题分组(字段包含 HTML)
- python - 如何绘制一组曲线的不确定性界限,其中每条曲线的时间步长不一致
- vb.net - 搜索 MS Access 并在 VB.Net 文本框中显示
- docker - Hyperledger Composer - Docker Swarm
- c# - 令牌中有句点时的 JProperty SelectToken
- sql - 从 sys.procedures 中过滤掉当天更改的存储过程