2012-07-13 7 views
9

Jeśli ładuję obraz, w jaki sposób mogę przechodzić przez wszystkie jego piksele i obracać białe (lub którekolwiek z podanych kolorów), aby stały się przezroczyste ?jak edytować piksele i usunąć białe tło w obrazie na płótnie w html5 i javascript

Mam pomysł, jak to zrobić, ale proces zapętlenia powinien być jak tablica 2d, a więc wymaga dwóch pętli.

Myślałem, że zacznę od pierwszego rzędu piksela, iterując w prawo, jeśli jest to biały piksel, to zmieniam go w przezroczysty i przesuję o 1 piksel w prawo, jeśli nie jest biały, to zatrzymuję się . Następnie w tym samym wierszu zaczynam od lewego najbardziej piksela i zaznaczam, czy biały, zmieniam go na przezroczysty, a następnie przesuję o 1 piksel w lewo, itd., Itd ...

Następnie przesuję 1 rząd w dół i powtórz cały proces ..

W ten sposób nie usuwam białych pikseli w rzeczywistym obrazie.

Odpowiedz

15

Jest to całkiem proste do zrobienia przy użyciu getImageData i putImageData, wystarczy pamiętać, że można uzyskać znaczący hit wydajności, im większy obraz. Trzeba tylko określić, czy aktualny piksel jest biały, a następnie zmienić jego alfa 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);​ 

Stwierdzono również pytanie, czy można zrobić porządek wartości rozmytych sprawdzić. To naprawdę proste, po prostu sprawdź, czy jest w pewnym zakresie. Następujące elementy zostaną wyłączone z bieli do czystej bieli przezroczystej.

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

Więcej środków

+1

wyjazdu [to], (http://beej.us/blog/data/html5s-canvas-2-pixel/) po dla samouczka na ten temat, aby uzyskać więcej informacji. – HeatfanJohn

+0

Przyjemny artykuł @HeatfanJohn – Loktar

+0

Zmieniłoby to wszystkie białe piksele obrazu, ale chcemy usunąć tylko piksele w tle, które są białe, prawda? – Rndm

-1

Loktar może mieć metodę, która 'działa', ale wydajność jest raczej ponura. Może to stanowić problem, jeśli masz dużo zdjęć, nie chcesz, aby Twoja strona zużywała baterie na laptopa/urządzenia przenośne, lub jeśli potrzebujesz tylko prędkości. Oto metoda, która działa znacznie wydajniej. Kliknij przycisk "Uruchom fragment kodu", aby zobaczyć wersję demonstracyjną w akcji.

'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

Można użyć ramy przetwarzania obrazu, aby nie ręcznie obsługiwać dane pikseli.

W przypadku MarvinJ, biorąc pod uwagę kolor, można ustawić wszystkie piksele na przezroczyste z jednej linii:

image.setColorToAlpha(0, 0); 

obrazu wejściowego:

enter image description here

Wynik:

enter image description here

Runnable przykład:

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>

Powiązane problemy