一个有趣的程序。
主要技术包含图片拖拽、粘贴、双击上传,然后通过canvas获得图片每一像素的rgb颜色值,然后按颜色值总体大小使用相应的字符代替形成字符画。
原图:

转换后:

代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>image2char</title>
<style>
.imageUploader {}
.imageUploader .eventContainerDiv {width:100%;height:100px;min-width:300px;min-height:100px;border:3px dashed silver;padding:4px;cursor:default;}
.imageUploader .eventContainerDiv img {display:none;overflow-x:auto;}
.imageUploader .imageContainerDiv .imageBox {width:200px;height:150px;float:left;margin:4px;border:1px solid #eee;}
.imageUploader .imageContainerDiv .imageBox img {max-width:100%;max-height:100%;object-fit: cover;}
.imageUploader .imageContainerDiv .imageBox button {height:28px;margin-top:-28px;position: absolute;}
.pixel-container {margin:0;padding:0;}
.pixel-row {display:flex;}
.pixel {width:12px;height:12px;margin:0;padding:0;font-size:12px;font-family:宋体;}
</style>
</head>
<body>
<input type="hidden" id="article_link_image" name="article_link_image" value=""/>
<div id="imageUploader" class="imageUploader" upload="" maxWidth="400" maxHeight="600" limitCount="1"></div>
<div id="imageShow"></div>
</body>
<script>
// 拖拽上传,兼容IE、FireFox、Chrome
function dragEventProcess(eventContainerDiv,upload){
document.addEventListener("dragenter", function(e){
eventContainerDiv.style.borderColor = ‘gray‘;
}, false);
document.addEventListener("dragleave", function(e){
eventContainerDiv.style.borderColor = ‘silver‘;
}, false);
eventContainerDiv.addEventListener("dragenter", function(e){
eventContainerDiv.style.borderColor = ‘gray‘;
eventContainerDiv.style.backgroundColor = ‘white‘;
}, false);
eventContainerDiv.addEventListener("dragleave", function(e){
eventContainerDiv.style.backgroundColor = ‘transparent‘;
}, false);
eventContainerDiv.addEventListener("dragenter", function(e){
e.stopPropagation();
e.preventDefault();
}, false);
eventContainerDiv.addEventListener("dragover", function(e){
e.stopPropagation();
e.preventDefault();
}, false);
eventContainerDiv.addEventListener("drop", function(e){
e.stopPropagation();
e.preventDefault();
var imageFile = e.dataTransfer.files[0];
loadImage(imageFile);
//submit.disabled = false;
}, false);
}
// 粘贴上传,兼容IE、FireFox、Chrome
function pasteEventProcess(eventContainerDiv,upload){
eventContainerDiv.addEventListener("paste", function(event){
// console.log(event);
// console.log(clipboardData);
// chrome、edge、firefox,不管粘贴截图还是网络图片都能从clipboardData中得到图片二进制数据。
if ( event.clipboardData || event.originalEvent ) {
var clipboardData = (event.clipboardData || event.originalEvent.clipboardData);
if ( clipboardData.items ) {
var items = clipboardData.items;
for (var i = 0; i < items.length; i++) {
// console.log(items[i].type);
if (items[i].type.indexOf("image") !== -1) {
var imageFile = items[i].getAsFile();
loadImage(imageFile);
}
}
}
}else {
alert(‘the browser is not support.‘);
}
}, false);
}
// 双击上传
function dblclickEventProcess(eventContainerDiv,upload){
eventContainerDiv.addEventListener("dblclick", function(event){
// 触发上一个元素(input file)的点击事件
eventContainerDiv.previousElementSibling.click();
});
}
function clearEventContainerDivImages(eventContainerDiv){
eventContainerDiv.setAttribute("count", "0");
var images = eventContainerDiv.querySelectorAll("img");
for(var i=0;i<images.length;i++){
eventContainerDiv.removeChild(images[i]);
}
}
// 初始化函数
function initialize(){
var imageUploaders = document.querySelectorAll(".imageUploader");
if(imageUploaders && imageUploaders.length > 0){
for(var i=0;i<imageUploaders.length;i++){
var uploader = imageUploaders[i];
// 如果已经初始化过则跳过。
if(uploader.getAttribute("initialized") == "true") continue;
var upload = uploader.getAttribute("upload");
var eventContainerDiv = document.createElement("div");
// 往div里创建一个input file标签,用于双击选择文件上传
var input = document.createElement("input");
input.type = "file";
input.style.display = "none";
input.onchange = function(event){
var evt = window.event || event;
var evtsrc = evt.srcElement || evt.target;
//console.log(evtsrc.parentNode.id);
var imageFile = evtsrc.files[0];
loadImage(imageFile);
};
uploader.appendChild(input);
// 往div里创建两个div,分别作为拖放粘贴双击容器和图片上传后的呈现容器
eventContainerDiv.className = "eventContainerDiv";
eventContainerDiv.contentEditable = true;
eventContainerDiv.innerHTML = "请将图片粘贴或拖拽到此区域,或双击此区域选择图片进行上传.";
// 绑定拖拽事件及处理
dragEventProcess(eventContainerDiv,upload);
// 绑定粘贴事件及处理
pasteEventProcess(eventContainerDiv,upload);
// 绑定双击事件及处理
dblclickEventProcess(eventContainerDiv,upload);
// 添加到容器里
uploader.appendChild(eventContainerDiv);
var imageContainerDiv = document.createElement("div");
imageContainerDiv.className = "imageContainerDiv";
// 添加到容器里
uploader.appendChild(imageContainerDiv);
uploader.setAttribute("initialized", "true");
}
}
}
window.addEventListener("load",function(){
// 在window下设置一个初始化函数,用于可动态地初始化组件(用js动态创建的组件,需要动态初始化)。
window.powerfulImageUploadInitialize = initialize;
powerfulImageUploadInitialize();
},false);
function group(array, subGroupLength) {
let index = 0;
let newArray = [];
while(index < array.length) {
newArray.push(array.slice(index, index += subGroupLength));
}
return newArray;
}
function loadImage(imageFile) {
var canvas = document.createElement(‘canvas‘);
var context = canvas.getContext(‘2d‘);
var reader = new FileReader();
reader.readAsDataURL(imageFile);
reader.onload = function(e){ // reader onload start
var image = new Image();
image.src = e.target.result;
image.onload = function(){ // image onload start
var img_width = this.width;
var img_height = this.height;
// 设置画布尺寸
canvas.width = img_width;
canvas.height = img_height;
// 将图片按像素写入画布
context.drawImage(this, 0, 0, img_width, img_height);
// 读取图片像素信息
var imageData = context.getImageData(0, 0, img_width, img_height);
var colorRows = group(imageData.data, img_width * 4); // 每4个元素表示一个像素的rgba。
imageRGB2Char(colorRows);
}
}
}
function imageRGB2Char(colorRows) {
var html = ‘‘;
console.log(‘colorRows.length:‘, colorRows.length);
for (var x=0; x<colorRows.length; x++) {
html += ‘<div class="pixel-row">‘;
var cells = colorRows[x];
console.log(‘cells.length‘, cells.length);
for (var y=0; y<cells.length; y++) {
if(y%4 === 0){ // 每四个元素为一个像素数据 r,g,b,alpha
// 这里只取rgb,不取a
var rgb = cells[y] + ‘,‘ + cells[y+1] + ‘,‘ + cells[y+2];
// html += ‘<div class="pixel" style="background-color: rgb(‘+ rgb2char(rgb) +‘);"></div>‘;
html += ‘<div class="pixel" style="color: rgb(‘+ rgb +‘);">‘ + rgb2char(rgb) + ‘</div>‘;
}
}
html += ‘</div>‘;
}
document.getElementById(‘imageShow‘).innerHTML = html;
}
function rgb2char(rgb) {
rgb = eval(rgb.replaceAll(‘,‘, ‘+‘));
var charr = ‘‘;
if (rgb >= 722) {
charr = " ";
} else if (rgb >= 684 && rgb < 722) {
charr = ";;";
} else if (rgb >= 646 && rgb < 684) {
charr = "\‘\‘";
} else if (rgb >= 608 && rgb < 646) {
charr = "..";
} else if (rgb >= 570 && rgb < 608) {
charr = ",,";
} else if (rgb >= 532 && rgb < 570) {
charr = "::";
} else if (rgb >= 494 && rgb < 532) {
charr = "tt";
} else if (rgb >= 456 && rgb < 494) {
charr = "rr";
} else if (rgb >= 418 && rgb < 456) {
charr = "ff";
} else if (rgb >= 380 && rgb < 418) {
charr = "kk";
} else if (rgb >= 342 && rgb < 380) {
charr = "ZZ";
} else if (rgb >= 304 && rgb < 342) {
charr = "FF";
} else if (rgb >= 266 && rgb < 304) {
charr = "XX";
} else if (rgb >= 228 && rgb < 266) {
charr = "##";
} else if (rgb >= 190 && rgb < 228) {
charr = "BB";
} else if (rgb >= 152 && rgb < 190) {
charr = "HH";
} else if (rgb >= 114 && rgb < 152) {
charr = "WW";
} else if (rgb >= 76 && rgb < 114) {
charr = "NN";
} else if (rgb >= 38 && rgb < 76) {
charr = "@@";
} else if (rgb >= 0 && rgb < 38) {
charr = "MM";
}
return charr;
}
</script>
</html>
原文:https://www.cnblogs.com/jsper/p/14880774.html