2012-07-13 25 views
9

Si cargo una imagen, ¿cómo puedo recorrer todos sus píxeles y activar los blancos (o el color que especifique) para convertirme en transparente ?cómo editar píxeles y eliminar fondo blanco en una imagen de lienzo en html5 y javascript

Tengo una idea sobre cómo hacer esto, pero el proceso de bucle debería ser como una matriz 2d, por lo que implicaría dos bucles for.

Estaba pensando en comenzar en la fila superior del primer píxel, iterando hacia la derecha, si es un píxel blanco, luego lo vuelvo transparente, y muevo 1 píxel hacia la derecha, si no es blanco, entonces me detengo . Luego, en la misma fila, empiezo desde el píxel más a la izquierda, y compruebo, si es blanco, lo hago transparente, luego muevo 1 píxel hacia la izquierda, etc., etc.

Luego muevo 1 fila hacia abajo y repita todo el proceso ..

De esta forma no elimino ningún pixel blanco en la imagen real.

Respuesta

15

Es bastante simple de hacer usando getImageData y putImageData solo tenga en cuenta que puede obtener un impacto bastante significativo en el rendimiento cuanto mayor sea la imagen. Sólo tiene que determinar si el píxel actual es de color blanco, a continuación, cambiar su alfa a 0.

Live Demo

var canvas = document.getElementById("canvas"), 
    ctx = canvas.getContext("2d"), 
    image = document.getElementById("testImage"); 

canvas.height = canvas.width = 135; 
ctx.drawImage(image,0,0); 

var imgd = ctx.getImageData(0, 0, 135, 135), 
    pix = imgd.data, 
    newColor = {r:0,g:0,b:0, a:0}; 

for (var i = 0, n = pix.length; i <n; i += 4) { 
    var r = pix[i], 
      g = pix[i+1], 
      b = pix[i+2]; 

     // If its white then change it 
     if(r == 255 && g == 255 && b == 255){ 
      // Change the white to whatever. 
      pix[i] = newColor.r; 
      pix[i+1] = newColor.g; 
      pix[i+2] = newColor.b; 
      pix[i+3] = newColor.a; 
     } 
} 

ctx.putImageData(imgd, 0, 0);​ 

También se preguntó si podría hacer que los valores de tipo difuso para comprobar. Es realmente fácil, solo revisa si está en un cierto rango. Lo siguiente se apagará de blanco a blanco puro transparente.

// If its white or close then change it 
    if(r >=230 && g >= 230 && b >= 230){ 
     // Change the white to whatever. 
     pix[i] = newColor.r; 
     pix[i+1] = newColor.g; 
     pix[i+2] = newColor.b; 
     pix[i+3] = newColor.a; 
    } 

Más recursos

+1

