Laden...

Bitmap maskieren

Erstellt von Xqgene vor 18 Jahren Letzter Beitrag vor 16 Jahren 3.944 Views
X
Xqgene Themenstarter:in
2.051 Beiträge seit 2004
vor 18 Jahren
Bitmap maskieren

Grafiker-Gurus gerufen! 🙂

Folgendes: ich habe ein Bild mit z.B. blauem Hintergrund. Jetzt will ich das Bitmap so "maskieren", dass alles, was nicht blau (nicht Hintergrund) ist, auf schwarz gesetzt wird.

hat jemand eine klevere Idee, als Pixel für Pixel, die Farbe zu ändern?

210 Beiträge seit 2005
vor 18 Jahren

Wenn b dein Bitmap ist:


using System.Drawing;
//...
Color c = b.GetPixel(50, 50);
if (c != Color.Blue)
b.SetPixel(50, 50, Color.Black);

Musst halt nur über sämtliche Pixel iterieren.

Blog

Portable WebDAV Library

Windows Server Advanced Power Management
Erweitertes Energie-Management unter Windows

Q
992 Beiträge seit 2005
vor 18 Jahren

Gibt es keine Eigenschaft namens Transparent Color oder so, die man dann verändern kann?

X
Xqgene Themenstarter:in
2.051 Beiträge seit 2004
vor 18 Jahren

ich habe jetzt in einer schleife gemacht und zwar so:


        ...
        private Bitmap CreateMask(Image originalImage)
        {
            int mcol = Color.Magenta.ToArgb();

            Bitmap bmp = new Bitmap(originalImage);
            Rectangle rect = new Rectangle(new Point(0, 0), bmp.Size);
            BitmapData bmpdata = bmp.LockBits(rect, ImageLockMode.ReadWrite, bmp.PixelFormat);
            unsafe
            {
                uint* ptr = (uint*)bmpdata.Scan0;
                for (int i = 0, j = bmp.Width * bmp.Height; i < j; i++)
                {
                    if (mcol != (int)*ptr)
                        *ptr = 0;
                    ptr++;
                }
            }
            bmp.UnlockBits(bmpdata);
            return bmp;
        }

warum unsafe? damit es schneller läuft.

210 Beiträge seit 2005
vor 18 Jahren

Trotzdem etwas umständlich, oder?

Läuft das von der Performance her wirklich so viel besser?

Blog

Portable WebDAV Library

Windows Server Advanced Power Management
Erweitertes Energie-Management unter Windows

M
115 Beiträge seit 2003
vor 18 Jahren

Gernot Melichar

X
Xqgene Themenstarter:in
2.051 Beiträge seit 2004
vor 18 Jahren

Original von exec
Läuft das von der Performance her wirklich so viel besser?

jeder kann sich selbst überzeugen

diese test anvendung konvertiert ein Farb-Bild in Graustuffen

.NET 2.0 Beta 2

I
1.739 Beiträge seit 2005
vor 18 Jahren

umständlich. - ja, leider gibt GDI+ nicht mehr her.

Gegenüber getPixel ist die angegebene Methode ungleich schneller(getpixel ist so ziemlich das langsamste was möglich ist). Optimierungsmöglichkeiten in C# sind nur bei Kenntnis der Farbtiefe der Bitmap möglich. Ansonsten(für weitere Optimierungen) bleibt noch der Weg über C++ & GDI(bei sehr guten Kenntnissen, lässt sich die C#- Methode noch etwas optimieren ca 10-15% / ziemlicher Aufwand).
Damit sich die "Umständlichkeit" in Grenzen hält, lohnt es sich die Methode in einer Helperklasse zu kapseln(Wiederverwendbarkeit)

P
939 Beiträge seit 2003
vor 18 Jahren

Ich hätte eine Idee wie man das Problem mit dem System.Drawing.Imaging-Namespace lösen kann. Ist nicht ganz ausgegoren, wahrscheinlich geht es anders noch besser.

