gpt4 book ai didi

c# - 优化 : VB. 从文件中加载图像并即时调整大小;目标:快速

转载 作者:行者123 更新时间:2023-11-30 16:07:44 26 4
gpt4 key购买 nike

我将发布我的设计目标是什么,以及我是如何实现它的。我很想知道是否有任何方法我错过了标记或可以优化得更好。

[目标]

~ 将“快速”照片滚动添加到现有的 WinForms 应用程序。

~“类似于 Picasa”- 从一张图片翻到另一张图片,向前和向后,保持尽可能小的滞后,并尽可能保持应用程序的响应能力。

~ 其他与本题目标无关的(重命名;标记;导出;等)

~ 从磁盘加载后调整图像大小以减少内存使用并加快从图像到图像的“翻转”;调整为显示图像的控件的尺寸。

[约束]

~ 没有将应用程序转换为 WPF

~ .NET Framework 最高版本:4.0

[测试平台]

带固态硬盘的戴尔 M6800

注意:在以下所有情况下,大部分时间都花在了调整大小上,而不是从磁盘加载到内存上。此外,加载和调整大小操作是在对图像进行排队的线程中执行的。我什至懒得使用缩略图;尽管速度很快,但对于此应用程序来说质量太差了。当用户从一个图像“翻转”到下一个图像时,一个线程将目录中的下一个图像加载到队列中,并将一个图像放在队列的后面(如果从队列中向后翻转,则反之亦然);将图像放入队列或从队列中删除所涉及的操作可以忽略不计。

[测试结果:Image.FromFile]

加载和调整大小平均需要 54 毫秒,使用以下代码。HMI 响应很差。

m_Image = Image.FromFile(Me.FullName)
m_Image = ResizeImage(m_Image, ImageSize, True)

Public Function ResizeImage(ByVal image As Image, ByVal size As Size, Optional ByVal preserveAspectRatio As Boolean = True) As Image
Dim newWidth As Integer
Dim newHeight As Integer
If preserveAspectRatio Then
Dim originalWidth As Integer = image.Width
Dim originalHeight As Integer = image.Height
Dim percentWidth As Single = CSng(size.Width) / CSng(originalWidth)
Dim percentHeight As Single = CSng(size.Height) / CSng(originalHeight)
Dim percent As Single = If(percentHeight < percentWidth, percentHeight, percentWidth)
newWidth = CInt(originalWidth * percent)
newHeight = CInt(originalHeight * percent)
Else
newWidth = size.Width
newHeight = size.Height
End If
Dim newImage As Image = New Bitmap(newWidth, newHeight)
Using graphicsHandle As Graphics = Graphics.FromImage(newImage)
graphicsHandle.InterpolationMode = InterpolationMode.HighQualityBicubic
graphicsHandle.DrawImage(image, 0, 0, newWidth, newHeight)
End Using
Return newImage
End Function

[测试结果:ImageFast]

加载和调整大小平均需要 41 毫秒,使用以下代码。HMI 响应有所改善,但仍不理想。从磁盘加载比“传统”方法更好。

ImageFast 的来源:Fastest Image Resizing in .NET

m_Image = ImageFast.FromFile(Me.FullName)
m_Image = ResizeImage1(m_Image, ImageSize.Width, ImageSize.Height)

[测试结果:ImageProcessor]

加载和调整大小平均需要 122 毫秒,使用以下代码。HMI 响应很差。

ImageProcessor 来源:http://www.hanselman.com/blog/NuGetPackageOfTheWeekImageProcessorLightweightImageManipulationInC.aspx

Private Sub UseImageProcessor(ByVal fileName As String)
Dim photoBytes As Byte() = File.ReadAllBytes(fileName)
Dim quality As Integer = 70
Dim format As ImageFormat = ImageFormat.Jpeg
Dim size As New Size(150, 0)
Using inStream As New MemoryStream(photoBytes)
Using outStream As New MemoryStream()
imageFactory.Load(inStream).Resize(size) '// resizing takes about 127mS on Dell
m_Image = imageFactory.Image
m_Image = Image.FromStream(inStream)
End Using
End Using
End Using
End Sub

这些结果都不是很好。这是一台速度极快的 PC,我并没有被震撼到,尤其是当我将图像到图像的性能与上述 Picasa 的性能进行比较时。

所以,我尝试了一些不同的东西。我在我的 WinForms 应用程序中添加了 PresentationCore 版本 4.0.0.0 的引用,允许我使用:

Imports System.Windows.Media.Imaging

现在,我可以对加载和调整大小执行此操作:

m_Image = GetBitMap(GetImageBitMap(Me.FullName))

Public Function GetImageBitMap(ByVal fullName As String) As BitmapImage
Dim imageData = File.ReadAllBytes(fullName)
Dim resizedImage As New BitmapImage()
resizedImage.BeginInit() ' Needed only so we can call EndInit()
With resizedImage
.StreamSource = New MemoryStream(imageData)
.CreateOptions = BitmapCreateOptions.IgnoreColorProfile
.DecodePixelHeight = ImageSize.Height
.DecodePixelWidth = ImageSize.Width
End With
resizedImage.EndInit() ' This does the actual loading and resizing
Return resizedImage
End Function

对于这两个操作(加载和调整大小),这是一个四个字母的单词 &= 快速:平均 3 毫秒,总计。加载和调整大小。 chalice 。

这里明显的问题是上述函数的返回是一个BitmapImage 对象,在 WinForms 应用程序(据我所知)中不可用。因此,我必须使用以下代码将其转换为 BitMap:

Private Function GetBitMap(bitmapImage As BitmapImage) As Bitmap
Try
'// https://stackoverflow.com/questions/6484357/converting-bitmapimage-to-bitmap-and-vice-versa
Using outStream As New MemoryStream()
Dim enc As BitmapEncoder = New BmpBitmapEncoder()
enc.Frames.Add(BitmapFrame.Create(bitmapImage))
enc.Save(outStream)
Dim bitmap As New System.Drawing.Bitmap(outStream)
Return New Bitmap(bitmap)
End Using
Catch ex As Exception
Throw
End Try
End Function

在上述平台上,使用 WPF 加载和调整大小方法以及为我们的 WinForms 应用程序转换回 BitMap 的结果是大约 22 毫秒用于加载、调整大小和转换(从 BitmapImage 到 BitMap)。 HMI 响应很好,如果不是很好的话。这比仅使用提到的 WinForms 方法的经验要好。

不过,我愿意接受任何进一步的建议(因此这里有问题)。目前的结果是可以接受的。我希望我不必花费从 BitmapImage 到 BitMap 的转换开销,但它毕竟是一个 WinForms 应用程序。

最佳答案

看起来您真正想要做的是在您的 WinForms 应用程序中使用 BitmapImage。为此,您只需要使用 ElementHost托管 WPF Image 控件。

Image imageControl;
imageControl.Source = GetImageBitMap(filename);

关于c# - 优化 : VB. 从文件中加载图像并即时调整大小;目标:快速,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30388272/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com