当前位置: 首页 > 知识库问答 >
问题:

指定并保存以像素为单位的精确大小的图形

赫连宏伯
2023-03-14

假设我有一个大小为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)

运气不佳(Python抱怨宽度和高度必须都低于32768(?)

从我所看到的一切来看,matplotlib要求图形大小以inchesdpi为单位指定,但我只对图形在磁盘中的像素感兴趣。我该怎么做?

澄清一下:我正在寻找一种使用matplotlib实现这一点的方法,而不是使用其他图像保存库。

共有3个答案

班承德
2023-03-14

OP希望保留1:1的像素数据。作为一名处理科学图像的天文学家,我不能允许对图像数据进行任何插值,因为它会引入未知和不可预测的噪声或错误。例如,下面是通过pyplot保存的480x480图像的片段。savefig():matplotlib重采样为大约2x2的像素细节,但请注意1x2像素列

你可以看到大多数像素被简单地加倍了(所以1x1像素变成了2x2),但是一些列和行变成了1x2或2x1每像素,这意味着原始的科学数据已经被改变了。

正如阿尔卡所暗示的,plt。imsave()将实现OP的要求。假设图像数据存储在图像数组im中,则可以执行以下操作

plt.imsave(fname='my_image.png', arr=im, cmap='gray_r', format='png')

在本例中,文件名具有png扩展名(但据我所知,您仍然必须指定格式='png'),图像数组是arr,我们选择倒灰度gray_r作为颜色图。我通常添加vmin和vmax来指定动态范围,但这些都是可选的。

最终结果是一个png文件,其像素尺寸与im阵列完全相同。

注意:OP没有指定轴等,这正是此解决方案所做的。如果要添加轴、记号等,我首选的方法是在单独的绘图上添加,使用transparent=True(PNG或PDF)保存,然后将后者覆盖在图像上。这保证了原始像素的完整性。

常元章
2023-03-14

根据您的代码,这对我来说很有效,生成了一个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)

我使用的是LinuxMint13中Python 2.7库的最后一个PIP版本。

希望有帮助!

方宏才
2023-03-14

Matplotlib不直接处理像素,而是处理物理尺寸和DPI。如果要显示具有特定像素大小的图形,需要知道显示器的DPI。例如,此链接将为您检测。

如果您的图像为3841x7195像素,则显示器不太可能如此大,因此您将无法显示该尺寸的图形(matplotlib要求图形适合屏幕,如果您要求的尺寸太大,它将缩小到屏幕尺寸)。假设您想要一张800x800像素的图像作为示例。以下是如何在我的显示器上显示800x800像素的图像(my_dpi=96):

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

所以你基本上只是用英寸除以你的DPI。

如果你想保存一个特定尺寸的图形,那就另当别论了。屏幕DPI不再那么重要了(除非你要求一个不适合屏幕的数字)。使用800x800像素图形的相同示例,我们可以使用Savefigdpi关键字以不同的分辨率保存它。要以与屏幕相同的分辨率保存它,只需使用相同的dpi:

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

要将其保存为8000x8000像素的图像,请使用10倍大的dpi:

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

请注意,并非所有后端都支持DPI的设置。这里使用了PNG后端,但是pdf和ps后端实现的大小不同。此外,更改DPI和大小也会影响字体大小等内容。较大的DPI将保持字体和元素的相对大小相同,但是如果您希望较大的图形使用较小的字体,您需要增加物理大小而不是DPI。

回到您的示例,如果您想保存3841 x 7195像素的图像,您可以执行以下操作:

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

请注意,我使用100的数字dpi来适应大多数屏幕,但用dpi=1000保存以实现所需的分辨率。在我的系统中,这会产生一个3840x7190像素的png——似乎保存的DPI总是比选定的值小0.02像素/英寸,这将对大图像尺寸产生(小)影响。这里有更多的讨论。

 类似资料:
  • 问题内容: 给定matplotlib中的一组轴,是否有办法确定其像素大小?我需要根据调整大小来调整大小,以适应更大或更小的数字。 (特别是我想更改线宽,使其与轴的大小成比例。) 问题答案: 这给出了以英寸为单位的宽度和高度。 这可能足以满足您的目的,但是要获得像素,可以乘以: 例如, 要制作与该图形大小完全相同的图像,必须删除图形与轴之间的空格:

  • 问题内容: 我希望找到如何获取OracleDB中结果集的kb大小。我不是系统管理员,但是经常运行返回超过10万行的查询,因此我需要找到一种确定总kb大小的方法。谢谢你 问题答案: 在SQL * Plus中: 要使用AUTOTRACE,需要PLUSTRACE角色,默认情况下不会授予该角色。了解更多。

  • 我正在创建一个将在所有Android设备上运行的应用程序。我想为我的应用程序创建xhdpi图形。我的应用是全屏的。我在创建图形时很困惑。有没有人可以告诉我,我的背景图像的最佳大小像素。 例如: null

  • 本文向大家介绍java精度计算代码 java指定精确小数位,包括了java精度计算代码 java指定精确小数位的使用技巧和注意事项,需要的朋友参考一下 本文实例为大家分享了java指定精确小数位的具体代码,供大家参考,具体内容如下 java代码: 控制台: 以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持呐喊教程。

  • 本文向大家介绍jquery精度计算代码 jquery指定精确小数位,包括了jquery精度计算代码 jquery指定精确小数位的使用技巧和注意事项,需要的朋友参考一下 本文实例为大家分享了jquery指定精确小数位的具体代码,供大家参考,具体内容如下 页面显示: 以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持呐喊教程。

  • 问题内容: 我有一个对象。我使用将对象编码为json 。 我怎样才能测量json字符串的大小? 问题答案: 并且不公开也不维护写入字节数。 一种方法是先使用内置函数将其编入其长度来封送该值。您要查找的位数是长度乘以8(1字节为8位)。之后,您必须手动将字节片写入输出中。对于小型类型,这不是问题,但是对于大型结构/值,可能是不希望的。另外,也没有必要的工作将其编组,获取其长度并手动编写切片。 一种更