Salida [esta] (http://beej.us/blog/data/html5s-canvas-2-pixel/) post para un tutorial sobre este tema para más información. – HeatfanJohn

+0

Buen artículo @HeatfanJohn – Loktar

+0

Esto cambiaría todos los píxeles blancos en la imagen, pero queremos eliminar solo los píxeles de fondo que son blancos, ¿verdad? – Rndm

-1

Loktar puede tener un método que 'funciona', pero su rendimiento es bastante deprimente. Esto puede ser un problema si tiene muchas imágenes, no desea que su sitio web drene las baterías de los dispositivos móviles/portátiles, o si solo desea velocidad. Aquí hay un método que funciona mucho más eficientemente. Haga clic en el botón "Ejecutar fragmento de código" para ver una demostración en acción.

'use-strict' 
 
let fileInput = document.getElementById('fileInput'), 
 
    theCANVAS = document.getElementById('theCanvas'), 
 
    theCANVASctx = theCANVAS.getContext('2d'), 
 
    imgTMP = document.getElementById('imgTMP'), 
 
    rComponent = document.getElementById('r'), 
 
    gComponent = document.getElementById('g'), 
 
    bComponent = document.getElementById('b'), 
 
    aComponent = document.getElementById('a'), 
 
    transColor = "rgba(255, 255, 255, 1)", 
 
    transCode = 0xffffffff; 
 

 
let makeColorTransparent = 
 
    function(canvasContext, transparentID, width, height) { 
 
    // where all the magic happens 
 
    let theImageData = canvasContext.getImageData(0, 0, width, height), 
 
     theImageDataBufferTMP = new ArrayBuffer(theImageData.data.length), 
 
     theImageDataClamped8TMP = new Uint8ClampedArray(theImageDataBufferTMP), 
 
     theImageDataUint32TMP = new Uint32Array(theImageDataBufferTMP), 
 
     n = theImageDataUint32TMP.length; 
 
    theImageDataClamped8TMP.set(theImageData.data); 
 

 
    imgDataLoop: while (n--) { 
 
     // effciency at its finest: 
 
     if (theImageDataUint32TMP[n] !== transparentID) 
 
     continue imgDataLoop; 
 
     theImageDataUint32TMP[n] = 0x00000000; // make it transparent 
 
    } 
 
    theImageData.data.set(theImageDataClamped8TMP); 
 
    theCANVASctx.putImageData(theImageData, 0, 0); 
 
    }, 
 
    downloadCanvas = function(downloadfilename) { 
 
    theCanvas.toBlob(function(theIMGblob) { 
 
     var thedataURL = URL.createObjectURL(theIMGblob), 
 
     theAtagLink = document.createElement('a'); 
 

 
     theAtagLink.download = '(proccessed)' + downloadfilename; 
 
     document.body.appendChild(theAtagLink); 
 
     theAtagLink.href = thedataURL; 
 
     theAtagLink.click(); 
 
    }); 
 
    }; 
 

 
fileInput.onchange = function(fileevent) { 
 
    let efiles = fileevent.target.files, 
 
    localTransColor = transColor, 
 
    localTransCode = transCode; 
 

 
    let cur = efiles.length, 
 
    nextfile = function() { 
 
     if (!cur--) { 
 
     imgTMP.src = ''; 
 
     return; 
 
     } 
 
     let fr = new FileReader(); 
 
     console.log(efiles[cur]); 
 
     fr.onload = function(dataevt) { 
 
     fr.onload = null; 
 
     let theArrayBuffer = dataevt.target.result, 
 
      theblob = new Blob([theArrayBuffer]); 
 
     imgTMP.src = URL.createObjectURL(theblob); 
 
     imgTMP.onload = function() { 
 
      imgTMP.onload = null; 
 
      let theImagesWidth = imgTMP.naturalWidth, 
 
      theImagesHeight = imgTMP.naturalHeight; 
 

 
      theCANVAS.width = theImagesWidth; 
 
      theCANVAS.height = theImagesHeight; 
 

 
      theCANVASctx.fillStyle = localTransColor; 
 
      theCANVASctx.clearRect(
 
      0, 
 
      0, 
 
      theImagesWidth, 
 
      theImagesHeight 
 
     ); 
 
      theCANVASctx.drawImage(imgTMP, 0, 0); 
 
      makeColorTransparent(
 
      theCANVASctx, 
 
      localTransCode, 
 
      theImagesWidth, 
 
      theImagesHeight 
 
     ); 
 

 
      //now, download the file: 
 
      downloadCanvas(efiles[cur].name); 
 

 
      //Finally, procced to proccess the next file 
 
      nextfile(); 
 
     }; 
 
     }; 
 
     fr.readAsArrayBuffer(efiles[cur]); 
 
    }; 
 
    nextfile(); 
 
} 
 

 
rComponent.oninput = gComponent.oninput = 
 
    bComponent.oninput = aComponent.oninput = 
 
    function() { 
 
    rComponent.value = Math.max(0, Math.min(rComponent.value, 255)); 
 
    gComponent.value = Math.max(0, Math.min(gComponent.value, 255)); 
 
    bComponent.value = Math.max(0, Math.min(bComponent.value, 255)); 
 
    aComponent.value = Math.max(0, Math.min(aComponent.value, 255)); 
 
    }; 
 

 
rComponent.onchange = gComponent.onchange = 
 
    bComponent.onchange = aComponent.onchange = 
 
    function() { 
 
    transColor = 'rgba(' + 
 
     rComponent.value + ',' + 
 
     gComponent.value + ',' + 
 
     bComponent.value + ',' + 
 
     aComponent.value/255 + ',' + 
 
     ')'; 
 
    // numberical equivelent of the rgba 
 
    transCode = 
 
     rComponent.value * 0x00000001 + 
 
     gComponent.value * 0x00000100 + 
 
     bComponent.value * 0x00010000 + 
 
     aComponent.value * 0x01000000; 
 
    };
<pre>rgba(<input type="number" value="255" max="255" min="0" step="1" id="r" maxlength="3" minlength="1" />,<input type="number" value="255" max="255" min="0" step="1" id="g" maxlength="3" minlength="1" />,<input type="number" value="255" max="255" min="0" step="1" id="b" maxlength="3" minlength="1" />,<input type="number" value="255" max="255" min="0" step="1" id="a" maxlength="3" minlength="1" />)</pre> 
 

 
<input type="file" name="filefield" multiple="multiple" accept="image/*" id="fileInput" /><br /> 
 
<img id="imgTMP" /> 
 
<canvas id="theCanvas"></canvas> 
 

 
<style>input[type=number]{width: 3em}#theCanvas {display: none}</style>

0

puede utilizar un marco de procesamiento de imágenes para no manejar manualmente los datos de píxeles.

En el caso de MarvinJ, dado un color, puede configurar todos los píxeles a transparente con una sola línea:

image.setColorToAlpha(0, 0); 

imagen de entrada:

enter image description here

Resultado:

enter image description here

Ejemplo Ejecutable:

var canvas = document.getElementById("canvas"); 
 
image = new MarvinImage(); 
 
image.load("https://i.imgur.com/UuvzbLx.png", imageLoaded); 
 

 
function imageLoaded(){ 
 
\t image.setColorToAlpha(0, 0); \t 
 
\t image.draw(canvas); 
 
}
<script src="https://www.marvinj.org/releases/marvinj-0.8.js"></script> 
 
<div style="width:400px; height:352px; background-image: linear-gradient(45deg, #808080 25%, transparent 25%), 
 
\t linear-gradient(-45deg, #808080 25%, transparent 25%), 
 
\t linear-gradient(45deg, transparent 75%, #808080 75%), 
 
\t linear-gradient(-45deg, transparent 75%, #808080 75%); 
 
\t background-size: 20px 20px; 
 
\t background-position: 0 0, 0 10px, 10px -10px, -10px 0px;"> 
 
<canvas id="canvas" width="400" height="352"></canvas> 
 
</div>

Cuestiones relacionadas