一个有趣的程序。
主要技术包含图片拖拽、粘贴、双击上传,然后通过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