2011-02-02 12 views
7

Tengo un mapa de bits 16x16 y quiero crear un SVG que contenga 16x16 cuadrados con los colores de los píxeles de la imagen. ¿Hay alguna manera fácil de lograr esto?¿Cómo crear una imagen SVG `pixelizada 'desde un mapa de bits?

Mis pensamientos actuales van en la dirección de usar Python y PIL para leer la imagen de mapa de bits y crear dinámicamente un archivo de imagen SVG con los objetos correspondientes. Pero esto se siente un poco torpe y como reinventar la rueda.

¿Hay una mejor manera de hacerlo?

+0

Acabo de hackear una secuencia de comandos de Python utilizando PIL para lograr mis objetivos, pero la pregunta sigue siendo, por supuesto. Si a alguien le importa, puedo publicarlo aquí. – hochl

+0

Por cierto, el término formal para "pixelizar" es "ráster". – Mehrdad

+0

No en este caso, ya que quiere una imagen vectorial como salida. – Amicable

Respuesta

23

Si no necesita que la salida sea SVG, le sugiero que utilice un lienzo HTML5 donde puede muestrear los píxeles de la imagen del lado del cliente (usando getImageData() en el contexto) y luego dibujar su propia escala ascendente imagen. O bien, si necesita SVG, puede usar Canvas para el muestreo de imágenes y luego usar elementos <rect/> creados en procedimientos en SVG para cada píxel.

He escrito an example using just HTML Canvas para que pueda ver cómo hacerlo. En resumen:

function drawPixelated(img,context,zoom,x,y){ 
    if (!zoom) zoom=4; if (!x) x=0; if (!y) y=0; 
    if (!img.id) img.id = "__img"+(drawPixelated.lastImageId++); 
    var idata = drawPixelated.idataById[img.id]; 
    if (!idata){ 
    var ctx = document.createElement('canvas').getContext('2d'); 
    ctx.width = img.width; 
    ctx.height = img.height; 
    ctx.drawImage(img,0,0); 
    idata = drawPixelated.idataById[img.id] = ctx.getImageData(0,0,img.width,img.height).data; 
    } 
    for (var x2=0;x2<img.width;++x2){ 
    for (var y2=0;y2<img.height;++y2){ 
     var i=(y2*img.width+x2)*4; 
     var r=idata[i ]; 
     var g=idata[i+1]; 
     var b=idata[i+2]; 
     var a=idata[i+3]; 
     context.fillStyle = "rgba("+r+","+g+","+b+","+(a/255)+")"; 
     context.fillRect(x+x2*zoom, y+y2*zoom, zoom, zoom); 
    } 
    } 
}; 
drawPixelated.idataById={}; 
drawPixelated.lastImageId=0; 

Si realmente necesita SVG involucrados, estaría feliz de escribir un ejemplo que genera dinámicamente eso.

Editar: OK, he creado an SVG version solo por diversión y práctica. :)

Como acotación al margen (de una mala lectura inicial de su pregunta) this demo file from ASVG3 su antiguo SVG Examples Page muestra cómo utilizar algunas de composición compleja de muchos efectos diferentes para crear pixelación en los datos vectoriales arbitrarios. Lamentablemente, la demostración no se carga en Chrome, ya que se ha cableado para requerir el (ahora descontinuado) Adobe SVG Viewer.

+0

Su demostración funcionó perfectamente en Chrome, pero no en absoluto en Firefox 3.6 – Neddy

+0

@Neddy, ¿qué demostración, la demo de canvas o la demo de SVG? Ambos funcionan bien para mí en FF 3.6.13/Win 7x64 (y Chrome v8 y Safari v5) – Phrogz

+0

La demo de SVG, la demostración de lienzo también funcionó bien en ambos. – Neddy

Cuestiones relacionadas