Especificar y guardar una figura con el tamaño exacto en píxeles

Resuelto Amelio Vazquez-Reina asked hace 12 años • 9 respuestas

Digamos que tengo una imagen de tamaño 3841 x 7195 píxeles. Me gustaría guardar el contenido de la figura en el disco, lo que da como resultado una imagen del tamaño exacto que especifico en píxeles.

Sin ejes, sin títulos. Sólo la imagen. Personalmente, no me importan los DPI, ya que solo quiero especificar el tamaño que toma la imagen en la pantalla en el disco en píxeles. .

He leído otros hilos y todos parecen hacer conversiones a pulgadas y luego especificar las dimensiones de la figura en pulgadas y ajustar los ppp de alguna manera. Me gustaría evitar tener que lidiar con la posible pérdida de precisión que podría resultar de las conversiones de píxeles a pulgadas.

Lo he probado con:

w = 7195
h = 3841
fig = plt.figure(frameon=False)
fig.set_size_inches(w,h)
ax = plt.Axes(fig, [0., 0., 1., 1.])
ax.set_axis_off()
fig.add_axes(ax)
ax.imshow(im_np, aspect='normal')
fig.savefig(some_path, dpi=1)

sin suerte (Python se queja de que el ancho y el alto deben estar por debajo de 32768 (?))

Por todo lo que he visto, matplotlibrequiere especificar el tamaño de la figura en inchesy dpi, pero solo me interesan los píxeles que ocupa la figura en el disco. ¿Cómo puedo hacer esto?

Para aclarar: estoy buscando una manera de hacer esto con matplotliby no con otras bibliotecas para guardar imágenes.

Amelio Vazquez-Reina avatar Dec 05 '12 07:12 Amelio Vazquez-Reina
Aceptado

Matplotlib no funciona con píxeles directamente, sino con tamaños físicos y DPI. Si desea mostrar una figura con un tamaño de píxel determinado, necesita conocer el DPI de su monitor. Por ejemplo este enlace lo detectará por usted.

Si tiene una imagen de 3841x7195 píxeles, es poco probable que su monitor sea tan grande, por lo que no podrá mostrar una figura de ese tamaño (matplotlib requiere que la figura quepa en la pantalla, si solicita un tamaño demasiado grande, se reducirá al tamaño de la pantalla). Imaginemos que desea una imagen de 800x800 píxeles solo como ejemplo. A continuación se explica cómo mostrar una imagen de 800 x 800 píxeles en mi monitor ( my_dpi=96):

plt.figure(figsize=(800/my_dpi, 800/my_dpi), dpi=my_dpi)

Básicamente, simplemente divides las dimensiones en pulgadas por tu DPI.

Si desea guardar una figura de un tamaño específico, entonces es un asunto diferente. Los DPI de pantalla ya no son tan importantes (a menos que solicites una cifra que no quepa en la pantalla). Usando el mismo ejemplo de la figura de 800x800 píxeles, podemos guardarla en diferentes resoluciones usando la dpipalabra clave de savefig. Para guardarlo en la misma resolución que la pantalla simplemente use el mismo ppp:

plt.savefig('my_fig.png', dpi=my_dpi)

Para guardarlo como una imagen de 8000x8000 píxeles, utilice un ppp 10 veces mayor:

plt.savefig('my_fig.png', dpi=my_dpi * 10)

Tenga en cuenta que la configuración de DPI no es compatible con todos los servidores. Aquí, se utiliza el backend PNG, pero los backends pdf y ps implementarán el tamaño de manera diferente. Además, cambiar el DPI y los tamaños también afectará cosas como el tamaño de fuente. Un DPI más grande mantendrá los mismos tamaños relativos de fuentes y elementos, pero si desea fuentes más pequeñas para una figura más grande, debe aumentar el tamaño físico en lugar del DPI.

Volviendo a su ejemplo, si desea guardar una imagen con 3841 x 7195 píxeles, puede hacer lo siguiente:

plt.figure(figsize=(3.841, 7.195), dpi=100)
( your code ...)
plt.savefig('myfig.png', dpi=1000)

Tenga en cuenta que utilicé la cifra de 100 ppp para que quepa en la mayoría de las pantallas, pero la guardé dpi=1000para lograr la resolución requerida. En mi sistema, esto produce un png con 3840x7190 píxeles; parece que el DPI guardado es siempre 0,02 píxeles/pulgada más pequeño que el valor seleccionado, lo que tendrá un (pequeño) efecto en tamaños de imagen grandes. Un poco más de discusión sobre esto aquí .

tiago avatar Dec 05 '2012 01:12 tiago

Esto funcionó para mí, según su código, generando una imagen png de 93 Mb con ruido de color y las dimensiones deseadas:

import matplotlib.pyplot as plt
import numpy

w = 7195
h = 3841

im_np = numpy.random.rand(h, w)

fig = plt.figure(frameon=False)
fig.set_size_inches(w,h)
ax = plt.Axes(fig, [0., 0., 1., 1.])
ax.set_axis_off()
fig.add_axes(ax)
ax.imshow(im_np, aspect='normal')
fig.savefig('figure.png', dpi=1)

Estoy usando las últimas versiones PIP de las bibliotecas Python 2.7 en Linux Mint 13.

¡Espero que ayude!

heltonbiker avatar Dec 05 '2012 01:12 heltonbiker