假设我有一个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,而不是其他图像保存库。
此解决方案适用于matplotlib 3.0.1、3.0.3和3.2.1版本。
def save_inp_as_output(_img, c_name, dpi=100):
h, w, _ = _img.shape
fig, axes = plt.subplots(figsize=(h/dpi, w/dpi))
fig.subplots_adjust(top=1.0, bottom=0, right=1.0, left=0, hspace=0, wspace=0)
axes.imshow(_img)
axes.axis('off')
plt.savefig(c_name, dpi=dpi, format='jpeg')
因为subplots_adjust设置使轴填充图形,所以您不希望指定bbox_inch ='tight',因为在本例中它实际上创建了空白填充。当你有多个子情节时,这个解决方案也适用。
这为我工作,基于你的代码,生成一个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版本。
希望有帮助!
OP希望保留1:1的像素数据。作为一名研究科学图像的天文学家,我不允许对图像数据进行任何插值,因为这会引入未知和不可预测的噪声或错误。例如,下面是通过pyplot.savefig()保存的480x480图像片段:
matplotlib重新采样的像素的细节大致为2x2,但请注意1x2像素的列
你可以看到大多数像素只是翻了一番(所以1x1像素变成了2x2),但一些列和行变成了每像素1x2或2x1,这意味着原始的科学数据已经被改变了。
正如Alka所暗示的那样,plt.imsave()将实现OP所要求的内容。假设你有图像数据存储在图像数组im,然后一个可以这样做
plt.imsave(fname='my_image.png', arr=im, cmap='gray_r', format='png')
在这个例子中,文件名有“png”扩展名(但你仍然必须指定format='png'的格式,就我所知),图像数组是arr,我们选择了反向灰度“gray_r”作为颜色映射。我通常添加vmin和vmax来指定动态范围,但这些是可选的。
最终结果是一个png文件,其像素尺寸与im数组完全相同。
注意:OP指定没有轴等,这就是这个解决方案所做的。如果想要添加轴、刻度等,我更喜欢的方法是在一个单独的图上做,保存为transparent=True (PNG或PDF),然后将后者覆盖在图像上。这保证了您保持原始像素的完整性。
此解决方案适用于matplotlib 3.0.1、3.0.3和3.2.1版本。
def save_inp_as_output(_img, c_name, dpi=100):
h, w, _ = _img.shape
fig, axes = plt.subplots(figsize=(h/dpi, w/dpi))
fig.subplots_adjust(top=1.0, bottom=0, right=1.0, left=0, hspace=0, wspace=0)
axes.imshow(_img)
axes.axis('off')
plt.savefig(c_name, dpi=dpi, format='jpeg')
因为subplots_adjust设置使轴填充图形,所以您不希望指定bbox_inch ='tight',因为在本例中它实际上创建了空白填充。当你有多个子情节时,这个解决方案也适用。