VintaSoft Imaging .NET SDK and Plug-ins Discussions

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

Board index < VintaSoft Imaging < VintaSoft Imaging .NET SDK and Plug-ins Discussions

We are migrating to new forums engine, no new registration or posting currently available. TIA for your patience.

Object is currently in use elsewhere



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


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


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/crashing 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


Page 1 from 1: 1