2012-10-29 54 views
4

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

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

+0

*任何*都比GDI +快。也许这可以帮助:http://opencv.org/可以用.net中的DLLImport导入。 – K3N

+0

这是否使用GPU和更优化的CPU代码? –

+0

根据它使用GPU的文档,但只能从Nvidia(CUDA)获得。否则CPU。 http://opencv.willowgarage.com/wiki/OpenCV_GPU – K3N

回答

5

您是否想过使用XNA来调整图像大小? Here you can find out如何使用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和,并利用其图像类与图片处理,并返回一个.NET Bitmap类:

public static Bitmap ResizeBitmap(Bitmap sourceBM, int width, int height) 
{ 
    // Initialize Emgu Image object 
    Image<Bgr, Byte> img = new Image<Bgr, Byte>(sourceBM); 

    // Resize using liniear interpolation 
    img.Resize(width, height, INTER.CV_INTER_LINEAR); 

    // Return .NET Bitmap object 
    return img.ToBitmap(); 
} 
+2

,以避免可能有用的链接腐烂。 – Woot4Moo

0

我写了一个快速扣球使用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在几秒钟,其中包括保存退出。

它在单核运行中调整到每秒165次约1.5倍。在i7和GPU看似无所作为的情况下,20%的CPU在多线程时期望获得5倍的CPU。

性能分析显示了一个热门路径wpfgfx_v0400.dll,它是本地WPF图形库,并且接近DirectX(在Google中查找'milcore')。

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

Luke

0

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

相关问题