假设我有一个3841 x 7195像素的图像。我想将图形的内容保存到磁盘,从而得到与我指定的像素大小完全相同的图像。
没有轴,没有标题。只是图像而已。我个人并不关心dpi,因为我只想指定图像在屏幕上磁盘上的大小,单位是像素。
我读过其他的线程,它们似乎都做了英寸的转换,然后以英寸为单位指定图形的尺寸,并以某种方式调整dpi。我希望避免处理像素到英寸转换可能导致的潜在精度损失。
我尝试过:
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)
with no luck (Python抱怨width和height必须都小于32768 (?))
从我所看到的一切来看,matplotlib要求图形大小以英寸和dpi为单位指定,但我只对图形在磁盘上占用的像素感兴趣。我该怎么做呢?
澄清一下:我正在寻找一种方法来使用matplotlib,而不是其他图像保存库。
基于tiago接受的响应,下面是一个小的通用函数,它将numpy数组导出到与数组具有相同分辨率的图像:
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()
正如tiago在之前的回复中所说,需要首先找到屏幕DPI,可以在这里完成,例如:http://dpi.lv
我在函数中添加了一个额外的参数resize_fact,例如,你可以将图像导出到原始分辨率的50%(0.5)。
我也有同样的问题。我使用PIL Image加载图像并转换为numpy数组,然后使用matplotlib修补一个矩形。这是一个jpg图像,所以我没有办法从PIL img.info['dpi']得到dpi,所以接受的解决方案不适合我。但经过一些修补,我想出了保存数字与原来的大小相同的方法。
我在这里添加了下面的解决方案,认为它会帮助那些和我有同样问题的人。
import matplotlib.pyplot as plt
from PIL import Image
import numpy as np
img = Image.open('my_image.jpg') #loading the image
image = np.array(img) #converting it to ndarray
dpi = plt.rcParams['figure.dpi'] #get the default dpi value
fig_size = (img.size[0]/dpi, img.size[1]/dpi) #saving the figure size
fig, ax = plt.subplots(1, figsize=fig_size) #applying figure size
#do whatver you want to do with the figure
fig.tight_layout() #just to be sure
fig.savefig('my_updated_image.jpg') #saving the image
这将以与原始图像相同的分辨率保存图像。
以防你没有使用jupyter笔记本。dpi可以通过以下方式获取。
figure = plt.figure()
dpi = figure.dpi
这为我工作,基于你的代码,生成一个93Mb的png图像与彩色噪声和所需的尺寸:
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)
我使用的是Linux Mint 13中Python 2.7库的最新PIP版本。
希望有帮助!