4

ユーザーが最初にビットマップにスキャンできるフォームがあります。スキャンが完了し、ビットマップが読み込まれると、4つのテキストボックスが有効になります。各テキストボックスの横に、「画像から切り取り」というボタンがあります。ユーザーがボタンをクリックすると、ビットマップをクリックしてドラッグし、MODIを使用して選択したテキストを取得できます。

これは、1つの厄介なバグを除いて、完璧に機能します。[画像から切り取り]ボタンをクリックして正方形をドラッグすると、テキストボックスに情報がうまく表示されます。次に、次のテキストボックスをクリックすると非常にうまくいきますが、タブキーを使用してフィールドを離れると、「パラメータが無効です」というメッセージがArgumentException表示され、コード内のどこにヘルプが表示されません。クラッシュが発生します。フォーム内で問題なくタブ移動できますが、ビットマップをスキャンすると、Tabキーを使用すると10回のうち9回のようにクラッシュします。

これを使用して(デバッグのためだけに)タブキーを上書きしようとしました:

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(Message&m)で
  • System.Windows.Forms.Control.WndProc(Message&m)で
  • System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message&m)で
  • System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message&m)で
  • System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd、Int32 msg、IntPtr wparam、IntPtr lparam)で
  • System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG&msg)で
  • System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID、Int32 reason、Int32 pvLoopData)で
  • System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason、ApplicationContext context)で
  • System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32理由、ApplicationContextコンテキスト)で
  • Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.OnRun()で
  • Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.DoApplicationModel()で
  • Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.Run(String [] commandLine)で
  • 17d14f5c-a337-4978-8281-53493378c1071.vb:line 81のORC_Testing.My.MyApplication.Main(String [] Args)で
  • System.AppDomain._nExecuteAssembly(RuntimeAssemblyアセンブリ、String [] args)で
  • System.AppDomain.ExecuteAssembly(String assemblyFile、Evidence assemblySecurity、String [] args)で
  • Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()で
  • System.Threading.ThreadHelper.ThreadStart_Context(オブジェクト状態)で
  • System.Threading.ExecutionContext.Run(ExecutionContext executeContext、ContextCallbackコールバック、オブジェクト状態、ブール値ignoreSyncCtx)で
  • System.Threading.ExecutionContext.Run(ExecutionContextexecutionContext、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、オブジェクトの1つでメソッドを呼び出している可能性があります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

コントロールはPictureBox、画像が破棄されるときに自動的に破棄されるため、自分で画像を破棄する必要はありません。画像を破棄する必要があるのは、後で使用するために他のオブジェクトに画像を渡さない場合のみです。

于 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 に答える