Como aplicar a técnica de chroma key em Adobe Flash

A técnica de Chroma Key , ou seja, a substituição de uma determinada cor, com o outro (ou outra fonte), a última década tem explodida, uma vez mais com quiralidade considerável, graças à tecnologia cada vez mais generalizada presente na película e no processamento de imagens digitais. Se no passado o Chroma Key foi usado muitas vezes com resultados pobres, hoje é uma técnica aplicada de forma contínua, mesmo em contextos e situações imagináveis ​​ou não, sempre reconhecível, como evidenciado pelo vídeo abaixo:

Há mostreò agora como aplicá-los técnica bastante simples Chroma Key no ambiente Adobe Flash. exemplo que eu fiz , eu usei um objeto de vídeo cortada para o seu quarto (ou WebCam que é).

Nota: nas amostras de código abaixo, e na demonstração filme do Flash , eu usei o preto como a cor do chroma! Na verdade, como você deve saber, são usados ​​painéis ou folhas de cor azul (daí o nome de Blue Screen) ou verde (Pantone 354)! ; dove è AA è il canale alpha di trasparenza. Você também vai notar que os valores uint cores são tudo na forma 0xAARRGGBB , onde AA é o canal alfa para transparência.

dell'oggetto BitmapData . threshold ( ) è un metodo molto potente e al tempo stesso molto semplice da utilizzare. Para processar a imagem I utilizado o método de threshold ( ) objeto BitmapData . threshold ( ) é um método muito eficaz e, ao mesmo tempo, muito fácil de usar. Ela permite realizar um controlo de um pixel por pixel Bitmap , e descobriram que uma cor (mascarado) é igual, não igual, maior ou menor do que o outro e sostituiendolo com um dado valor. O protótipo é a seguinte:

1
2
3
4
5
6
7
8
threshold ( sourceBitmapData : BitmapData , limiar public function (sourceBitmapData: BitmapData ,
, sourceRect: retângulo ,
, destPoint: Ponto ,
, operação: Cordas ,
uint , limiar: uint ,
uint = 0 , color: uint = 0,
uint = 0xFFFFFFFF , mask: uint = 0xFFFFFFFF,
= false ) : uint copysource: Boolean = false): uint
  • sourceBitmapData são os dados de bitmap na qual operam. Essa fonte pode ser diferente ou o mesmo que o BitmapData no qual você está trabalhando
  • che definisce l'area su cui eseguire l'operazione sourceRect é um ponteiro para um objeto do tipo Rectangle que define a área em que para realizar a operação
  • che definisce le coordinate x ed y di destinazione: quasi sempre 0,0 destPoint é um ponteiro para um objeto do tipo Point que define as coordenadas x e y de destino: quase sempre 0.0
  • operation esta é uma string que define a operação a ser realizada sobre os pixels (ver detalhes abaixo), e pode ter os seguintes valores: "<", "<=", ">", ">=", "==", "!="
  • threshold é um unsigned int, um inteiro sem sinal, indicando a cor (ou valor limite) para comparar com os dados de pixel do bitmap, por exemplo 0x00FF0000
  • color é um unsigned int, um inteiro sem sinal, indicando a cor a ser substituída, se a operação de comparação é bem sucedida
  • e ai pixel della bitmap sorgente mask é um unsigned int, um inteiro sem sinal, indicando que a máscara deve ser aplicada ao parâmetro de threshold e os pixels de fonte mapa de bits
  • copierà il valore corrente quando l'operazione di confronto fallisce copySource é um boolean que se definir a true irá copiar o valor atual, quando a operação de comparação não

O método retorna uma uint que representa o número de pixels alterados. A operação que realiza o método pode ser resumida da seguinte forma:

  • A partir das coordenadas definido na sourceRect
  • , cioè viene eseguita l'operazione di AND logico tra i due valori: (pixelLetto & mask) É lido o valor do pixel em sourceBitmap e é aplicada à máscara, mask , ou seja, a operação é realizada pela lógica E dos dois valores: (pixelLetto & mask)
  • O valor obtido é comparado com (threshold & mask) , também mascarado, aplicando-se a operação de comparação de operation
  • viene impostato quel pixel su color Se a comparação retornar true , então a partir de destPoint está definido que o pixel da color
  • a true : in questo caso viene copiato il valore così com'è Se a comparação retornar false , não realizar qualquer operação, a menos que defina o parâmetro copySource a true : neste caso, o valor é copiado como é

No exemplo que eu fiz você vai notar quatro caixas com quatro imagens do quarto:

chromakey
Lembre-se de permitir o acesso à sala: Se você tem mais quartos comunicantes
escolher o caminho certo com o botão direito de definições

: A primeira caixa no canto superior esquerdo, vídeo original, o vídeo é o que parece quando usamos o objeto Camera anexado ao objeto Video :