Drei Arbeitsschritte, man erstellt eine ColorMatrix, die alle Farben, ausser den Blau-Kanal auf 0 runtersetzt. Dann ändert man die Hintergrundfarbe von blau in grün und setzt auch den Blau-Kanal auf 0 runter. Übrig bleibt eine schwarze Sillouette mit grünem Hintergrund.

Msdn: GDI+ Recoloring

Die ColorMatrix ist ja eine 5x5-Matrix, die Farbtransformationen im ARGB(W)-Raum ausführt. Gibt es vielleicht eine Matrix, die das gleiche Ergebnis in einem Schritt erreicht?

Gruss
Pulpapex

X
Xqgene Themenstarter:in
2.051 Beiträge seit 2004
vor 18 Jahren

hm..

ich habe jetzt nach Pulpapex-"Anleitung" folgendes zusammen gestellt:


		float[][] cl = new float[][]{
									new float[]{255, 0, 0, 0, 1},
									new float[]{255, 0, 0, 255, 1},
									new float[]{255, 0, 255, 0, 1},
									new float[]{255, 0, 0, 0, 1},
									new float[]{255, 0, 0, 0, 1}};
			ColorMatrix cmx = new ColorMatrix(cl);

			
			ImageAttributes iat = new ImageAttributes();
			iat.SetColorMatrix(cmx);

			Bitmap bmp = new Bitmap(16, 16);
			Graphics g = Graphics.FromImage(bmp);
			g.DrawImage(pictureBox1.Image, new Rectangle(0, 0, 16, 16), 0, 0, 16, 16, GraphicsUnit.Pixel, iat);
			
			ColorMap[] cmp = new ColorMap[2]{new ColorMap(),new ColorMap()};
			cmp[0].OldColor = Color.Magenta;
			cmp[0].NewColor = Color.Black;
			cmp[1].OldColor = Color.FromArgb(0, 0, 0, 0);
			cmp[1].NewColor = Color.Magenta;
			
			ia = new ImageAttributes();
			ia.SetRemapTable(cmp);

			g.DrawImage(bmp, new Rectangle(0, 0, 16, 16), 0, 0, 16, 16, GraphicsUnit.Pixel, iat);

			pictureBox1.Image = bmp;

als Hintergrundfarbe wird Magenta verwendet.

das finde ich noch umständlicher als mit unsafe. ob diese methode schneller ist als mit pointer? hat jemand lust das zu testen?

T
13 Beiträge seit 2007
vor 16 Jahren
Bitmap-Hintergrund ist immer blau...

Ich zeichne ein Grafikobjekt auf eine Bitmap, doch leider ist der Hintergrund des Bitmaps standardmäßig blau - komischer Weise. Habe schon (meine Bitmap = bmp) bmp.MakeTransparent() und

img = Image.FromHbitmap(bmp.GetHbitmap(Color.White));

ausprobiert. Wenn ich bei GetHbitmap(Color.Green) einstelle wird der Hintergrund sogar Schwarz. Was kann ich tun damit der Hintergrund wirklich Weiss ist?

O
778 Beiträge seit 2007
vor 16 Jahren

glücklicherweise gibts ja aber im Unterforum Komponenten noch die Klasse RoBitmap, deren Methoden Get-/SetPixel die von Bitmap von Haus aus um Faktor 800 (Angaben des Autors) schlagen, wodurch das Iterieren doch wieder interessant wird...

1.820 Beiträge seit 2005
vor 16 Jahren

Hallo!

Ich habe die RoBitmap-Klasse selbst mal ausprobiert, sie ist wirklich um einiges schneller.

Nobody is perfect. I'm sad, i'm not nobody 🙁

T
13 Beiträge seit 2007
vor 16 Jahren

So habe die Antwort woanders gefunden, die Lösung für mein obiges Problem lautet Graphics.Clear()...

Indirekt Danke an Herbivore, es stand in einem anderen Thread...