-
Notifications
You must be signed in to change notification settings - Fork 10
/
Copy pathdataToImage.html
137 lines (112 loc) · 4.84 KB
/
dataToImage.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>data to image demo</title>
</head>
<body>
<header><h1>data to image demo</h1></header>
<main>
可编辑,但是要注意JSON格式:
<pre id="getData" contenteditable="true">
{
"head": "hello colleagues",
"message": "Winter is coming, please keep warm."
}
</pre
>
<button id="toImage">生成</button>
<p><img id="dataImg" src="" alt="" /></p>
<pre id="dataShow"></pre>
<button id="toData">解析</button>
</main>
</body>
<script>
var imgUrl = null;
document.querySelector("#toImage").addEventListener("click", function() {
// var myObjData = {
// head: "hello colleagues",
// message: "Winter is coming, please keep warm."
// };
var TextData = document.querySelector("#getData").innerText;
var myObjData = JSON.parse(TextData);
console.log("TextData", TextData);
console.log("TextData", JSON.parse(TextData));
// 1. 将对象转换为字节数组
var strData = JSON.stringify(myObjData);
// TextEncoder 将输入的代码流指向一个字节流并输出
// TextEncoder.encode() 返回包含使用此特定TextEncoder对象的方法编码的文本的Uint8Array。
// Uint8Array 数组类型表示一个8位无符号整型数组,创建时内容被初始化为0。
var uint8array = new TextEncoder("utf-8").encode(strData);
// 方形图像的大小,该大小足以存储这些数据。
var dataSize = Math.ceil(Math.sqrt(uint8array.length / 3));
console.log("uint8array", uint8array); // [123,34,104, 101,97,100...]
// 2. 将字节数组转换为图像数据(需要无损格式的来存储图像数据,因此选择PNG作为输出格式)
// 8位无符号整型固定数组,类型化数组表示一个由值固定在0-255区间的8位无符号整型组成的数组
var paddedData = new Uint8ClampedArray(dataSize * dataSize * 4);
var idx = 0;
for (var i = 0; i < uint8array.length; i += 3) {
// subarray 方法是对于 TypedArray 数组的一部分,再建立一个新的视图。
var subArray = uint8array.subarray(i, i + 3);
// TypedArray 数组的 set 方法用于复制数组(普通数组或 TypedArray 数组),也就是将一段内容完全复制到另一段内存。
paddedData.set(subArray, idx);
paddedData.set([255], idx + 3);
idx += 4;
}
console.log("paddedData", paddedData); // [123,34,104,255, 101,97,100,255...]
var imageData = new ImageData(paddedData, dataSize, dataSize);
// 3. 绘制图像
var imgSize = 256;
var canvas = document.createElement("canvas");
canvas.width = canvas.height = imgSize;
var ctx = canvas.getContext("2d");
ctx.fillStyle = "#AA0000";
ctx.fillRect(0, 0, imgSize, imgSize);
// 第一个像素存放 真实存放数据的图片大小 (限制,不能超过255)
ctx.fillStyle = "rgb(" + dataSize + ",0,0)";
ctx.fillRect(0, 0, 1, 1);
ctx.putImageData(imageData, 0, 1);
imgUrl = canvas.toDataURL();
// 4. 显示图像
document.querySelector("#dataImg").src = imgUrl;
});
document.querySelector("#toData").addEventListener("click", function() {
var img = new Image();
// 1. 加载
img.onload = function() {
// 2. 将图像绘制到画布
var imgSize = img.width;
var canvas = document.createElement("canvas");
canvas.width = canvas.height = imgSize;
var ctx = canvas.getContext("2d");
ctx.drawImage(img, 0, 0);
// 3. 将像素转换为字节数组
var headerData = ctx.getImageData(0, 0, 1, 1);
var dataSize = headerData.data[0]; // 获取第一个像素存放的 真实存放数据的图片大小
var imageData = ctx.getImageData(0, 1, dataSize, dataSize);
var paddedData = imageData.data;
var uint8array = new Uint8Array((paddedData.length / 4) * 3);
var idx = 0;
for (var i = 0; i < paddedData.length - 1; i += 4) {
var subArray = paddedData.subarray(i, i + 3);
uint8array.set(subArray, idx);
idx += 3;
}
var includeBytes = uint8array.length;
for (var i = uint8array.length - 1; i > 0; i--) {
if (uint8array[i] == 0) {
includeBytes--;
} else {
break;
}
}
// 4. 解码字节数组
var data = uint8array.subarray(0, includeBytes);
var strData = new TextDecoder("utf-8").decode(data);
// 现在strData变量保存了编码到PNG图像中的原始字符串数据。
document.querySelector("#dataShow").innerHTML = strData;
};
img.src = imgUrl;
});
</script>
</html>