2012-02-04 14 views
5

Hay un par de preguntas similares en SO, pero ninguna de ellas realmente ayudó. Básicamente estoy tratando de cambiar el tamaño de una imagen PNG sencilla, como se ve aquí:Cambio de tamaño de png transparente con la biblioteca de imágenes de Python y el efecto halo

http://media.spiralknights.com/wiki-images/3/3e/Equipment-Proto_Sword_icon.png (desde el MMO Spiral Knights, derechos de autor de tres anillos de Entretenimiento)

que originalmente habían aplicado una utilidad que utiliza estas imágenes en php, y la utilidad de cambio de tamaño allí funcionó perfectamente bien. Usé el método descrito en la página imagecopyresampled en la documentación de PHP.

Honestamente, ni siquiera puedo conseguir que cambie su tamaño en Photoshop, pero los resultados son casi desastrosos en Python. Constantemente obtengo un efecto halo, y creo que esto es al menos en parte a los valores RGBA reales de los píxeles transparentes. A continuación, esta imagen lo dice mejor:

resize examples

(el segundo al último cambio de tamaño era sólo una sugerencia que vi en otro foro para cambiar el tamaño de primero en el doble del tamaño final, y que sirvió de nada al menos un poco, pero no lo suficiente)

La imagen ya está en modo RGBA cuando se está cambiando de tamaño.

Como puede ver, los tamaños de PHP y Photoshop no tienen halo. Honestamente todo menos el tamaño de PHP hace demasiado trabajo, me gusta la paleta mínima en la imagen php (si miras las versiones más grandes puedes ver que el tamaño de PHP usa menos entre colores), pero podría vivir con la forma en que Photoshop ha cambiado el tamaño, o incluso la parte interna del tamaño python, pero el halo es inaceptable.

Me parece, y me corrijo si me equivoco, que PHP y Photoshop parecen saber que no deben usar el color de los píxeles en el canal alfa al interpolar, pero Python usa ese borde claro, que de lo contrario es transparente, en su redimensionamiento.

Desafortunadamente, hay que cambiar el tamaño de muchos iconos diferentes, con perfiles variables, por lo que no son tan simples como este circular, pero este fue el primero que estaba usando mientras experimentaba.

No hay mucho de una pregunta de código en sí mismo, pero si necesita algo para mirar, entonces este es el quid:

>> import Image 
>> img = Image.open('swordorig.png') 
>> img 
<PngImagePlugin.PngImageFile image mode=RGBA size=256x256 at 0x2A3AF58> 
>> img.resize((36,36), Image.ANTIALIAS).save('swordresize.png') 

eventual pregunta ser: ¿existe una manera de contar PIL NO utilice el color de un píxel que tiene un alfa de 0 mientras remuestrea?

+0

No se sabe PIL, pero ¿se intentó utilizar el RGBa (no RGBA) para indicarle que considere la imagen premultiplicada alfa? – rotoglup

+1

No lo había hecho, ¡así que gracias por la sugerencia! Desafortunadamente, parece que PIL no puede escribir RGBa como png. "IOError: no se puede escribir el modo RGBa como PNG" – cogs

+0

Si le gusta el resultado Bicúbico de Photoshop, tal vez 'Image.BICUBIC' o' Image.NEAREST' será mejor? http://pastebin.com/VRBKWZUh – reclosedev

Respuesta

6

Gracias a todos por responder! Y especialmente a Rotoglup por decirme el término para lo que realmente estaba buscando. Repasando las páginas de desbordamiento de pila para alfa premultiplicado en PIL, encontré una solución que funciona; aquí es una hoja actualizada de los gráficos de cambio de tamaño:

resize sheet 2

Las barras grises son sólo para dar una impresión de lo que se vería en un fondo más claro.

https://stackoverflow.com/a/6882161/1189554

Gracias a madlag

Así que mi código termina pareciéndose a esto:

>> import Image, numpy 
>> img = Image.open('swordorig.png') 
>> premult = numpy.fromstring(img.tostring(), dtype=numpy.uint8) 
>> alphaLayer = premult[3::4]/255.0 
>> premult[::4] *= alphaLayer 
>> premult[1::4] *= alphaLayer 
>> premult[2::4] *= alphaLayer 
>> img = Image.fromstring("RGBA", img.size, premult.tostring()) 
>> img.resize((36,36), Image.ANTIALIAS).save('swordresize.png') 

y se obtiene el icono que se encuentra en la parte inferior de la hoja. Todavía hay más colores que la versión de PHP, y un anillo muy suave, pero en general mucho, mucho más agradable. Estoy seguro de que el algoritmo podría modificarse para mejorarlo aún más. ¡Gracias de nuevo a todos por responder!

Cuestiones relacionadas