4

我有一个表单,用户可以先扫描到位图。扫描完成并加载位图后,我有 4 个文本框被启用。在每个文本框旁边,我有一个名为“从图像剪切”的按钮。当用户单击按钮时,他们可以在位图中单击并拖动以使用 MODI 获取选定的文本。

除了一个烦人的错误外,这很完美:当我单击“从图像剪切”按钮并拖动一个正方形时,它会将信息很好地发送到文本框。然后,如果我单击下一个文本框,它会非常顺利,但是如果我使用 Tab 键离开该字段,我会得到一个“参数无效”ArgumentException并且它没有显示代码中的位置的任何帮助崩溃了。我可以毫无问题地在表单中进行选项卡,但是一旦扫描了位图,当我使用选项卡键时,它会像 10 次中的 9 次一样崩溃。

我尝试使用以下方法覆盖 tab 键(仅用于调试):

Protected Overrides Function ProcessTabKey(ByVal forward As Boolean) As Boolean
    MsgBox("TAB is currently disabled!")
    Return False 'Tried True as well, just in case
End Function

...但它仍然崩溃。

关于出了什么问题的任何建议?因为我不知道从哪里开始调试,所以我不知道要显示什么代码。

编辑 1

这是ArgumentException抛出的堆栈跟踪:

  • 在 System.Drawing.Image.get_Width()
  • 在 System.Drawing.Image.get_Size()
  • 在 System.Windows.Forms.PictureBox.ImageRectangleFromSizeMode(PictureBoxSizeMode 模式)
  • 在 System.Windows.Forms.PictureBox.OnPaint(PaintEventArgs pe)
  • 在 System.Windows.Forms.Control.PaintWithErrorHandling(PaintEventArgs e,Int16 层)
  • 在 System.Windows.Forms.Control.WmPaint(消息和 m)
  • 在 System.Windows.Forms.Control.WndProc(消息和 m)
  • 在 System.Windows.Forms.Control.ControlNativeWindow.OnMessage(消息& m)
  • 在 System.Windows.Forms.Control.ControlNativeWindow.WndProc(消息和 m)
  • 在 System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd,Int32 msg,IntPtr wparam,IntPtr lparam)
  • 在 System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(味精和味精)
  • 在 System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID,Int32 原因,Int32 pvLoopData)
  • 在 System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 原因,ApplicationContext 上下文)
  • 在 System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 原因,ApplicationContext 上下文)
  • 在 Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.OnRun()
  • 在 Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.DoApplicationModel()
  • 在 Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.Run(字符串 [] 命令行)
  • 在 ORC_Testing.My.MyApplication.Main(String[] Args) 在 17d14f5c-a337-4978-8281-53493378c1071.vb:line 81
  • 在 System.AppDomain._nExecuteAssembly(RuntimeAssembly 程序集,字符串 [] 参数)
  • 在 System.AppDomain.ExecuteAssembly(字符串 assemblyFile,证据 assemblySecurity,String [] args)
  • 在 Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
  • 在 System.Threading.ThreadHelper.ThreadStart_Context(对象状态)
  • 在 System.Threading.ExecutionContext.Run(ExecutionContext executionContext,ContextCallback 回调,对象状态,布尔 ignoreSyncCtx)
  • 在 System.Threading.ExecutionContext.Run(ExecutionContext executionContext,ContextCallback 回调,对象状态)
  • 在 System.Threading.ThreadHelper.ThreadStart()

编辑 2

这是我扫描/加载图像的方式:

Dim filename As Collection
filename = TwainHandler.ScanImages("c:\scan\", "tif")
Dim ScannedFile As Image = Image.FromFile(filename(1))
PictureBox1.Image = ScannedFile
PictureBox1.Width = ScannedFile.Width
' etc.
4

3 回答 3

12

您的问题很可能是,在某些时候,您正在对您的一个对象调用该Dispose方法。Image当您调用 时Image.Dispose,它会从内存中删除底层图像数据,因此该Image对象仍然存在,但由于它不再包含实际图像而无效。当您将PictureBox.Image属性设置为加载的Image对象时,PictureBox控件假定该Image对象将保持有效,以便以后在控件需要将自身重新绘制到屏幕上时,它可以重用它。例如:

Dim myImage As Image = Image.FromFile("file path")
PictureBox1.Image = myImage
PictureBox1.Refresh() ' This works
myImage.Dispose()
PictureBox1.Refresh() ' This throws an exception because it tries to access the disposed Image object

控件会在图片被dispose的PictureBox时候自动为你dispose,所以你不用担心自己dispose。唯一应该处理图像的时间是当您不将它们提供给任何其他对象以供以后使用时。

于 2012-12-17T13:09:31.047 回答
1

这是我的解决方案,即使问题很旧,也有人可以使用它。

Dim myImage As Image = Image.FromFile("file path")
PictureBox1.Image = myImage.clone // Use clone to give a new copy not a reference of image
PictureBox1.Refresh() // This works
myImage.Dispose()
PictureBox1.Refresh()  // This works also because we've a copy not reference 
于 2015-07-24T06:58:55.603 回答
0

PictureBox1.Image = myImage.Clone 这样您使用的是图像的副本,因此与原始图像发生什么无关紧要

于 2014-02-10T11:58:12.280 回答