Matplotlib - unable to save image in same resolution as original image

后端 未结 1 1314
野的像风
野的像风 2020-12-05 03:27

I am unable to save the image without the white borders and at the initial resolution (1037x627)

import numpy as np
import matplotlib.pyplot as          


        
相关标签:
1条回答
  • 2020-12-05 04:17

    There are two factors at play here:

    1. An Axes doesn't take up the entire Figure by default
    2. In matplotlib, the Figure's size is fixed, and the contents are stretched/squeezed/interpolated to fit the figure. You want the Figure's size to be defined by its contents.

    To do what you want to do, there are three steps:

    1. Create a figure based on the size of the image and a set DPI
    2. Add a subplot/axes that takes up the entire figure
    3. Save the figure with the DPI you used to calculate figure's size

    Let's use a random Hubble image from Nasa http://www.nasa.gov/sites/default/files/thumbnails/image/hubble_friday_12102015.jpg. It's a 1280x1216 pixel image.

    Here's a heavily commented example to walk you through it:

    import matplotlib.pyplot as plt
    
    # On-screen, things will be displayed at 80dpi regardless of what we set here
    # This is effectively the dpi for the saved figure. We need to specify it,
    # otherwise `savefig` will pick a default dpi based on your local configuration
    dpi = 80
    
    im_data = plt.imread('hubble_friday_12102015.jpg')
    height, width, nbands = im_data.shape
    
    # What size does the figure need to be in inches to fit the image?
    figsize = width / float(dpi), height / float(dpi)
    
    # Create a figure of the right size with one axes that takes up the full figure
    fig = plt.figure(figsize=figsize)
    ax = fig.add_axes([0, 0, 1, 1])
    
    # Hide spines, ticks, etc.
    ax.axis('off')
    
    # Display the image.
    ax.imshow(im_data, interpolation='nearest')
    
    # Add something...
    ax.annotate('Look at This!', xy=(590, 650), xytext=(500, 500),
                color='cyan', size=24, ha='right',
                arrowprops=dict(arrowstyle='fancy', fc='cyan', ec='none'))
    
    # Ensure we're displaying with square pixels and the right extent.
    # This is optional if you haven't called `plot` or anything else that might
    # change the limits/aspect.  We don't need this step in this case.
    ax.set(xlim=[-0.5, width - 0.5], ylim=[height - 0.5, -0.5], aspect=1)
    
    fig.savefig('test.jpg', dpi=dpi, transparent=True)
    plt.show()
    

    The saved test.jpg will be exactly 1280x1216 pixels. Of course, because we're using a lossy compressed format for both input and output, you won't get a perfect pixel match due to compression artifacts. If you used lossless input and output formats you should, though.

    0 讨论(0)
提交回复
热议问题