本文参考自Canvas API和张鑫旭 的 canvas实现图片背景色去色变透明 及 HTML5 file API加canvas实现图片前端JS压缩并上传。根据实际需要修改而成。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<meta name="renderer" content="webkit">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<style>
#originalCanvas {
cursor: crosshair;
}
.resultCanvas {
position: relative;
max-width: 300px;
max-height: 300px;
background: url("bg.png");
}
li {
border: 1px solid #f0f;
margin-bottom: -1px;
}
img {
display: inline-block;
border: none;
vertical-align: middle;
}
</style>
</head>
<body style="background-color: beige">
<input type="file" id="file" onchange="fileImg(this)">
<ul>
<li>
<h2>原图信息</h2>
<div class="originalImgInfo"></div>
</li>
<li>
<h3>压缩图300*300</h3>
<canvas id="originalCanvas"></canvas>
</li>
<li>
<button type="button" onclick="translatedImg()">转换去色</button>
<div id="color" style="width:200px;height:50px;background-color: rgba(0,0,0,1)">rgba(0,0,0,1)</div>
<h2>转化之后</h2>
<div class="resultCanvas">
<img id="resultImg" src="dh.png" alt="原图">
</div>
</li>
</ul>
<script type="text/javascript">
// 上传图片
function fileImg ( et ) {
const file = et.files[0];
// console.log ( et );
// console.log ( et.value );
// console.log ( file );
let infoStr = '';
infoStr += '<p>name: ' + file.name + "</p>";
infoStr += '<p>lastModified: ' + file.lastModified + "</p>";
infoStr += '<p>lastModifiedDate: ' + file.lastModifiedDate.toLocaleString () + "</p>";
infoStr += '<p>size: ' + file.size + "KB" + "</p>";
infoStr += '<p>type: ' + file.type + "</p>";
document.querySelector ( ".originalImgInfo" ).innerHTML = infoStr;
// 原图 预览
let originalImgSrc = URL.createObjectURL ( file );
// document.querySelector ( "#originalImg" ).src = originalImgSrc;
const originalImg = new Image ();
originalImg.onload = function () {
// 原图 压缩后 绘制到 canvas
// 压缩后 最大 300*300
const MaxWidth = 300;
const MaxHeight = 300;
let cvsWidth = originalImg.width;
let cvsHeight = originalImg.height;
if ( cvsWidth > MaxWidth || cvsHeight > MaxHeight ) {
// 原图 宽比较大
if ( originalImg.width >= originalImg.height ) {
//宽
cvsWidth = MaxWidth;
cvsHeight = Math.round ( cvsWidth * originalImg.height / originalImg.width );
} else {
// 原图 高比较大
//高
cvsHeight = MaxHeight;
cvsWidth = Math.round ( MaxHeight * originalImg.width / originalImg.height );
}
}
let canvas = document.querySelector ( "#originalCanvas" );
canvas.width = cvsWidth;
canvas.height = cvsHeight;
let ctx = canvas.getContext ( "2d" );
ctx.clearRect ( 0, 0, cvsWidth, cvsHeight );
ctx.drawImage ( originalImg, 0, 0, cvsWidth, cvsHeight );
// canvas.parentNode.insertBefore ( originalImg, canvas );
//取色
let color = document.getElementById ( 'color' );
function pick ( event ) {
let x = event.offsetX;
let y = event.offsetY;
let pixel = ctx.getImageData ( x, y, 1, 1 );
let data = pixel.data;
let rgba = 'rgba(' + data[0] + ',' + data[1] +
',' + data[2] + ',' + (data[3] / 255) + ')';
color.style.background = rgba;
color.textContent = rgba;
}
canvas.addEventListener ( 'click', pick );
};
originalImg.src = originalImgSrc;
}
/*// 简易的颜色色值相似度计算算法: rgb
similar = Math.sqrt((r2 - r1) * (r2 - r1) + (g2 - g1) * (g2 - g1) + (b2 - b1) * (b2 - b1))*/
function similar ( r1, r2, g1, g2, b1, b2 ) {
return Math.sqrt ( (r2 - r1) * (r2 - r1) + (g2 - g1) * (g2 - g1) + (b2 - b1) * (b2 - b1) );
}
function translatedImg () {
const originalCanvas = document.querySelector ( "#originalCanvas" );
let canvas = document.createElement ( "canvas" );
canvas.width = originalCanvas.width;
canvas.height = originalCanvas.height;
let originalCtx = originalCanvas.getContext ( "2d" );
let ctx = canvas.getContext ( "2d" );
// 获取像素数据
let imgData = originalCtx.getImageData ( 0, 0, originalCanvas.width, originalCanvas.height );
console.log ( imgData );
// 要去除的颜色
const rgba = document.getElementById ( 'color' ).textContent.split ( "(" )[1].split ( ")" )[0].split ( "," );
console.log ( rgba );//rgba(11,172,212,1)
// 容差大小
let tolerance = 20;
// 去色
for ( let i = 0; i < imgData.data.length; i += 4 ) {
let r = imgData.data[i];// red
let g = imgData.data[i + 1];// green
let b = imgData.data[i + 2]; // blue
let alpha = imgData.data[i + 3];//alpha
let similarRelut = similar ( rgba[0], r, rgba[1], g, rgba[2], b ); //rgba
if ( similarRelut <= tolerance ) {
imgData.data[i] = 0;// red
imgData.data[i + 1] = 0;// green
imgData.data[i + 2] = 0; // blue
imgData.data[i + 3] = 0;//alpha
} else {
imgData.data[i] = r;// red
imgData.data[i + 1] = g;// green
imgData.data[i + 2] = b; // blue
imgData.data[i + 3] = alpha;//alpha
}
}
ctx.clearRect ( 0, 0, originalCanvas.width, originalCanvas.height );
ctx.putImageData ( imgData, 0, 0 );
document.querySelector ( "#resultImg" ).src = canvas.toDataURL ( "image/png" );
}
</script>
</body>
</html>
来源:oschina
链接:https://my.oschina.net/liyoungs/blog/3157971