2012-10-29 58 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內存之間的額外數據傳輸。

相關問題