Effektive Bildverarbeitung mit .NET?



  • Hallo,

    die Operationen GetPixel(x,y) und SetPixel(x,y) tun zwar ihren Dienst, sind aber alles andere als performant.
    Da es bei meinem Programm auch auf die Geschwindigkeit ankommt (bei welchem wohl nicht?) suche ich nach Alternativen.

    Ich bin nach ausgiebigem googeln auf eine Lösung gestoßen, bei der die Pixeloperationen über BitmapData gehen.
    Leider war das Programm in C# geschrieben, wovon ich nichts verstehe.

    Ich hoffe hier kann mir jemand zeigen, wie ich diese Variante in C++ verwende. 🙂



  • Hallo nochmal,

    gibt es niemanden der mir weiterhelfen kann? Oder hat jemand zumindest einen Link der mir weiterhelfen könnte?
    Oder ist meine Frage einfach zu banal? 😕



  • Siehe hier. Da hat einer auch ne fertige DLL gebastelt dass du dich auch net mit C# rumschlagen musst 🙂



  • danke 🙂



  • So geht es am besten:

    using namespace System::Runtime::InteropServices;
    using namespace System::Drawing;
    using namespace System::Drawing::Imaging;
    
    // Ein Bild laden
    	Bitmap ^MyBitmap = gcnew Bitmap("Bild.jpg");
    
    	// BitmapData-Struktur erstellen
    	BitmapData MyBitmapData;
    
    	// Array für Bilddaten erstellen
    	// 4 Byte pro Pixel für ARGB
    	// 3 Byte pro Pixel für RGB
    	array<unsigned char, 3> ^Data = gcnew array<unsigned char, 3>(MyBitmap->Height, MyBitmap->Width, 4);
    
    	// Managed Handle auf die Daten allokieren
    	GCHandle MyHandle = GCHandle::Alloc(Data, GCHandleType::Pinned);
    
    	// Datenadresse in der Struktur setzten
    	MyBitmapData.Scan0 = MyHandle.AddrOfPinnedObject();
    
    	// Offset für eine Bildzeile
    	// sollte laut MSDN ein vielfaches von 4 sein, geht aber auch wenn es nicht so ist für RGB zum beispiel
    	MyBitmapData.Stride = MyBitmap->Width * 4;
    
    	// Bitmap sperren
    	// Bei ImageLockMode::ReadOnly und ImageLockMode::ReadWrite werden die Daten aus der Bitmap in unsere Datenarray geschrieben
    
    	MyBitmap->LockBits(Rectangle(0, 0, MyBitmap->Width, MyBitmap->Height), ImageLockMode::UserInputBuffer | ImageLockMode::ReadWrite, PixelFormat::Format32bppArgb, %MyBitmapData);
    
    	// Daten manipulieren
    	// Data[Y, X, 0] = Alpha;
    	// Data[Y, X, 0] = Red;
    	// Data[Y, X, 0] = Green;
    	// Data[Y, X, 0] = Blue;
    
    	// Bitmap entsperren
    	// Bei ImageLockMode::WriteOnly und ImageLockMode::ReadWrite werden die Daten aus unserer Datenarray in die Bitmap geschrieben
    
    	MyBitmap->UnlockBits(%MyBitmapData);
    
    	// Handle freigeben
    
    	MyHandle.Free();
    


  • Hallo,

    dankeschön! Ich habe jetzt mal versucht, das ganze bei mir einzubauen.
    Klappt soweit auch ganz gut, nur ist das Data Array leer. Hab ich da etwas falsch gemacht, oder muss ich irgendwie noch explizit die Bildaten reinspeichern?



  • Ich hab es jetzt grad nochmal getestet und es funktioniert eigentlich. Ab dem Befehl LockBits stehen die Daten in der Array und wenn man die Bitmap ändern will muss mann die Daten der Array vor UnlockBits ändern.
    Trotzdem war ein Fehler drin, die Daten stehen nämlich anders in der Array und zwar:

    Data[Y, X, 3] = Alpha;
    Data[Y, X, 2] = Red;
    Data[Y, X, 1] = Green;
    Data[Y, X, 0] = Blue;
    


  • Funktioniert. 🙂
    1000 Dank!



  • Bitte, gerne!

    Ich wär froh gewesen wenn mir das jemand gesagt hätte.


Anmelden zum Antworten