1
2
Camera = Camera . getCamera ( ) ; var cam: Camera = Camera getCamera ();.
( cam ) ; . vid_video attachCamera (CAM);

Imediatamente a seguir são a caixa de Threshold, este é gerado da seguinte maneira:

1
2
3
4
/ / Threshold
BitmapData = new BitmapData ( vid_video . width , vid_video . height , true ) ; var simpleBitmapData: BitmapData = new BitmapData (largura vid_video., vid_video altura, é verdade.);
Bitmap = new Bitmap ( simpleBitmapData ) ; var simpleBitmap: Bitmap = new Bitmap (simpleBitmapData);
simpleBitmap ) ; addChild (simpleBitmap);

Em essência, este cria a primeira instância de um objecto BitmapData o tamanho do vídeo. Este está ligado a um objecto Bitmap , o qual pode ser adicionado à fase. (impostate almeno un valore di 30 fotogrammi al secondo nel vostro progetto): Neste ponto, pode-se aplicar o método de threshold , inserindo nosso procedimento dentro do evento ENTER_FRAME (definido para um valor de pelo menos 30 quadros por segundo em seu projeto):

1
2
3
4
5
6
7
8
9
10
11
12
13
Event . ENTER_FRAME , addEventListener ( Evento . ENTER_FRAME,
e : Event ) : void { function (e: Evento ): void {
. draw ( vid_video ) ; .. simpleBitmap bitmapData empate (vid_video);
. threshold ( simpleBitmap . bitmapData , simpleBitmap. bitmapData. limite (simpleBitmap. bitmapData,
( 0 , 0 , simpleBitmap . bitmapData . width , simpleBitmap . bitmapData . height ) , new Rectangle (0, 0, simpleBitmap. bitmapData. largura, simpleBitmap. bitmapData. altura),
( 0 , 0 ) , novo ponto (0, 0),
"=="
0x00000000,
0x00000000,
0x00ffffff,
; true);
}
);

, visualizzata nello stage tramite l'oggetto Bitmap simpleBitmap . Linha cópia 3 (cada ENTER_FRAME ) de conteúdo de vídeo em nosso BitmapData , exibido no Palco usando o objeto Bitmap simpleBitmap . il metodo threshold() , nelle modalità descritte in precedenza. Linha 4 aplica-se (sempre em cada ENTER_FRAME ) no nosso BitmapData método threshold() , da maneira descrita anteriormente. eseguendo l'operazione di uguaglianza "==" . Neste exemplo, utilizados os parâmetros que se aplicam threshold sobre toda a área do Bitmap de realizar a operação de igualdade "==" . in dipendenza della maschera) viene sostituito con il vuoto 0x00000000 . Se o leito é igual aos pixels pretos 0x00000000 (ou 0xFF000000 na dependência da máscara) é substituído com o vazio 0x00000000 . No final, portanto, temos um chroma key no preto.

Utilizando um intervalo

