如果我加载图像,我怎样才能遍历所有像素并将白色像素(或我指定的颜色)转为透明?
我知道如何执行此操作,但循环过程应该像2d数组,因此它将涉及两个for循环。
我以为我会从顶行第一个像素开始,向右迭代,如果它是一个白色像素,然后我把它变成透明,向右移动1个像素,如果它不是白色,那么我就停止了。然后在同一行,我从最左边的像素开始,然后检查,如果是白色,我把它变成透明,然后向左移动1个像素等等......
然后我向下移动1行并重复整个过程..
这样我就不会删除实际图像中的任何白色像素。
答案 0 :(得分:21)
使用getImageData
和putImageData
非常简单,只需注意,图像越大,性能就越显着。您只需确定当前像素是否为白色,然后将其alpha更改为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);
还有人询问你是否可以使这些值模糊检查。它非常简单,只需检查它是否在一定范围内。以下将关闭白色至纯白色透明。
// 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;
}
更多资源
答案 1 :(得分:2)
您可以使用图像处理框架手动处理像素数据。
如果是MarvinJ,给定一种颜色,您可以用一行将所有像素设置为透明:
var canvas = document.getElementById("canvas");
image = new MarvinImage();
image.load("https://i.imgur.com/UuvzbLx.png", imageLoaded);
function imageLoaded(){
image.setColorToAlpha(0, 0);
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%),
linear-gradient(-45deg, #808080 25%, transparent 25%),
linear-gradient(45deg, transparent 75%, #808080 75%),
linear-gradient(-45deg, transparent 75%, #808080 75%);
background-size: 20px 20px;
background-position: 0 0, 0 10px, 10px -10px, -10px 0px;">
<canvas id="canvas" width="400" height="352"></canvas>
</div>
&#13;
{{1}}&#13;
答案 2 :(得分:-1)
Loktar可能有一种“有效”的方法,但它的表现相当惨淡。如果你有很多图像,你不希望你的网站耗尽笔记本电脑/移动设备电池,或者你只是想要速度,这可能是一个问题。这是一种更有效的方法。单击“运行代码片段”按钮,以获取其实际演示。
'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>