Speed of interpolation algorithms, C# and C++ working together
I need fast implementation of popular interpolation algorithms. I figured it out that C# in such simple algorithms will be much slower than C++ so i think of writing some native code and using it in my C# GUI.
First of all i run some tests and few operations on 1024x1024x3
matrix took 32ms in C# and 4ms in C++ and that's what i basicly need.
Interpolation however is not a good word because i need them only for downscaling. But the question is: Will it be faster than C# methods in Drawing2D
Image outputImage = new Bitmap(destWidth, destHeight, PixelFormat.Format24bppRgb);
Graphics grPhoto = Graphics.FromImage(outputImage);
grPhoto.InterpolationMode = InterpolationMode.*; //all of them
grPhoto.DrawImage(bmp, new Rectangle(0, 0, destWidth, destHeight),
Rectangle(0, 0, sourceWidth, sourceHeight), GraphicsUnit.Pixel);
grPhoto.Dispose();
Some of these method run in 20ms and some in 80. Is there a way to do it faster?
EDIT 1:
First of all i'm using XNA in this application but there seems to be no way to select different interpolation method. Of course it's working very fast.
Ideal way would be to implement those methods on graphic card.
EDIT 2:
Here is my whole method:
private unsafe Texture2D Scale(GraphicsDevice gd, Texture2D texture, float scale)
{
int sourceWidth = texture.Width;
int sourceHeight = texture.Height;
int destWidth = (int)(sourceWidth * scale);
int destHeight = (int)(sourceHeight * scale);
StopwatchEx sw = new StopwatchEx();
sw.IntervalStart();
//convert texture into bitmap
byte[] textureData = new byte[4 * sourceWidth * sourceHeight];
texture.GetData<byte>(textureData);
System.Drawing.Bitmap b开发者_如何学Pythonmp = new System.Drawing.Bitmap(sourceWidth, sourceHeight, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
System.Drawing.Imaging.BitmapData bmpData = bmp.LockBits(new System.Drawing.Rectangle(0, 0, sourceWidth, sourceHeight), System.Drawing.Imaging.ImageLockMode.WriteOnly,
System.Drawing.Imaging.PixelFormat.Format32bppArgb);
IntPtr safePtr = bmpData.Scan0;
System.Runtime.InteropServices.Marshal.Copy(textureData, 0, safePtr, textureData.Length);
bmp.UnlockBits(bmpData);
//output bitmap
System.Drawing.Image outputImage = new System.Drawing.Bitmap(destWidth, destHeight, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
System.Drawing.Graphics grPhoto = System.Drawing.Graphics.FromImage(outputImage);
grPhoto.InterpolationMode = (System.Drawing.Drawing2D.InterpolationMode)(interpolationMode);
grPhoto.SmoothingMode = (System.Drawing.Drawing2D.SmoothingMode)smoothingMode;
grPhoto.PixelOffsetMode = (System.Drawing.Drawing2D.PixelOffsetMode)pixelOffsetMode;
grPhoto.DrawImage((System.Drawing.Image)bmp, new System.Drawing.Rectangle(0, 0, destWidth, destHeight),
new System.Drawing.Rectangle(0, 0, sourceWidth, sourceHeight), System.Drawing.GraphicsUnit.Pixel);
grPhoto.Dispose();
textureData = new byte[4 * sourceWidth * sourceHeight];
MemoryStream ms = new MemoryStream();
((System.Drawing.Bitmap)outputImage).Save(ms, System.Drawing.Imaging.ImageFormat.Bmp);
ms.Seek(0, SeekOrigin.Begin);
Texture2D result = Texture2D.FromFile(gd, ms);
ms.Dispose();
sw.IntervalStop();
sw.AppendResults("MEGS.txt");
return result;
}
Funny thing is that HighQualityBicubic is much faster than Bicubic. (40ms vs 100ms)
How did you implement your matrix in C#?
In your case a lot of speed could be lost due to .Net having to do bounds checks in a matrix array by default. In that case you could make your code much faster using unsafe C# (and thus removing any bounds checks).
But if it already works fast enough with the external methods why not use them?
Have you tried this with the GetThumbnailImage
method?
To further extend Adam Robinson's comment: I hope you timed this using the Stopwatch class?
精彩评论