Kaminari
Kaminari

Reputation: 1487

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 bmp = 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)

Upvotes: 3

Views: 2088

Answers (2)

Foxfire
Foxfire

Reputation: 5755

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?

Upvotes: 1

Codesleuth
Codesleuth

Reputation: 10541

Have you tried this with the GetThumbnailImage method?

To further extend Adam Robinson's comment: I hope you timed this using the Stopwatch class?

Upvotes: 0

Related Questions