J'ai besoin d'une implémentation rapide des algorithmes d'interpolation courants. J'ai compris que C# dans de tels algorithmes simples serait beaucoup plus lent que C++ donc je pense à écrire du code natif et à l'utiliser dans mon interface graphique C#. Tout d'abord, j'ai effectué quelques tests et peu d'opérations sur la matrice 1024x1024x3
ont pris 32ms en C# et 4ms en C++ et c'est ce dont j'ai le plus besoin. Cependant, l'interpolation n'est pas un bon mot car je n'en ai besoin que pour la réduction d'échelle. Mais la question est: Est-il plus rapide que C# méthodes Drawing2DVitesse des algorithmes d'interpolation, C# et C++ travaillant ensemble
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();
Certains d'entre eux dans l'exécution de la méthode 20ms et certains en 80. Est-il possible de le faire plus vite?
EDIT 1:
Tout d'abord j'utilise XNA dans cette application, mais il semble y avoir aucun moyen de sélectionner la méthode d'interpolation différente. Bien sûr, cela fonctionne très vite.
Idéal serait de mettre en œuvre ces méthodes sur une carte graphique.
EDIT 2:
Voici ma méthode tout:
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;
}
Le plus drôle est que HighQualityBicubic est beaucoup plus rapide que bicubique. (40ms vs 100ms)
Comment avez-vous calculé la durée de ces opérations? Les fonctions GDI en C# appellent simplement l'API non managée; il ne devrait pas y avoir de différence de vitesse (généralement appréciable) entre C# et C++ en faisant la même chose. –
@Adam Robinson 'Stopwatch' classe. Ne serait pas plus rapide d'écrire ces méthodes moi-même et d'appeler la méthode dlls non managée en donnant un pointeur vers l'image en mémoire retournant un autre pointeur? – Kaminari
Pas très probable, puisque le travail n'est pas fait en code managé. –