2014-09-06 72 views

回答

7

另一种方法是使用pypng。你仍然需要安装另一个软件包,但它是纯Python,所以应该很简单。 (实际上有一个在pypng源用Cython文件,但它的使用是可选的。)

下面是使用pypng到numpy的阵列写入PNG的示例:

import png 

import numpy as np 

# The following import is just for creating an interesting array 
# of data. It is not necessary for writing a PNG file with PyPNG. 
from scipy.ndimage import gaussian_filter 


# Make an image in a numpy array for this demonstration. 
nrows = 240 
ncols = 320 
np.random.seed(12345) 
x = np.random.randn(nrows, ncols, 3) 

# y is our floating point demonstration data. 
y = gaussian_filter(x, (16, 16, 0)) 

# Convert y to 16 bit unsigned integers. 
z = (65535*((y - y.min())/y.ptp())).astype(np.uint16) 

# Use pypng to write z as a color PNG. 
with open('foo_color.png', 'wb') as f: 
    writer = png.Writer(width=z.shape[1], height=z.shape[0], bitdepth=16) 
    # Convert z to the Python list of lists expected by 
    # the png writer. 
    z2list = z.reshape(-1, z.shape[1]*z.shape[2]).tolist() 
    writer.write(f, z2list) 

# Here's a grayscale example. 
zgray = z[:, :, 0] 

# Use pypng to write zgray as a grayscale PNG. 
with open('foo_gray.png', 'wb') as f: 
    writer = png.Writer(width=z.shape[1], height=z.shape[0], bitdepth=16, greyscale=True) 
    zgray2list = zgray.tolist() 
    writer.write(f, zgray2list) 

这里的颜色输出:

foo_color.png

和这里的灰度输出:

foo_gray.png


更新:我最近创建了一个名为numpngw模块,用于写入numpy的阵列到PNG文件提供一个功能的GitHub的仓库。该存储库有一个setup.py文件用于将其作为软件包进行安装,但基本代码位于单个文件numpngw.py中,可以将其复制到任何方便的位置。 numpngw唯一的依赖是numpy。

下面是生成同样的16位图像那些脚本如上图所示:

import numpy as np 
import numpngw 

# The following import is just for creating an interesting array 
# of data. It is not necessary for writing a PNG file with PyPNG. 
from scipy.ndimage import gaussian_filter 


# Make an image in a numpy array for this demonstration. 
nrows = 240 
ncols = 320 
np.random.seed(12345) 
x = np.random.randn(nrows, ncols, 3) 

# y is our floating point demonstration data. 
y = gaussian_filter(x, (16, 16, 0)) 

# Convert y to 16 bit unsigned integers. 
z = (65535*((y - y.min())/y.ptp())).astype(np.uint16) 

# Use numpngw to write z as a color PNG. 
numpngw.write_png('foo_color.png', z) 

# Here's a grayscale example. 
zgray = z[:, :, 0] 

# Use numpngw to write zgray as a grayscale PNG. 
numpngw.write_png('foo_gray.png', zgray) 
+0

这很好用!作为额外的好处,pyng是“Canopy软件包”之一,虽然默认情况下不安装,但它可以通过Canopy程序轻松安装。 – DanHickstein 2014-09-12 22:37:08

2

PNG和numpngw的这种解释是非常有帮助!但是,我认为我应该提到一个小小的“错误”。在转换为16位无符号整数时,y.max()应该是y.min()。对于随机颜色的图片,它并不重要,但对于真实的图片,我们需要做的正确。这是更正的代码行...

z = (65535*((y - y.min())/y.ptp())).astype(np.uint16) 
+0

我刚注意到这个!当然,你是对的。我已经更新了我的答案(以及示例https://github.com/WarrenWeckesser/numpngw)。 – 2017-06-20 02:29:51

相关问题