Esta técnica é muito bem quando você quer substituir a cor é preciso. Em nosso exemplo anterior, na verdade, um valor de 0x00000001 não é levado em consideração. Para superar esse obstáculo, devemos fazer algo diferente de "==" . Além disso, em um filme real, há sombras e reflexos a considerar que, na prática, que se deslocam a nossa cor chroma de um nível mínimo para um nível máximo. O ideal, então, seria a de criar uma série de filtros de threshold que ocorrem tanto um nível escuro que um nível de luz da cor que escolheu para a croma.
Para conseguir isso não é o suficiente para escrever:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
Event . ENTER_FRAME , addEventListener ( Evento . ENTER_FRAME,
e : Event ) : void { function (e: Evento ): void {
. draw ( vid_video ) ; .. simpleBitmap bitmapData empate (vid_video);

. threshold ( simpleBitmap . bitmapData , simpleBitmap. bitmapData. limite (simpleBitmap. bitmapData,
( 0 , 0 , simpleBitmap . bitmapData . width , simpleBitmap . bitmapData . height ) , new Rectangle (0, 0, simpleBitmap. bitmapData. largura, simpleBitmap. bitmapData. altura),
( 0 , 0 ) , novo ponto (0, 0),
"<=",
0x00222222,
0x00000000,
0x00ffffff,
; true);
}
);

. O resultado, embora apreciável, não é correto, por uma razão simples: usando o operador "<=" , que é conceitualmente correto, confrontanto todos os níveis inferior ou igual a 0x00222222 . Segue-se que o valor 0x00002200 - o que é um verde escuro - será considerado como chroma, que não era a nossa intenção, querendo filtrar apenas a gradação preto e alguns um pouco 'mais claro, mas sempre a "negra". le tre componenti RGB separatamente. A técnica mais preciso é o parâmetro para explorar mask e analisar através do threshold dos três componentes RGB separadamente. O que vamos conseguir agora é um filtro inverso, ou seja, vamos criar uma máscara que irá conter apenas a nossa gama. Primeiro vamos criar uma função que pode operar o controle sobre um canal RGB específico:

1
2
3
4
5
6
7
8
9
10
11
myBitmapData : BitmapData , channel : String , op : String , threshold : uint ) : void { applyThresholdRGB função (myBitmapData: BitmapData , canal: Cordas , op: Cordas , limite: uint ): void {
uint = ( channel == "red" ) ? 0x00FF0000 : ( ( channel == "green" ) ? 0x0000FF00 : 0x000000FF ) ; var MaskColor: uint = (canal == "vermelho") 0x00FF0000: ((canal == "verde") 0x0000FF00:? 0x000000FF)?;
( myBitmapData , myBitmapData. limite (myBitmapData,
( 0 , 0 , myBitmapData . width , myBitmapData . height ) , new Rectangle (0, 0, myBitmapData. largura, myBitmapData. altura),
( 0 , 0 ) , novo ponto (0, 0),
op,
limiar
0x00000000,
MaskColor,
; false);
}

) su un canale RGB specificato nel parametro channel . A função applyThresholdRGB() permite que você execute um dado de comparação (ver parâmetro op ) em um canal RGB especificado no parâmetro de channel . Vamos criar uma função que gera uma máscara:

1
2
3
4
5
6
7
8
9
10
11
12
13
myBitmapData : BitmapData , colorLow : uint , colorHi : uint ) : void { createBitmapMask função (myBitmapData: BitmapData , colorLow: uint , colorHi: uint ): void {
/ / Red
"red" , "<" , colorLow ) ; applyThresholdRGB (myBitmapData, "vermelho", "<", colorLow);
"red" , ">" , colorHi ) ; applyThresholdRGB (myBitmapData, "vermelho", ">", colorHi);

/ / Verde
"green" , "<" , colorLow ) ; applyThresholdRGB (myBitmapData, "verde", "<", colorLow);
"green" , ">" , colorHi ) ; applyThresholdRGB (myBitmapData, "verde", ">", colorHi);

/ / Azul
"blue" , "<" , colorLow ) ; applyThresholdRGB (myBitmapData, "azul", "<", colorLow);
"blue" , ">" , colorHi ) ; applyThresholdRGB (myBitmapData, "azul", ">", colorHi);
}

Agora que temos a máscara (no exemplo é a caixa no canto superior direito máscara de bitmap), podemos usá-lo para sobrepor a imagem original, eliminando as partes que não são necessários. Em resumo, temos:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Event . ENTER_FRAME , addEventListener ( Evento . ENTER_FRAME,
e : Event ) : void { function (e: Evento ): void {
/ / Clonar a imagem de vídeo
. draw ( vid_video ) ; .. simpleBitmap bitmapData empate (vid_video);

/ / Cria um objeto com bitmap dados BitmapData mesmo que o original
Bitmap = new Bitmap ( simpleBitmap . bitmapData . clone ( ) ) ; var bitmapMask: Bitmap = new Bitmap (. simpleBitmap. bitmapData clone ());

/ / Cria a máscara
bitmapData , 0x00000000 , 0x00222222 ) ; createBitmapMask (bitmapMask. bitmapData, 0x00000000, 0x00222222);

/ / I aplicar a máscara para o original em BlendMode.ERASE
. draw ( bitmapMask , null , null , BlendMode . ERASE , null , false ) ; .. simpleBitmap bitmapData empate (bitmapMask, null, null, BlendMode ERASE, null, false.);
}
);

O resultado final é visível na caixa no canto inferior direito Mesclar Bitmap. Desta forma é possível aplicar o Chroma Key não a uma cor específica, mas a uma escala.

7 comentários para: ""

  1. 17 de setembro de 2011 ale:

    você pode fazer o upload. fla que você criou?

  2. 29 de maio de 2012 Dario :

    E no caso de você precisava de um limbo verde (ou branco) em um estúdio de filme em que atirar em um muito, muito baixo ... Líquido Gate Studio,

  3. 09 de fevereiro de 2013 Kevin:

    Muito bom exemplo -, gostaria de ver o Fla também.!

Deixe um comentário

TAG XHTML permita: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> código de entrada:
 <pre></pre> // blocco generico <code></code> // blocco generico [cc_actionscript][/cc_actionscript] // Actionscript [cc_actionscript3][/cc_actionscript3] // Actionscript 3 [cc_css][/cc_css] // CSS Style Sheet [cc_html][/cc_html] // HTML [cc_js][/cc_js] // Javascript [cc_objc][/cc_objc] // Objective-C [cc_php][/cc_objc] // PHP [cc_sql][/cc_sql] // SQL