Object is currently in use elsewhere

Questions, comments and suggestions concerning VintaSoft Imaging .NET SDK.

Moderator: Alex

Post Reply
rsl922
Posts: 2
Joined: Tue Dec 21, 2010 11:59 pm

Object is currently in use elsewhere

Post by rsl922 »

This unhandled exception in the Imaging SDK code is a little frustrating, as it comes up randomly, and crashes my application. Like many people, I have a Thumbnail Viewer and an Image Viewer on my Winforms form. All of my images are in TIFF format. A context menu allows the user to "cleanup" the page (deskew, despeckle, sharpen). This works okay much of the time, but occasionally the multi-threaded SDK code finds that an image is locked (don't know why, it just does) and because an exception happens on a secondary thread, it kills the whole app. I don't care if the requested command fails, I just need it to not crash my program! Is there anything I'm doing to cause this?

BTW - sharpen and despeck work fine, deskew doesn't seem to do much.

Here is all my Vinta-related code (VB.Net). I'm not bothering to do the async stuff, just working on the current image in place.

cmi = context menu item, this is for Fix / Cleanup

''' <summary>
''' Cleans up the currently focused image.
''' </summary>
''' <param name="sender"></param>
''' <param name="e"></param>
''' <remarks></remarks>
Private Sub cmiFix_Cleanup_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmiFix_Cleanup.Click
cleanup(TiffViewer.FocusedImage)
End Sub

''' <summary>
''' Fix Rotate the currently focused image.
''' </summary>
''' <param name="sender"></param>
''' <param name="e"></param>
''' <remarks></remarks>
Private Sub cmiFix_Rotate_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmiFix_Rotate.Click
rotate(TiffViewer.FocusedImage)
End Sub

''' <summary>
''' Cleans up the currently focused image.
''' </summary>
''' <remarks></remarks>
Private Sub cleanup(ByVal img As VintasoftImage)
despeckle(img)
deskew(img)
sharpen(img)
End Sub

''' <summary>
''' Change the format to RGB 24, necessary for sharpening.
''' </summary>
''' <param name="img"></param>
''' <remarks></remarks>
Private Sub convertToRGB24(ByVal img As VintasoftImage)
Try
Dim cmd As New ChangePixelFormatCommand(PixelFormat.Bgr24)

cmd.ExecuteInPlace(img)
Catch
End Try
End Sub

''' <summary>
''' Deskews the image.
''' </summary>
''' <param name="img"></param>
''' <remarks></remarks>
Private Sub deskew(ByVal img As VintasoftImage)
Try
Dim cmd As New Document.DeskewCommand()

cmd.ExecuteInPlace(img)
Catch
End Try
End Sub

''' <summary>
''' Remove random specks from the image.
''' </summary>
''' <param name="img"></param>
''' <remarks></remarks>
Private Sub despeckle(ByVal img As VintasoftImage)
Try
Dim level1 As Integer = 8
Dim level2 As Integer = 25
Dim radius As Integer = 30
Dim level3 As Integer = 400
' increase standard values for very big and big images
If (img.Width * img.Height) > 100000000 Then
' 100 MPixels
level1 *= 4
level2 *= 4
radius *= 4
level3 *= 4
ElseIf (img.Width * img.Height) > 60000000 Then
' 60 MPixels
level1 *= 2
level2 *= 2
radius *= 2
level3 *= 2
End If

Dim cmd As New Document.DespeckleCommand(level1, level2, radius, level3)

cmd.ExecuteInPlace(img)
Catch
End Try
End Sub

' Checks that focused image is present and correct.
Private Function isValidImage() As Boolean
Try
isValidImage = Not (TiffViewer.FocusedIndex = -1 OrElse TiffViewer.Images.Count = 0 OrElse TiffViewer.FocusedImage.IsBad)
Catch
isValidImage = False
End Try
End Function

''' <summary>
''' Rotates the image 180 degrees.
''' </summary>
''' <param name="img"></param>
''' <remarks></remarks>
Private Sub rotate(ByVal img As VintasoftImage)
Try
Dim cmd As New Transforms.RotateCommand(180)

cmd.ExecuteInPlace(img)
Catch
End Try
End Sub

''' <summary>
''' Sharpens the image.
''' </summary>
''' <param name="img"></param>
''' <remarks></remarks>
Private Sub sharpen(ByVal img As VintasoftImage)
Try
Select Case img.PixelFormat
Case PixelFormat.Bgr24, PixelFormat.Bgr32, PixelFormat.Bgra32, PixelFormat.Bgr48, PixelFormat.Bgra64
' format is already okay

Case Else
convertToRGB24(img)
End Select

Dim cmd As New Filters.SharpenCommand()

cmd.ExecuteInPlace(img)
Catch
End Try
End Sub
Alex
Site Admin
Posts: 2303
Joined: Thu Jul 10, 2008 2:21 pm

Re: Object is currently in use elsewhere

Post by Alex »

Hello,

Please send a demo project to support@vintasoft.com - we need to reproduce the problem.

Best regards, Alexander
rsl922
Posts: 2
Joined: Tue Dec 21, 2010 11:59 pm

Re: Object is currently in use elsewhere

Post by rsl922 »

I learned that cleaning up images while loading (TiffViewerImages_ImageCollectionChanged) can be too slow, as the process of calling despeckle, deskew, and sharpen can cost 4-5 seconds, which adds up fast with enough images!

So, I did this instead on ThumbnailViewer_Click. This way, the image would be cleaned up as I was displaying it. However, if the user was to click on an thumbnail, and then another within a short time (a couple of seconds), it could hang the library and lock my viewer.

Thanks to Alex, there is an easy solution. ThumbnailViewer_ThumbnailPainting is an event that is not under user control, so that eliminated the timing/* issue. Since this is called repeatedly, it is critical that the image's tag property hold a flag to indicate that the desired operation has already been done, so you don't end up doing it over and over again.

My final VB.Net code is:

''' <summary>
''' Handles the painting of a thumbnail image.
''' </summary>
''' <param name="sender"></param>
''' <param name="e"></param>
''' <remarks></remarks>
Private Sub TiffThumbnailViewer_ThumbnailPainting(ByVal sender As System.Object, ByVal e As Vintasoft.Imaging.ThumbnailPaintingEventArgs) Handles TiffThumbnailViewer.ThumbnailPainting
e.Handled = False

Try
' clean up the image
fixImage(TiffViewer.Images(e.Index))

Dim mybrush As Brush = Brushes.Firebrick
Dim mystyle As FontStyle
Dim mytext As String
If TiffThumbnailViewer.SelectedIndices.Contains(e.Index) Then
mystyle = FontStyle.Bold
mytext = String.Format(">> PAGE {0} <<", e.Index + 1)
Else
mystyle = FontStyle.Regular
mytext = String.Format("PAGE {0}", e.Index + 1)
End If
' must be set after mystyle
Dim myfont As New Font("Tahoma", Convert.ToSingle(8 * TiffThumbnailViewer.ThumbnailSize.Width / 128), mystyle)
' must be set after setting mytext and myfont
Dim textSize As SizeF = e.Graphics.MeasureString(mytext, myfont)
' must be set after textSize
Dim rectClipping As New RectangleF(0, 0, e.Thumbnail.Width, e.Thumbnail.Height + textSize.Height)
Dim rectImage As New RectangleF(0, 0, e.Thumbnail.Width, e.Thumbnail.Height)

e.Graphics.SetClip(rectClipping)
' draw the thumbnail
e.Graphics.DrawImage(e.Thumbnail, rectImage)
' draw the page number centered under the thumbnail
e.Graphics.DrawString(mytext, myfont, mybrush, e.Graphics.VisibleClipBounds.Width / 2 - textSize.Width / 2, e.Thumbnail.Height)

e.Handled = True
Catch
End Try
End Sub

''' <summary>
''' Cleans up the given image.
''' </summary>
''' <param name="img"></param>
''' <remarks>Doesn't bother if all operations have already been done.</remarks>
Private Sub fixImage(ByVal img As VintasoftImage)
Try
If (CType(img.Tag, Integer) < ALL_OPS) Then
despeckle(img)
deskew(img)
sharpen(img)
End If
Catch
End Try
End Sub

''' <summary>
''' Deskews the image.
''' </summary>
''' <param name="img"></param>
''' <remarks></remarks>
Private Sub deskew(ByVal img As VintasoftImage)
Try
Dim t As Integer = CType(img.Tag, Integer)

If Convert.ToBoolean(t And OP_DESKEW) Then
' did it already
Else
Dim cmd As New Document.DeskewCommand()
cmd.ExecuteInPlace(img)

img.Tag = t Or OP_DESKEW
End If
Catch
End Try
End Sub

' image cleanup operations
Private ReadOnly OP_DESPECK As Integer = 1
Private ReadOnly OP_DESKEW As Integer = 2
Private ReadOnly OP_SHARPEN As Integer = 4
Private ReadOnly ALL_OPS As Integer = OP_DESPECK + OP_DESPECK + OP_SHARPEN
Post Reply