<!DOCTYPE html>
<html lang='en'>
<head>
<meta charset='UTF-8'>
<meta name='renderer' content='webkit'>
<meta name='renderer' content='ie-stand'>
<meta http-equiv='X-UA-Compatible' content='IE=Edge,chrome=1'>
<meta name='format-detection' content='telephone=no, email=no' />
<meta name='viewport' content='width = device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no'>
<title>图片隐身术</title>
</head>
<body>
<canvas id="canvas" width="495" height="654"></canvas>
<script>
var canvas = document.getElementById("canvas"),
ctx = canvas.getContext('2d'),
img = new Image();
// 获取图片中信息
// img.src = 'xiaolan.png';
// img.onload = function () {
// ctx.drawImage(img, 0, 0);
// var originData = ctx.getImageData(0, 0, ctx.canvas.width, ctx.canvas.height);
// console.log(originData);
// processData(originData);
// }
// 得到图片中隐藏的信息
var processData = function (originalData) {
var data = originalData.data;
for (var i = 0; i < data.length; i++) {
if (i % 4 == 0) {
// 红色分量
if (data[i] % 2 == 0) {
data[i] = 0;
} else {
data[i] = 255;
}
} else if (i % 4 == 3) {
// alpha通道不做处理
continue;
} else {
// 关闭其他分量,不关闭也不影响答案,甚至更美观 o(^▽^)o
data[i] = 0;
}
}
// 将结果绘制到画布
ctx.putImageData(originalData, 0, 0);
}
// 合并图片信息
img.src = "tangyan.jpg";
img.onload = function () {
ctx.drawImage(img, 0, 0);
var originalData = ctx.getImageData(0, 0, ctx.canvas.width, ctx.canvas.height);
ctx.fillText('I LOVE YOU FAN', 60, 130);
ctx.font = '30px Microsoft Yahei';
var textData = ctx.getImageData(0, 0, ctx.canvas.width, ctx.canvas.height);
mergeData(originalData,textData, 'R');
}
// 将想要隐藏的信息与图片合并在一起
var mergeData = function (originalData,newData, color) {
var oData = originalData.data;
var bit, offset; // offset的作用是找到alpha通道值,这里需要大家自己动动脑筋
switch (color) {
case 'R':
bit = 0;
offset = 3;
break;
case 'G':
bit = 1;
offset = 2;
break;
case 'B':
bit = 2;
offset = 1;
break;
}
for (var i = 0; i < oData.length; i++) {
if (i % 4 == bit) {
// 只处理目标通道
if (newData[i + offset] === 0 && (oData[i] % 2 === 1)) {
// 没有信息的像素,该通道最低位置0,但不要越界
if (oData[i] === 255) {
oData[i]--;
} else {
oData[i]++;
}
} else if (newData[i + offset] !== 0 && (oData[i] % 2 === 0)) {
// // 有信息的像素,该通道最低位置1,可以想想上面的斑点效果是怎么实现的
if (oData[i] === 255) {
oData[i]--;
} else {
oData[i]++;
}
}
}
}
ctx.putImageData(originalData, 0, 0);
}
</script>
</body>
</html>