Parallelisieren von GDI+ Bild Vergrößern .net

Ich habe versucht zu parallelisieren Sie die Größe der JPEG-Dateien verwenden .Net. Alle meine versuche sind gescheitert, weil die Grafik.DrawImage-func scheint zu sperren, wenn Sie aktiv sind. Versuchen Sie die folgenden Schnitt:

Sub Main()
    Dim files As String() = IO.Directory.GetFiles("D:\TEMP")
    Dim imgs(25) As Image
    For i As Integer = 0 To 25
      imgs(i) = Image.FromFile(files(i))
    Next

    Console.WriteLine("Ready to proceed ")
    Console.ReadLine()

    pRuns = 1
    For i As Integer = 0 To 25
      Threading.Interlocked.Increment(pRuns)
      Threading.ThreadPool.QueueUserWorkItem(New Threading.WaitCallback(AddressOf LongTerm), imgs(i))
    Next
    Threading.Interlocked.Decrement(pRuns)

    pSema.WaitOne()
    Console.WriteLine("Fin")
    Console.ReadLine()
  End Sub

  Sub LongTerm(ByVal state As Object)
    Dim newImageHeight As Integer
    Dim oldImage As Image = CType(state, Image)
    Dim newImage As Image
    Dim graph As Graphics
    Dim rect As Rectangle
    Dim stream As New IO.MemoryStream

    Try
      newImageHeight = Convert.ToInt32(850 * oldImage.Height / oldImage.Width)
      newImage = New Bitmap(850, newImageHeight, oldImage.PixelFormat)
      graph = Graphics.FromImage(newImage)
      rect = New Rectangle(0, 0, 850, newImageHeight)

      With graph
        .CompositingQuality = Drawing2D.CompositingQuality.HighQuality
        .SmoothingMode = Drawing2D.SmoothingMode.HighQuality
        .InterpolationMode = Drawing2D.InterpolationMode.HighQualityBicubic
      End With

      'Save image to memory stream
      graph.DrawImage(oldImage, rect)
      newImage.Save(stream, Imaging.ImageFormat.Jpeg)
    Catch ex As Exception

    Finally
      If graph IsNot Nothing Then
        graph.Dispose()
      End If
      If newImage IsNot Nothing Then
        newImage.Dispose()
      End If
      oldImage.Dispose()
      stream.Dispose()

      Console.WriteLine("JobDone {0} {1}", pRuns, Threading.Thread.CurrentThread.ManagedThreadId)
      Threading.Interlocked.Decrement(pRuns)
      If pRuns = 0 Then
        pSema.Set()
      End If
    End Try

  End Sub

Alle threads warten auf der graph.DrawImage(). Gibt es einen Weg, um die Geschwindigkeit code Leistung mit anderen Funktionen? Ist es unmöglich, die Verwendung von Grafiken.Zeichnen mit mehreren threads? In der realen Anwendung mehrere Bilder sollten verkleinert werden gleichzeitig (auf einem quad-core pc), nicht immer die gleichen. Der gepostete code ist nur für Testzwecke...

Vielen Dank im Voraus

Edit: Aktualisiert den code nach Kommentaren

  • Wenn Sie fügen Sie die Deklarationen für pSema und pRuns, wird es einfacher sein, Antworten auf cut-and-paste und testen Sie das proggy.
  • Ich habe festgestellt, dass ein großer Teil der Zeit wird damit verbracht, in der IO, nicht in der DrawImage-Aufruf. Wenn Sie das Bild Konstruktor einen stream, vermeiden Sie einige locking-Probleme, die in den decoder. (und es ist etwas schneller). Ich lief einige benchmarks, die beim Bau der imageresizing.net Bibliothek.
  • Auch, WIC auf WS2008 R2 und Win7 ist eine gute alternative, und imageresizing.net unterstützt, dass die code-Pfad als eine Reihe von Plug-ins. WPF ist immer noch eine schlechte Idee, auf dem server, zu viele ungepatchte Speicher-Lecks.
InformationsquelleAutor PTa | 2010-09-15
Schreibe einen Kommentar