.net中的多线程图像旋转

时间:2014-07-03 21:53:53

标签: .net multithreading image rotation

对不起有点沮丧,所以请求一些帮助。是的,之前已经提出了类似的问题,但我没有办法解决这个问题。

我在尝试读取一组图像并旋转它们时收到System.OutOfMemoryException。基本上,我有大量的图像。我想将每个图像读入内存,然后将图像旋转90度,180度和270度,并将每个旋转的图像保存为文件。

我没有损坏的图片。如果我单独阅读每个图像并一次旋转一个,一切正常。要旋转的所有图像都存在于同一目录中。该目录最多可容纳数百张图像。每个单独的图像本身并不那么大:平均大小<1。 1 mb存储为.PNG文件。所有图像都保存为PNG文件。

另外,我有一台运行的服务器。它是一台双CPU机器。每个CPU有8个超线程处理器。这使得32个处理器/线程。这台机器有64GB的内存。我想使用这些资源使用.net 4.5并行处理图像,我不能这样做,也无法弄清楚原因。我应该能够并行处理许多图像而不会耗尽内存...但不能!!!!

以下是旋转图像的例程:

Private Sub RotateImage90_180_270(ByVal filename As String)

    Dim file90 As String = filename.Replace(".png", "_rot90.png")
    Dim file180 As String = filename.Replace(".png", "_rot180.png")
    Dim file270 As String = filename.Replace(".png", "_rot270.png")

    Using fs As New FileStream(filename, FileMode.Open, FileAccess.Read)
        Using original As Image = Image.FromStream(fs)

            original.RotateFlip(RotateFlipType.Rotate90FlipNone)
            original.Save(file90, System.Drawing.Imaging.ImageFormat.Png)

            original.RotateFlip(RotateFlipType.Rotate90FlipNone)
            original.Save(file180, System.Drawing.Imaging.ImageFormat.Png)

            original.RotateFlip(RotateFlipType.Rotate90FlipNone)
            original.Save(file270, System.Drawing.Imaging.ImageFormat.Png)

        End Using
    End Using

End Sub

以下是有效的例程;如果顺序。获取文件夹中的文件列表。通过生成旋转文件的列表一次迭代1个文件。我的32个cpus中有31个闲置,我等了好几分钟等待这个过程结束。

Private Sub doRotations(ByVal folderPath As String)

    Dim files As String()


    files = System.IO.Directory.GetFiles(folderPath, "*.png")

    Me.EventLog1.WriteEntry("doStep4 PATH: " & folderPath & "  FILE COUNT: " & files.Length)

    For i = 0 To files.Length - 1

        Try
            RotateImage90_180_270(files(i))
        Catch ex As Exception
            Me.EventLog1.WriteEntry("doStep4 ERROR: " & ex.ToString & "File: " & files(i), EventLogEntryType.Error)
        End Try

    Next

End Sub

所以这就是我的代码开始失败的地方。并行for循环,开始一个线程来单独处理每个图像。

Private Sub doRotations_InParallel(ByVal folderPath As String)

    Dim files As String()

    files = System.IO.Directory.GetFiles(folderPath, "*.png")

    Me.EventLog1.WriteEntry("doStep4 PATH: " & folderPath & "  FILE COUNT: " & files.Length)

    Parallel.ForEach(files, Sub(currentFile)
                                RotateImage90_180_270(currentFile)
                            End Sub)
End Sub

我还尝试将目录中的整个文件列表分成一组文件并并行运行每个集合。例如,并行运行25,然后是25,依此类推。由于我有32个CPU并使用25个线程,所以我不应该有问题。但我这样做!!!

由于进行旋转的例程具有&#34;使用&#34;块,不应该自动释放文件句柄和分配的内存吗?并且由于每个都在自己的线程上.Foreach不应该将内存空间分开(为什么在一个线程上分配的内存会影响一个单独的线程?)。

无论如何,帮助将不胜感激!包括除使用System.Drawing.Imaging以外的选项,因为我认为内存泄漏来自那里。

哦,我刚刚尝试了下面的代码并且它不会起作用。试图在旋转/保存之前获取读入的图像副本并手动关闭/处理。仍然不起作用。某处显然存在内存泄漏;只是无法弄清楚在哪里。

请帮忙!

Private Sub RotateImage90_180_270(ByVal filename As String)

    Dim file90 As String = filename.Replace(".png", "_rot90.png")
    Dim file180 As String = filename.Replace(".png", "_rot180.png")
    Dim file270 As String = filename.Replace(".png", "_rot270.png")

    Dim originalCopy As Image

    Using fs As New FileStream(filename, FileMode.Open, FileAccess.Read)
        Using original As Image = Image.FromStream(fs)

            originalCopy = original.Clone
            'original.RotateFlip(RotateFlipType.Rotate90FlipNone)
            'original.Save(file90, System.Drawing.Imaging.ImageFormat.Png)

            'original.RotateFlip(RotateFlipType.Rotate90FlipNone)
            'original.Save(file180, System.Drawing.Imaging.ImageFormat.Png)

            'original.RotateFlip(RotateFlipType.Rotate90FlipNone)
            'original.Save(file270, System.Drawing.Imaging.ImageFormat.Png)

            original.Dispose()

        End Using

        fs.Close()
        fs.Dispose()

    End Using

    originalCopy.RotateFlip(RotateFlipType.Rotate90FlipNone)
    originalCopy.Save(file90, System.Drawing.Imaging.ImageFormat.Png)

    originalCopy.RotateFlip(RotateFlipType.Rotate90FlipNone)
    originalCopy.Save(file180, System.Drawing.Imaging.ImageFormat.Png)

    originalCopy.RotateFlip(RotateFlipType.Rotate90FlipNone)
    originalCopy.Save(file270, System.Drawing.Imaging.ImageFormat.Png)

    originalCopy.Dispose()

End Sub

0 个答案:

没有答案