ImageToHTML - це онлайн сервіс який дозволяє перетворити зображення у HTML код, без візуальної втрати якості зображення.
Ідея створити ImageToHTML виникла при читані інформації про Pixel art (Піксельна графіка).
Замінити зображення на HTML елемент де кожен елемент має ширину і висоту 1 піксель з вказаним кольором - що замінює 1 піксель у картинці.
Для отримання кольору піксель у зображенні у JavaScript можна за допомогою метода CanvasRenderingContext2D.getImageData(), попередньо намалювавши зображення на полотні canvas методом CanvasRenderingContext2D.drawImage().
<canvas id="canva"></canvas>
<input id="open_file" type="file">
document.querySelector('#open_file').onchange=function(){
f=new FileReader();
f.onload=function(){
var img=document.createElement("img");
img.onload=function(){
var canvas=document.querySelector('#canva');
var ctx=canvas.getContext('2d');
canvas.width=img.width;
canvas.height=img.height;
ctx.drawImage(this,0,0);
document.querySelector('#result_html').value='';
}
img.src=this.result;
}
f.readAsDataURL(this.files[0]);
};
Перше представлення HTML коду було наступним (зображення 2*2 пікселя):
<div style="width:2px;height:2px;">
<div>
<div style="width:1px; height:1px; display:inline-block; background-color: red;"></div><div style="width:1px; height:1px; display:inline-block; background-color: red;"></div>
</div>
<div>
<div style="width:1px; height:1px; display:inline-block; background-color:black;"></div><div style="width:1px; height:1px; display:inline-block; background-color:black"></div>
</div>
</div>
Звісно цей код потрібно оптимізувати використавши класи і CSS стилі.
У зображенні кольори часто повторюються тому створювати клас для кожного пікселя не доцільно. Тому для кожного кольору який може бути у декілька пікселів створюється лише один клас. Наприклад: c0 - для червоного кольору, c1 - для чорного.
<style>.pixel{width:1px; height:1px; display:inline-block;}
.c0{background-color: red;}
.c1{background-color: black;}
</style>
<div style="width:2px;height:2px;">
<div><div class="pixel c0"></div><div class="pixel c0"></div></div>
<div><div class="pixel c1"></div><div class="pixel c1"></div></div>
</div>
Функція CanvasToHTML проходить все полотно елемента canvas по пікселях і створює HTML код для кожного пікселя.
function CanvasToHTML(canvas){
var ctx=canvas.getContext('2d');
var s='<div style="width:'+canvas.width+'px;height:'+canvas.height+'px;">', style='', colors=[];
for(var y=0,i,c;y<canvas.height;y++){
s+='<div class="line_pixel">';
for(var x=0,imgData;x<canvas.width;x++){
imgData=ctx.getImageData(x,y,1,1);
c='rgba('+imgData.data[0]+','+imgData.data[1]+','+imgData.data[2]+','+(imgData.data[3]==0?'0':255/imgData.data[3])+')';
i=colors.indexOf(c);
if(i==-1){
colors.push(c);
i=colors.length-1;
style+='.c'+i+'{background-color:'+c+'}';
}
s+='<div class="pixel c'+i+'"></div>';
}
s+='</div>\n';
}
s+='</div>';
return '<style>.line_pixel{display: block;}.pixel{display:inline-block;width:1px;height:1px;}\n'+style+'\n</style>\n'+s;
}
document.getElementById('test').value=CanvasToHTML(document.getElementById('canva')); //виклик функції
Звичайно що отриманий HTML код є дуже великим, особливо при великих зображеннях.
Також часто у зображеннях один колір може займати декілька пікселів підряд, тому вказавши ширину одного елемента наприклад 4 пікселя ми цим самим одним елементом замінюємо 4 пікселя. Це дає змогу ще більш зменшити HTML код в розмірах.
<style>.pixel{width:1px; height:1px; display:inline-block;}
.c0{background-color: red;}
.c1{background-color: black;}
</style>
<div style="width:2px;height:2px;">
<div><div class="pixel c0" style="width:2px"></div></div>
<div><div class="pixel c1" style="width:2px"></div></div>
</div>
Функція CanvasToHTMLMax проходить все полотно елемента canvas по пікселях і створює HTML код для кожного пікселя, враховуючи ширину що колір може займати не один піксель в лінії. Це дозволяє сутєво сменшити HTML код, особливо для картинок де однотоний фон тощо.
function CanvasToHTMLMax(canvas){
var s='<div style="width:'+canvas.width+'px;height:'+canvas.height+'px;">', style='', colors=[];
for(var y=0,i0=-1,w=0,i,c;y<canvas.height;y++){
s+='<div class="line_pixel">';
for(var x=0,imgData;x<canvas.width;x++){
imgData=ctx.getImageData(x,y,1,1);
c='rgba('+imgData.data[0]+','+imgData.data[1]+','+imgData.data[2]+','+(imgData.data[3]==0?'0':255/imgData.data[3])+')';
i=colors.indexOf(c);
if(i==-1){
colors.push(c);
i=colors.length-1;
style+='.c'+i+'{background-color:'+c+'}';
}
if(i0==-1)i0=i;
if(i0==i){
w++;
}
else{
if(w==1)
s+='<div class="pixel c'+i0+'"></div>';
else s+='<div class="pixel c'+i0+'" style="width:'+w+'px"></div>';
w=1;
i0=i;
}
}
if(i0==i)s+='<div class="pixel c'+i+'" style="width:'+w+'px"></div>';
i0=-1;
w=0;
s+='</div>\n';
}
s+='</div>';
return '<style>.line_pixel{display: block;}.pixel{display:inline-block;width:1px;height:1px;}\n'+style+'\n</style>\n'+s;
}
document.getElementById('test2').value=CanvasToHTMLMax(document.getElementById('canva')); //виклик функції