2013-02-15 12 views
19

Ho un'immagine con un vaso giallo in primo piano e lo sfondo trasparente:Put bordo Immagine intorno parzialmente trasparente in fase di elaborazione su CGContext

enter image description here

sto disegnando su un CGContext:

CGContextDrawImage(context, CGRectMake(0, 0, 100, 100), myImage.CGImage); 

posso disegnare un'ombra intorno ad esso utilizzando la seguente dichiarazione prima CGContextDrawImage:

CGContextSetShadowWithColor(context, CGSizeMake(0,0), 5, [UIColor blueColor].CGColor); 

enter image description here

Ma voglio mettere un colpo intorno all'immagine, in modo che sarò sembra seguente:

enter image description here

Se ho fatto questo:

CGContextSetRGBStrokeColor(shadowContext, 0.0f, 0.0f, 1.0f, 1.0f); 
CGContextSetLineWidth(shadowContext, 5); 
CGContextStrokeRect(shadowContext, CGRectMake(0, 0, 100, 100)); 

E ' (ovviamente) disegna un bordo rettangolare attorno all'intero iamge in questo modo:

enter image description here

Quale non è quello che mi serve.

Ma qual è il modo migliore per disegnare il bordo come nella terza immagine?

Si noti che in questo caso non è possibile utilizzare UIImageView, pertanto non è possibile utilizzare le proprietà di CALayer di UIImageView.

+0

Si sta chiamando 'CGContextSetShadowWithColor' prima della chiamata a' CGContextDrawImage'? – Ariel

+0

@elcanibal: Sì. Altrimenti, non ci sarebbe ombra. Sto modificando la domanda originale per riflettere questo. –

+0

Si prega di inviare un PNG del vaso giallo con sfondo trasparente. La tua prima immagine (senza decorazioni) ha uno sfondo grigio. –

risposta

13

Un modo per fare ciò è utilizzare lo mathematical morphology operator of dilation per "espandere" il canale alfa dell'immagine verso l'esterno, quindi utilizzare l'immagine della scala di grigi risultante come maschera per simulare un tratto. Riempiendo la maschera dilatata, quindi disegnando l'immagine principale sopra, ottieni l'effetto di un tratto. Ho creato una demo che mostra questo effetto, disponibile su Github qui: https://github.com/warrenm/Morphology (tutta la fonte è MIT con licenza, nel caso si rivelasse utile).

Ed ecco uno screenshot di esso in azione:

enter image description here

Si noti che questo è incredibilmente lenta (dilatazione richiede iterazione di un kernel su ogni pixel), così si dovrebbe scegliere una larghezza del tratto e precompute la maschera l'immagine per ciascuna delle tue immagini sorgente in anticipo.

+1

Mi chiedo quanto sia fattibile portarlo nel Core Image Kernel Language. Tale implementazione potrebbe essere molto più veloce di un ciclo dritto con operazioni scalari C. –

+0

Per una persona con una certa esperienza con CI o anche GLSL sarebbe piuttosto banale. È solo un operatore di minimizzazione su un quartiere. Tuttavia, mi risulta che Core Image non sia compatibile con iOS. Inoltre, se uno fosse intelligente, si potrebbe probabilmente approfittare di una proprietà di separabilità o scomposizione del kernel per fare meno lavoro. – warrenm

+0

Dang, hai ragione. Non l'avevo notato prima: CIKernel non è presente in iOS (andando per sua assenza dai documenti iOS). –

0

Proverei a impostare il colore del tratto e la larghezza della linea prima della chiamata a CGContextDrawImage o a modificare l'ombreggiatura (opacità, sfocatura, ecc.) In modo che assomigli ad un tratto intorno all'immagine. Fammi sapere se funziona!

+0

Non funzionerà. Due ragioni: 1. L'ombra non simula un tratto in modo accurato. 2.Avrò bisogno di mettere sia il tratto che l'ombra. Quindi ho bisogno di essere in grado di accarezzare davvero l'immagine. –

+0

È possibile impostare entrambe le cose prima di chiamare 'CGContextDrawImage', cioè chiamare' CGContextSetShadowWithColor', 'CGContextSetRGBStrokeColor' e' CGContextSetLineWidth' in precedenza. – Ariel

+1

@elcanibal: Ma cosa ti accarezza? Hai bisogno di un percorso. –

Problemi correlati