Is there a way to resize an image using a GPU?

Is there a way to resize an image using a graphics adapter (graphics card) that can be used in a .NET application?

I am looking for an extremely efficient way to resize images and have heard that the GPU can do this much faster than the processor (GDI + using C #). Are there any known implementations or sample code using the GPU for resizing images that I could use in .NET?

+4
source share
3 answers

Have you considered using XNA to resize your images? Here you can learn how to use XNA to save the image as png / jpeg in a MemoryStream, and then reuse its Bitmap object:

EDIT: here I will give an example (taken from the link above) on how you can use 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; } 

I also found out today that you can use OpenCV to use GPU / multi-core processors. For example, you can use a .NET wrapper such as Emgu and use your Image class to manipulate your image and return a .NET Bitmap class:

 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(); } 
+5
source

I wrote a quick splash to test performance using WPF, although I can’t say for sure that it uses a GPU.

However, see below. This scales the image to 33.5 (or something else) from its original size.

 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); } } 

The image I tested was 495 x 360. It resized to 16k x 12k in a couple of seconds, including saving.

It resizes to 1.5x about 165 times per second in single-core mode. On i7 and the GPU, it would seem to do nothing, the processor is 20% I expect to get 5 times more with multithreading.

Performance profiling shows a hot way to wpfgfx_v0400.dll , which is the native WPF graphics library and is close to DirectX (look-up 'milcore' on Google).

So it can accelerate, I don’t know.

Luke

0
source

Yes, you can use the GPU to resize your images. This can be done using DirectX Surfaces (e.g. using SlimDx in C #). You must create a surface and transfer the image onto it, and then you can stretch this surface to another target surface of the desired size using only the GPU, and finally return the image with the modified surface from the target surface. In this case, the pixel format on the surface may be different, and the GPU automatically processes it. But there are things that can affect the performance of this operation. Moving data between the GPU and the processor takes a lot of time. You can use some methods to improve performance depending on your situation and avoid additional data transfer between the CPU and GPU memory.

0
source

Source: https://habr.com/ru/post/1442866/


All Articles