2010-05-21 8 views
8

Ich möchte alle Pixel in einem rechteckigen Bereich einer Bitmap durch 'transparentes Weiß' ersetzen - d. H. A = 0, b = 255, r = 255, g = 255.Wie man einen Bereich einer Bitmap mit 'transparentem Weiß' malt?

FillRectangle tut dies nicht - bei einem transparenten Pinsel bleiben die vorhandenen Pixel unverändert.

Muss ich SetPixel einzeln für jedes Pixel im Rechteck verwenden?

Antwort

13

Sie müssen die Graphics.CompositingMode Eigenschaft festlegen. Zum Beispiel:

protected override void OnPaint(PaintEventArgs e) { 
    var img = Properties.Resources.Chrysanthemum; 
    e.Graphics.DrawImage(img, 0, 0); 
    e.Graphics.CompositingMode = System.Drawing.Drawing2D.CompositingMode.SourceCopy; 
    using (var br = new SolidBrush(Color.FromArgb(0, 255, 255, 255))) { 
     e.Graphics.FillRectangle(br, new Rectangle(50, 50, 100, 100)); 
    } 
} 

Die tatsächliche Farbe, die Sie spielt keine Rolle, verwenden, werden Sie ein schwarzes Rechteck mit einem Alpha von 0

+1

Es ist nicht * das * unüblich, Farbkanäle für Daten zu verwenden, Sagen Sie für eine Geländekarte in einem Spiel, wo Wasser, Straßen, Felsen, Schnee ARGB sind. Manchmal möchten Sie also Bitmaps mit Null-RGB-Werten erstellen können. –

+1

Übrigens ist die Farbe in meinem Fall relevant wegen der späteren Verarbeitung, die transparente Bereiche Farben mit anderen Bereichen Farben "mischt". – mackenir

0

FillRectangle tut dies nicht - bei einem transparenten Pinsel bleiben die vorhandenen Pixel unverändert.

Sinnvoll, da Sie mit 0% Deckkraft zeichnen. :)

Eine schnelle Lösung für eine Steuerung wäre ein Farbschlüssel. Sie können die Schlüsselfarbe des Steuerelements auf eine bestimmte Farbe (d. H. Magenta) einstellen. Alle Pixel dieser Farbe würden dann transparent dargestellt. (Wenn das Steuerelement dies natürlich unterstützt.)

Das oder Bitmap.MakeTransparent (Farbe) für allgemeine Zwecke. Das Problem ist wiederum, dass die angegebene Farbe transparent ist, so dass Sie eine Farbe auswählen müssen, die nicht im Bild vorhanden ist. (Es gibt ein anderes Beispiel hier: http://msdn.microsoft.com/en-us/library/ms172507%28v=VS.80%29.aspx)

Edit: Am Ende könnte der LockBits() Ansatz in den anderen Kommentaren erwähnt werden, was Sie suchen. Sobald Sie wissen, wie die Breite und die Schrittwerte zusammenwirken, ist es einfach, das Bild auf der niedrigst möglichen Ebene zu bearbeiten. Hier ist ein allgemeines Beispiel: http://www.bobpowell.net/lockingbits.htm Stellen Sie sicher, dass das Bild Transparenz unterstützt (siehe PixelFormat), sperren Sie dann das Bild mit einem geeigneten Modus (z. B. PixelFormat.Format32bppArgb), Schleife über jedes Pixel, lesen für Bytes, schreiben Sie Ihre neue Farbe, etc

+0

Ja, es macht total Sinn :) Ich wollte nur sagen. Abgesehen davon denke ich, dass deine Antwort nicht relevant ist - ich arbeite mit einer Bitmap, nicht mit einer Kontrolle. Und obwohl ich das Rechteck eine bestimmte Farbe malen könnte (und hoffe, dass diese Farbe nirgendwo sonst im Bild vorhanden ist) und es dann transparent mache, kann ich "transparentes Weiß" angeben? Ich denke nicht. – mackenir

+0

yourBitmap.MakeTransparent (Color.White) sollte das tun. Der Nachteil ist, dass alles weiß transparent ist, das stimmt. Ein Problem ist, dass nicht jedes Bildformat Transparenz unterstützt, es hängt also wahrscheinlich auch davon ab, wie Ihr Bildobjekt erstellt wird. Sehen Sie sich die PixelFormat-Enumeration und -Member an. Und dann, natürlich, der Ansatz zum Sperren der Bitmap in der "unsicheren" Zeiger Dimension arbeiten. Was Pete gesagt hat. :) – sunside

2

Wenn Sie die Composite-Malmethoden verwenden, wird das Alpha verwendet, um die Farbe zu mischen, so dass nichts passieren wird.

Wenn Sie die Bitmap festlegen möchten, erstellen Sie sie entweder aus Daten mit dem gewünschten Hintergrund oder legen Sie den Hintergrund fest, indem Sie LockBits verwenden, um die Daten massenweise zu bearbeiten.

Sie könnten auch in der Lage sein, eine Bitblt-Methode mit den entsprechenden Flags zu verwenden, aber ich weiß nicht, wie man das in verwalteten Code übersetzt.

0

Dieser kleine Hack sollte es tun:

Graphics g = Graphics.FromImage(myBitmap); 
g.SetClip(new RectangleF(10, 10, 20, 20)); 
g.Clear(Color.Transparent); 
g.RestoreClip(); 
g.Dispose(); 
+0

Nein. Das setzt die Pixel auf "transparent black": 0,0,0,0, nicht "transparent white": 0,255,255,255. – Guffa

+0

Sie könnten es ändern in 'g.Clear (Color.FromArgb (0, 255, 255, 255));' Obwohl Hans Passant die Antwort wahrscheinlich besser ist –

3

Ich glaube, dass Sie SetPixel (oder gleichwertiges Verfahren zur Einstellung der Farbwerte direkt), um die Pixel zu erhalten werden „transparent white“ verwenden müssen.

Sie können die Methode Graphics.Clear verwenden, um die Farbe oder die Pixel festzulegen. Sie können sie jedoch nicht verwenden, um sie sowohl als transparent als auch als Farbe festzulegen. Ich versuchte, dies um die Pixel in einem Teil der Bitmap gesetzt:

using (Graphics g = Graphics.FromImage(theBitmap)) { 
    g.Clip = new Region(new Rectangle(10, 10, 80, 80)); 
    g.Clear(Color.FromArgb(0, Color.White)); 
} 

Die Pixel in der Region am Ende als „transparent schwarz“: 0,0,0,0. Auch das Zeichnen eines durchgehenden weißen Rechtecks ​​vor dem Löschen hilft nicht. Wenn das Alpha in einer Farbe Null ist, sind die anderen Farbkomponenten ebenfalls Null.

Mit einem fast transparenten Alpha wie 1 funktioniert gut, die Pixel enden als "fast transparent weiß": 1.255.255.255.

1

Wichtiger Hinweis erhalten:

Vergewissern Sie sich, wenn Sie erstellen Sie das Bild, das Sie tun, um diese

mainImage = new Bitmap(totalWidth, maxHeight, PixelFormat.Format32bppARgb); 

und nicht

mainImage = new Bitmap(totalWidth, maxHeight, PixelFormat.Format32bppRgb); 

Es wird Ihnen einige Probleme ersparen. Gehe nicht davon aus, dass 32 Bit Alphakanal bedeutet ;-)

Verwandte Themen