Flex / ActionScript branco para transparente
-
03-07-2019 - |
Pergunta
Eu estou tentando escrever alguma coisa no meu 3 aplicação Flex com actionscript que terá uma imagem e quando um usuário clica em um botão, ele irá retirar todas as (ish) pixels brancos e convertê-los para transparente, eu digo branco ( ish) porque eu tentei exatamente branco, mas eu recebo um monte de artefatos em torno das bordas. Eu comecei um pouco perto usando o seguinte código:
targetBitmapData.threshold(sourceBitmapData, sourceBitmapData.rect, new Point(0,0), ">=", 0xFFf7f0f2, 0x00FFFFFF, 0xFFFFFFFF, true);
No entanto, ele também torna vermelho ou amarelo desaparecer. Por que ele está fazendo isso? Eu não sei exatamente como fazer este trabalho. Existe outra função que é mais adequado para as minhas necessidades?
Solução
Um amigo e eu estávamos tentando fazer isso um tempo atrás para um projeto, e encontrou escrevendo um método em linha que faz isso no ActionScript para ser incrivelmente lento. Você tem que analisar cada pixel e fazer um cálculo contra ela, mas fazê-lo com PixelBender provou ser muito rápido (se você pode usar o Flash 10, caso contrário, seu preso com lenta AS).
O Pixel Bender olhares código como:
input image4 src;
output float4 dst;
// How close of a match you want
parameter float threshold
<
minValue: 0.0;
maxValue: 1.0;
defaultValue: 0.4;
>;
// Color you are matching against.
parameter float3 color
<
defaultValue: float3(1.0, 1.0, 1.0);
>;
void evaluatePixel()
{
float4 current = sampleNearest(src, outCoord());
dst = float4((distance(current.rgb, color) < threshold) ? 0.0 : current);
}
Se você precisa fazê-lo em como você pode usar algo como:
function threshold(source:BitmapData, dest:BitmapData, color:uint, threshold:Number) {
dest.lock();
var x:uint, y:uint;
for (y = 0; y < source.height; y++) {
for (x = 0; x < source.width; x++) {
var c1:uint = source.getPixel(x, y);
var c2:uint = color;
var rx:uint = Math.abs(((c1 & 0xff0000) >> 16) - ((c2 & 0xff0000) >> 16));
var gx:uint = Math.abs(((c1 & 0xff00) >> 8) - ((c2 & 0xff00) >> 8));
var bx:uint = Math.abs((c1 & 0xff) - (c2 & 0xff));
var dist = Math.sqrt(rx*rx + gx*gx + bx*bx);
if (dist <= threshold)
dest.setPixel(x, y, 0x00ffffff);
else
dest.setPixel(x, y, c1);
}
}
dest.unlock();
}
Outras dicas
Você pode realmente fazê-lo sem pixelbender e em tempo real, graças à inerente função limite :
// Creates a new transparent BitmapData (in case the source is opaque)
var dest:BitmapData = new BitmapData(source.width,source.height,true,0x00000000);
// Copies the source pixels onto it
dest.draw(source);
// Replaces all the pixels greater than 0xf1f1f1 by transparent pixels
dest.threshold(source, source.rect, new Point(), ">", 0xfff1f1f1,0x00000000);
// And here you go ...
addChild(new Bitmap(dest));
parece que o código acima faria uma gama de cores transparente.
pseudo-código:
para cada pixel na targetBitmapData
se a cor do pixel é> = # FFF7F0F2
mudança de cor para # 00FFFFFF
algo assim nunca será perfeito, porque você vai perder todas as cores de luz Gostaria de encontrar um seletor de cores on-line que você pode usar para ver exatamente quais cores serão alteradas
A resposta em 1 de Pixel Bender código:
dst = float4 (? (Distância (current.rgb, cor) deve ser: dst = (distância (current.rgb, cor) ou Se (distância (current.rgb, cor)