2010-05-21 13 views
8

Voglio sostituire tutti i pixel in un'area rettangolare di una bitmap con 'bianco trasparente' - cioè, a = 0, b = 255, r = 255, g = 255.Come dipingere un'area di una bitmap con 'bianco trasparente'?

FillRectangle non esegue questa operazione - dato un pennello trasparente, i pixel esistenti non vengono modificati.

Devo usare SetPixel individualmente per ogni pixel nel rettangolo?

risposta

13

Dovrai impostare la proprietà Graphics.CompositingMode. Per esempio:

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)); 
    } 
} 

Il colore reale si utilizza non importa, si otterrà un rettangolo nero con un alfa pari a 0.

+1

Non è * che * non comune usare i canali di colore per i dati, Dite per una mappa del terreno in una partita in cui acqua, strade, rocce, neve sono ARGB. Quindi a volte vuoi essere in grado di creare bitmap con valori RGB zero alfa e non zero. –

+1

BTW il colore nel mio caso è rilevante a causa dell'elaborazione successiva che "mescola" i colori delle aree trasparenti con altri colori delle aree. – mackenir

0

FillRectangle non esegue questa operazione - dato un pennello trasparente, i pixel esistenti non vengono modificati.

Ha senso, poiché si sta disegnando con un'opacità dello 0%. :)

Una soluzione rapida per un controllo sarebbe una chiave di colore. È possibile impostare il colore della chiave del controllo su un colore specifico (ad es. Magenta); tutti i pixel di questo colore verrebbero quindi resi trasparenti. (Se il controllo lo supporta, ovviamente.)

Quello o bitmap.MakeTransparent (colore) per scopi generali. Il problema è, ancora una volta, che il colore specificato sarebbe trasparente, quindi dovresti scegliere un colore che non esiste nell'immagine. (C'è un altro esempio qui: http://msdn.microsoft.com/en-us/library/ms172507%28v=VS.80%29.aspx)

Modifica: Alla fine, l'approccio LockBits() menzionato negli altri commenti potrebbe essere quello che cerchi. Una volta compreso come interagiscono i valori della larghezza e della falcata, è facile manipolare l'immagine al livello più basso possibile. Ecco un esempio generale: http://www.bobpowell.net/lockingbits.htm Assicurati che l'immagine supporti la trasparenza (vedi PixelFormat), quindi blocca l'immagine con una modalità appropriata (es. PixelFormat.Format32bppArgb), loop su ogni pixel, lettura per byte, scrivi il tuo nuovo colore, ecc.

+0

Sì, ha assolutamente senso :) Stavo solo dicendo. A parte questo, non penso che la tua risposta sia pertinente: sto lavorando con una bitmap, non con un controllo. E anche se potrei dipingere il rettangolo di un colore particolare (e spero che quel colore non sia presente in nessun'altra immagine) e renderlo trasparente, posso specificare "bianco trasparente"? Non lo penso. – mackenir

+0

yourBitmap.MakeTransparent (Color.White) dovrebbe farlo. Lo svantaggio è che tutto il bianco è trasparente allora, è vero. Un problema è che non tutti i formati di immagine supportano la trasparenza, quindi probabilmente dipende anche da come viene creato l'oggetto immagine. Dai un'occhiata all'enumerazione e al membro PixelFormat. E poi, ovviamente, l'approccio per bloccare la bitmap affinché funzioni nella dimensione del puntatore "non sicura". Cosa disse Pete. :) – sunside

2

Se si utilizzano i metodi di pittura compositi, verrà utilizzato l'alfa per sfumare il colore, quindi non accadrà nulla.

Se si desidera impostare la bitmap, crearla dai dati con lo sfondo desiderato oppure impostare lo sfondo utilizzando LockBits per manipolare i dati in blocco.

Si potrebbe anche essere in grado di fare utilizzando un metodo bitblt con i flag appropriati, ma non so come tradurre quello nel codice gestito.

0

Questo piccolo hack dovrebbe fare il trucco:

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

No. Ciò imposta i pixel su "nero trasparente": 0,0,0,0, non "bianco trasparente": 0,255,255,255. – Guffa

+0

Si può cambiare in 'g.Clear (Color.FromArgb (0, 255, 255, 255))' Anche se la risposta di Hans Passant è probabilmente migliore –

3

credo che è necessario utilizzare SetPixel (o metodo equivalente di impostare direttamente i valori dei colori) per ottenere i pixel di essere "trasparente".

È possibile utilizzare il metodo Graphics.Clear per impostare il colore oi pixel, ma non è possibile utilizzarlo per impostarli su trasparente e un colore. Ho provato questo per impostare i pixel in una parte di un bitmap:

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

I pixel nella regione finiscono come "nero trasparente": 0,0,0,0. Anche disegnare un rettangolo bianco solido prima della cancellazione non aiuta. Quando l'alfa è zero in un colore, anche gli altri componenti del colore sono zero.

Utilizzando un alfa quasi trasparente come 1 funziona bene, i pixel finiscono come "quasi bianco trasparente": 1.255.255.255.

1

punta Importante:

Assicurarsi che quando si creare l'immagine che si esegue questa operazione

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

e non

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

Ti risparmia qualche problema. Non supporre 32 bit significa canale alfa ;-)

Problemi correlati