Farbe in Bitmap zu einer anderen ändern.
-
Hey.
Wie der Titel sagt suche ich eine Methode mit der ich eine Farbe, die in einer Bitmap vorkomt zu einer anderen ändern kann.
Also Wie MakeTransparent nur, dass ich halt die Zielfarbe selber festlegen möchte.
Danke im Voraus.
-
Ganz einfache Idee:
1. Erste Bitmap mit MakeTransparent präparieren
2. Zweite Bitmap mit der Zielfarbe und
3. erste Bitmap auf der zweiten malen.Ist relativ einfach und sicher, auch wenn es nicht sehr speicherplatzeffizient ist.
-
Der Vorschlag von Rhombicosidodecahedron ist nicht so schlecht, auch wenn er einiges an Overhead hat.
.NET hat bietet nämlich leider keinen Mechanismus an über den man beliebige Manipulationen an Bitmaps effizient und einfach machen kann. Wenn es also keine vordefinierte Methode gibt mit der man arbeiten kann muss man rumtricksen.
Die "sauberste" Variante, die aber was Effizienz angeht auch nicht sehr gut ist, ist LockBits. Ein Beispiel dazu findest du auf der LockBits MSDN Seite:
http://msdn.microsoft.com/en-us/library/5ey6h79d.aspx
Das Beispiel berücksichtigt nur leider nicht den Fall dass das geladene File eventuell ein anderes Farbformat als 24 Bit RGB verwenden könnte.
Und Zeilengrenzen werden auch nicht korrekt verarbeitet - das Beispiel wird u.U. mit Bitmaps mit nicht durch 4 teilbarer Breite nicht klarkommen.Aber so inetwa könnte es gehen (ungetestet, ggf. musst du ein paar Syntaxfehler etc. beheben):
Bitmap bmp = ... Color findColor = ... Color replaceColor = ... // Lock the bitmap's bits. BitmapData bmpData = bmp.LockBits( new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb); // Get the address of the first line. IntPtr ptr = bmpData.Scan0; // Declare an array to hold the bytes of the bitmap. int stride = bmpData.Stride > 0 ? bmpData.Stride : -bmpData.Stride; int byteSize = stride * bmpData.Height; byte[] rgbValues = new byte[byteSize]; // Copy the RGB values into the array. Marshal.Copy(ptr, rgbValues, 0, bytes); // Loop through all lines for (int y = 0; y < bmpData.Height; y++) { int offset = bmpData.Stride * y; if (bmpData.Stride < 0) offset += byteSize; Debug.Assert(offset >= 0 && offset < byteSize); // Loop through all pixels on this line for (int x = 0; x < bmpData.Width; x++) { // Modify the pixel value if (rgbValues[offset] == findColor.B && rgbValues[offset + 1] == findColor.G && rgbValues[offset + 2] == findColor.R) { rgbValues[offset] = replaceColor.B; rgbValues[offset + 1] = replaceColor.G; rgbValues[offset + 2] = replaceColor.R; } // Move to next pixel offset += 3; } } // Copy the RGB values back to the bitmap Marshal.Copy(rgbValues, 0, ptr, bytes); // Unlock the bits. bmp.UnlockBits(bmpData);
Das UnlockBits() sollte natürlich in einen "finally" Block, aber dafür war ich zu faul
-
Danke für die Antworten. Die letzte werde ichmir nochmal genauer an sehen, die andere funktioniert in sofern nicht, dass mein bild generell transparenz enthällt..