Decir 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 resulta en una imagen de la tamaño exacto yo especifica en píxeles.

Sin eje, sin títulos. Sólo la imagen. No me importa personalmente los inhaladores de polvo seco, ya que solo me quiere para especificar el tamaño de la imagen en la pantalla en el disco en píxeles.

He leído otros hilos, y todos ellos parecen hacer conversiones de pulgadas y, a continuación, especifique las dimensiones de la figura en pulgadas y ajustar los dpi en alguna manera. Me gustaría evitar lidiar con la posible pérdida de precisión que podrían resultar de pixel-a-pulgadas de conversiones.

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 la anchura y la altura debe ser cada uno por debajo de 32768 (?))

De todo lo que he visto, matplotlib requiere la figura de tamaño especificado en inches y dpi, pero yo sólo estoy interesado en los píxeles la figura tiene en el disco. ¿Cómo puedo hacer esto?

Para aclarar: estoy buscando una manera de hacer esto con matplotlib, y no con el resto de imágenes de ahorro de las bibliotecas.

  • Con matplotlib, no es posible establecer la figura de tamaño directamente en pulgadas.
  • Me refería en píxeles…

3 Comentarios

  1. 137

    Matplotlib no trabajo con píxeles directamente, sino tamaños físicos y DPI. Si desea mostrar una figura con un determinado tamaño de píxel, usted necesita saber el DPI de tu monitor. Por ejemplo en este enlace detectará que para usted.

    Si usted tiene una imagen de 3841×7195 píxeles es poco probable que el monitor va a ser de ese tamaño, por lo que no será capaz de mostrar una figura de ese tamaño (matplotlib requiere de la figura para que quepa en la pantalla, si usted pide un tamaño demasiado grande se encoge al tamaño de la pantalla). Vamos a imaginar que queremos un 800×800 píxeles de la imagen sólo para dar un ejemplo. He aquí cómo mostrar una 800×800 píxeles de la imagen en mi monitor (my_dpi=96):

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

    Así que, básicamente, solo hay que dividir las dimensiones en pulgadas por su DPI.

    Si desea guardar una figura de un tamaño específico, es una cuestión diferente. La pantalla Ips no son tan importantes ya (a menos que usted pida una figura que no quepan en la pantalla). Utilizando el mismo ejemplo de la 800×800 píxeles de la figura, podemos guardarlo en diferentes resoluciones mediante las dpi palabra clave de savefig. Para guardarlo en la misma resolución que la pantalla, utilizar el mismo dpi:

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

    Para guardarlo como un 8000×8000 píxeles de la imagen, utilice un dpi 10 veces más grande:

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

    Tenga en cuenta que la configuración de los DPI no es compatible con todos los motores. Aquí, el formato PNG de motor se utiliza, pero el pdf y ps motores implementará el tamaño de forma diferente. También, cambiar los DPI y tamaños afectará también a cosas como fontsize. Una mayor DPI mantendrá el mismo tamaño relativo de las fuentes y los elementos, pero si quieres fuentes más pequeñas para una figura más grande de la necesidad de aumentar el tamaño físico en lugar de los DPI.

    Volviendo a tu 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)

    Nota que he utilizado la figura de dpi de 100 para caber en la mayoría de las pantallas, pero guarda con dpi=1000 para lograr la resolución requerida. En mi sistema, esto produce un png con 3840×7190 píxeles — parece que el DPI guardado siempre es de 0.02 píxeles/pulgada más pequeño que el valor seleccionado, el cual tendrá un pequeño efecto en los grandes tamaños de la imagen. Más de alguna discusión de este aquí.

    • Es útil recordar que los tamaños de monitor (y por lo tanto estándar del navegador y una interfaz de usuario tamaños de ventana) están normalmente en términos de 96 dpi – múltiplos de 96. De repente números como 1440 píxeles son significativas (15 pulgadas) cuando el pensamiento de como esta.
    • No podía conseguir que esto funcione, pasando figsize a plt.figure. La solución fue hacer como las otras respuestas sugieren y después de llamar a esto sin figsize, a continuación, llamar fig.set_size_inches(w,h)
    • Docs para figure y savefig.
    • El enlace no mostrar el valor correcto para el Apple Thunderbolt Display.
    • Me gusta esta solución, pero tengo una advertencia. El tamaño de texto escalas inversamente ppp. (Mi sistema es el MacBook Pro, mac OS X), de modo interactivo de impresión haciendo el dpi a grandes (como 10*my_dpi) se reduce el texto a cerca de la invisibilidad.
    • Lo que si se ejecuta el código en una cabeza de servidor o de otro decapitado medio ambiente, y otros se ejecuta el código en diferentes entornos?
    • Si se ejecuta en una cabeza servidor no hay ninguna restricción de la figura de ajuste en la pantalla. El único límite es que no puede tener más de 2^16 píxeles en cada dimensión. Por lo que necesita para asegurarse de que los tamaños de los tiempos de DPI están a menos de 2^16. Si los demás ejecutar el código en diferentes entornos, sólo asegúrese de que todas tienen el mismo DPI y las figuras deben ser consistentes.

  2. 15

    Esto funcionó para mí, basado en su código, generando un 93Mb imagen png con el 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 la última PIP versiones de Python 2.7 bibliotecas en Linux Mint 13.

    Espero que ayude!

    • Configuración de un muy bajo nivel de dpi significa que las fuentes no será visible, a no ser muy grandes tamaños de fuente se utiliza de forma explícita.
    • Es probablemente mejor para establecer un mayor dpi y dividir su pulgadas de tamaño (que es arbitrario de todos modos) por que los dpi. Aparte de eso, su instalación no produce una exacta píxel a píxel de reproducción, gracias !
    • Estoy tratando de utilizar este antes de guardar las imágenes con elementos de la trama en él (círculos, líneas, …). Esto perturba la anchura de línea, de manera que los elementos son apenas visibles.
  3. 4

    Basado en la respuesta aceptado por tiago, aquí es una pequeña función genérica que las exportaciones de una colección de la matriz de una imagen con la misma resolución que la matriz:

    import matplotlib.pyplot as plt
    import numpy as np
    
    def export_figure_matplotlib(arr, f_name, dpi=200, resize_fact=1, plt_show=False):
        """
        Export array as figure in original resolution
        :param arr: array of image to save in original resolution
        :param f_name: name of file where to save figure
        :param resize_fact: resize facter wrt shape of arr, in (0, np.infty)
        :param dpi: dpi of your screen
        :param plt_show: show plot or not
        """
        fig = plt.figure(frameon=False)
        fig.set_size_inches(arr.shape[1]/dpi, arr.shape[0]/dpi)
        ax = plt.Axes(fig, [0., 0., 1., 1.])
        ax.set_axis_off()
        fig.add_axes(ax)
        ax.imshow(arr)
        plt.savefig(f_name, dpi=(dpi * resize_fact))
        if plt_show:
            plt.show()
        else:
            plt.close()

    Como se ha dicho en la respuesta anterior por tiago, el DPI de la pantalla tiene que ser encontrado en primer lugar, que se puede hacer aquí, por ejemplo: http://dpi.lv

    He añadido un argumento adicional resize_fact en la función que la que puede exportar la imagen a un 50% (0,5) de la resolución original, por ejemplo.

Dejar respuesta

Please enter your comment!
Please enter your name here