经过一些更多的测试后,我发现这个问题可能是由于图像没有及时加载,无法被克隆到位图中并显示出来。这可能吗?
注意:是的,标题中还有其他关于这个错误的问题,但从一项研究来看,这似乎是一个含糊不清的错误,有许多可能的原因。我没有发现任何与我的情况相同的问题。
我得到了以下错误。
System.ArgumentException was unhandled
HResult=-2147024809
Message=Parameter is not valid.
Source=System.Drawing它产生于这段代码。表面上看起来是随机的(例如,有时起作用,有时不起作用。在没有重新启动VS和重建项目的情况下,它连续运行的次数越多,就越有可能失败):
private Bitmap GetSprite(bool anim, int tsIndex, int tileIdx) {
System.Drawing.Rectangle cloneRect;
string prefix = (anim) ? "A" : "S";
using (Bitmap b = new Bitmap(prefix + tsIndex.ToString() + ".png")) {
if (anim) {
cloneRect = new System.Drawing.Rectangle(BaseObjects.A_AnimSpriteSets[tsIndex].StaticRecs[tileIdx].X, BaseObjects.A_AnimSpriteSets[tsIndex].StaticRecs[tileIdx].Y, BaseObjects.A_AnimSpriteSets[tsIndex].RecWidth, BaseObjects.A_AnimSpriteSets[tsIndex].RecHeight);
} else {
cloneRect = new System.Drawing.Rectangle(BaseObjects.A_StaticSpriteSets[tsIndex].StaticRecs[tileIdx].X, BaseObjects.A_StaticSpriteSets[tsIndex].StaticRecs[tileIdx].Y, BaseObjects.A_StaticSpriteSets[tsIndex].RecWidth, BaseObjects.A_StaticSpriteSets[tsIndex].RecHeight);
}
return b.Clone(cloneRect, b.PixelFormat);
}
}具体而言,第四行:
using (Bitmap b = new Bitmap(prefix + tsIndex.ToString() + ".png"))代码的简化目标是根据spriteset索引和sprite索引从spriteset返回包含sprite的位图。此位图显示在PictureBox中,直到更改为不同的图像为止。我知道逻辑起作用,这不是问题所在。我用来测试的.png是384*256。
所有参数都被正确设置,所有引用的文件都在那里,一切似乎都井井有条。最奇怪的是,它有时起作用,有时不起作用。这使我相信,这可能是System.Drawing内部的内存泄漏,但我似乎无法找到它。
编辑:更新了代码并添加了StackTrace。尽管不再使用位图(例如,有关位图的处理方式,请参阅下面的代码),但仍然存在相同的问题。
if (Sprite.Image != null) { Sprite.Image.Dispose(); }
Sprite.Image = GetSprite(true, tsIdx, tileIdx);StackTrace:
System.ArgumentException was unhandled
HResult=-2147024809
Message=Parameter is not valid.
Source=System.Drawing
StackTrace:
at System.Drawing.Bitmap..ctor(String filename)
at CreationTool.Main.GetSprite(Boolean anim, Int32 tsIndex, Int32 tileIdx) in F:\~\~\CreationTool\Main.cs:line 420
at CreationTool.Main.Input_EnemySprite_SelectedIndexChanged(Object sender, EventArgs e) in F:\~\~\CreationTool\Main.cs:line 107
at System.Windows.Forms.ComboBox.OnSelectedIndexChanged(EventArgs e)
at System.Windows.Forms.ComboBox.set_SelectedIndex(Int32 value)
at CreationTool.States.State_Enemy.populateForm() in F:\~\~\CreationTool\States\State_Enemy.cs:line 28
at CreationTool.States.State_Enemy.Load(String name) in F:\~\~\CreationTool\States\State_Enemy.cs:line 22
at CreationTool.Main.btnLoad_Click(Object sender, EventArgs e) in F:\~\~\CreationTool\Main.cs:line 174
at System.Windows.Forms.Control.OnClick(EventArgs e)
at System.Windows.Forms.Button.OnClick(EventArgs e)
at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.ButtonBase.WndProc(Message& m)
at System.Windows.Forms.Button.WndProc(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopData)
at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
at System.Windows.Forms.Application.Run(Form mainForm)
at CreationTool.Program.Main() in F:\~\~\CreationTool\Program.cs:line 15
at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()发布于 2012-12-31 08:29:22
哇,这代码漏得要命。您需要释放实现IDisposable的所有类型,这是System.Drawing程序集(GDI+)中相当多的类型:
private Bitmap GetSprite(bool anim, int tsIndex, int tileIdx)
{
Rectangle cloneRect;
string prefix = (anim) ? "A" : "S";
using (Bitmap b = new Bitmap(prefix + tsIndex.ToString() + ".png"))
{
if (anim)
{
cloneRect = new Rectangle(BaseObjects.A_AnimSpriteSets[tsIndex].StaticRecs[tileIdx].X, BaseObjects.A_AnimSpriteSets[tsIndex].StaticRecs[tileIdx].Y, BaseObjects.A_AnimSpriteSets[tsIndex].RecWidth, BaseObjects.A_AnimSpriteSets[tsIndex].RecHeight);
}
else
{
cloneRect = new Rectangle(BaseObjects.A_StaticSpriteSets[tsIndex].StaticRecs[tileIdx].X, BaseObjects.A_StaticSpriteSets[tsIndex].StaticRecs[tileIdx].Y, BaseObjects.A_StaticSpriteSets[tsIndex].RecWidth, BaseObjects.A_StaticSpriteSets[tsIndex].RecHeight);
}
return b.Clone(cloneRect, b.PixelFormat);
}
}还请确保还通过将调用方包装在using语句中来处理此函数返回的位图:
using (Bitmap b = GetSprite(true, 0, 5))
{
// do whatever you needed to do with the bitmap here
}发布于 2013-09-20 11:14:49
我也发现这是为了寻找答案。请注意,它还可以在下列情况下引发异常:
流包含一个单维大于65,535像素的PNG图像文件。
http://msdn.microsoft.com/en-us/library/z7ha67kw.aspx
发布于 2020-09-20 06:42:18
对我来说,这是因为引用了一个相对路径,比如@"Resources\ImageName.png"。在调试模式中,我没有加载映像的问题,但正如OP所暗示的,这实际上可能是资源加载时间问题。我正确地使用了using并处理了我的对象,但这实际上与问题无关。一旦在发布内部运行,“参数无效”的错误就会再次出现。
我怀疑编译器的优化是这样的,在调试模式下,映像流确实能够被扩展以便构造函数解析,但是在发布版构建时,路径仍然需要在cctor准备解析路径时进行扩展,这导致路径无效错误。只需将路径从相对路径更改为固定路径或预展开路径即可解决此问题。
https://stackoverflow.com/questions/14099246
复制相似问题