有没有办法使用GPU调整图像大小?

有没有办法使用可通过.NET应用程序使用的GPU(图形卡)来调整图像大小?

我正在寻找一种非常高效的方法来调整图像大小,并且听说GPU可以比CPU(GDI +使用C#)更快地完成它。 是否有已知的实现或示例代码使用GPU来调整我可以在.NET中使用的图像?

您是否考虑过使用XNA来调整图像大小? 在这里,您可以了解如何使用XNA将图像作为png / jpeg保存到MemoryStream中,稍后将其重用为Bitmap对象:

编辑:我将在这里发布一个例子(取自上面的链接)关于如何使用XNA。

public static Image Texture2Image(Texture2D texture) { Image img; using (MemoryStream MS = new MemoryStream()) { texture.SaveAsPng(MS, texture.Width, texture.Height); //Go To the beginning of the stream. MS.Seek(0, SeekOrigin.Begin); //Create the image based on the stream. img = Bitmap.FromStream(MS); } return img; } 

我今天也发现你可以使用OpenCV来使用GPU /多核CPU。 例如,您可以选择使用.NET包装器(如Emgu)并使用其Image类操作图片并返回.NET Bitmap类:

 public static Bitmap ResizeBitmap(Bitmap sourceBM, int width, int height) { // Initialize Emgu Image object Image img = new Image(sourceBM); // Resize using liniear interpolation img.Resize(width, height, INTER.CV_INTER_LINEAR); // Return .NET Bitmap object return img.ToBitmap(); } 

我写了一个快速尖峰来检查使用WPF的性能,虽然我不能肯定地说它使用GPU。

不过,见下文。 这会将图像缩放到原始大小的33.5(或其他)倍。

 public void Resize() { double scaleFactor = 33.5; var originalFileStream = System.IO.File.OpenRead(@"D:\SkyDrive\Pictures\Random\Misc\DoIt.jpg"); var originalBitmapDecoder = JpegBitmapDecoder.Create(originalFileStream, BitmapCreateOptions.None, BitmapCacheOption.OnLoad); BitmapFrame originalBitmapFrame = originalBitmapDecoder.Frames.First(); var originalPixelFormat = originalBitmapFrame.Format; TransformedBitmap transformedBitmap = new TransformedBitmap(originalBitmapFrame, new System.Windows.Media.ScaleTransform() { ScaleX = scaleFactor, ScaleY = scaleFactor }); int stride = ((transformedBitmap.PixelWidth * transformedBitmap.Format.BitsPerPixel) + 7) / 8; int pixelCount = (stride * (transformedBitmap.PixelHeight - 1)) + stride; byte[] buffer = new byte[pixelCount]; transformedBitmap.CopyPixels(buffer, stride, 0); WriteableBitmap transformedWriteableBitmap = new WriteableBitmap(transformedBitmap.PixelWidth, transformedBitmap.PixelHeight, transformedBitmap.DpiX, transformedBitmap.DpiY, transformedBitmap.Format, transformedBitmap.Palette); transformedWriteableBitmap.WritePixels(new Int32Rect(0, 0, transformedBitmap.PixelWidth, transformedBitmap.PixelHeight), buffer, stride, 0); BitmapFrame transformedFrame = BitmapFrame.Create(transformedWriteableBitmap); var jpegEncoder = new JpegBitmapEncoder(); jpegEncoder.Frames.Add(transformedFrame); using (var outputFileStream = System.IO.File.OpenWrite(@"C:\DATA\Scrap\WPF.jpg")) { jpegEncoder.Save(outputFileStream); } } 

我测试的图像是495 x 360.它在几秒钟内将其重新调整为超过16k x 12k,包括保存。

它在单核运行中每秒调整到1.5倍,大约165次。 在i7和GPU看似无所事事的情况下,CPU处于20%时我预计在multithreading时会增加5倍。

性能分析显示了wpfgfx_v0400.dll的热门路径, wpfgfx_v0400.dll是本机WPF图形库,并且接近DirectX(在Google中查找“milcore”)。

所以它可能会加速,我不知道。

卢克

是的,可以使用GPU来调整图像大小。 这可以使用DirectX Surfaces完成(例如在C#中使用SlimDx)。 您应创建一个曲面并将图像移动到该曲面,然后您可以仅使用GPU将此曲面拉伸到所需大小的另一个目标曲面,最后从目标曲面返回resize的图像。 在这些场景中,曲面的像素格式可以不同,GPU会自动处理它。 但是这里有些东西会影响这个操作的性能。 在GPU和CPU之间移动数据是一个耗时的过程。 您可以应用一些技术来根据您的情况提高性能,并避免CPU和GPU内存之间的额外数据传输。