将numpy数组写入png或动画png文件。

numpngw的Python项目详细描述


这个python包定义了函数write_png,该函数编写 numpy数组到一个png文件,函数write_apng写入 动画PNG(APNG)文件的数组序列。也包括 是可用于保存matplotlib的类AnimatedPNGWriter。 动画作为动画PNG文件;参见示例8。

write_png的功能包括:

  • 创建8位和16位rgb文件;
  • 创建1位、2位、4位、8位和16位灰度文件;
  • 使用alpha通道创建rgb和灰度图像;
  • 设置透明颜色;
  • 为索引PNG文件自动创建调色板;
  • 包含^{TT5}$,^{TT6}$,^{TT7}$,^{TT8}$,^{TT9}$,^{TT10}$ 以及iCCP块。

这个包是用纯python编写的。唯一的外部依赖 是numpy和setuptools。

该包有一套单元测试,但仍应考虑 原型质量软件。可能存在向后不兼容的API更改 在释放之间。

本软件在BSD 2条款许可下发布。

对于具有更多功能的包(包括读取png文件的函数), 看一看:

下面的示例显示了使用 努比和努姆普。要查看示例5-8中的动画,必须查看 此文件带有支持动画PNG文件的浏览器。目前(作为 关于此文件的编写)、Firefox、Safari 10和最新版本的 Chromium支持动画PNG。歌剧需要延期。

示例1

下面的脚本创建这个png文件,一个8位的rgb图像。

Example 1

脚本:

import numpy as np
from numpngw import write_png


# Example 1
#
# Create an 8-bit RGB image.

img = np.zeros((80, 128, 3), dtype=np.uint8)

grad = np.linspace(0, 255, img.shape[1])

img[:16, :, :] = 127
img[16:32, :, 0] = grad
img[32:48, :, 1] = grad[::-1]
img[48:64, :, 2] = grad
img[64:, :, :] = 127

write_png('example1.png', img)

例2

下面的脚本创建这个png文件,一个1位灰度图像。

Example 2

脚本:

import numpy as np
from numpngw import write_png

# Example 2
#
# Create a 1-bit grayscale image.

mask = np.zeros((48, 48), dtype=np.uint8)
mask[:2, :] = 1
mask[:, -2:] = 1
mask[4:6, :-4] = 1
mask[4:, -6:-4] = 1
mask[-16:, :16] = 1
mask[-32:-16, 16:32] = 1

write_png('example2.png', mask, bitdepth=1)

例3

下面的脚本创建这个png文件,一个16位的rgb文件,其中 值(0,0,0)是透明的。可能不明显,但是 两个正方形是透明的。

Example 3

脚本:

import numpy as np
from numpngw import write_png

# Example 3
#
# Create a 16-bit RGB image, with (0, 0, 0) indicating a transparent pixel.

# Create some interesting data.
w = 32
nrows = 3*w
ncols = 5*w
kernel = np.exp(-np.linspace(-2, 2, 35)**2)
kernel = kernel/kernel.sum()
np.random.seed(123)
x = np.random.randn(nrows, ncols, 3)
x = np.apply_along_axis(lambda z: np.convolve(z, kernel, mode='same'), 0, x)
x = np.apply_along_axis(lambda z: np.convolve(z, kernel, mode='same'), 1, x)

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

# Create two squares containing (0, 0, 0).
z[w:2*w, w:2*w] = 0
z[w:2*w, -2*w:-w] = 0

# Write the PNG file, and indicate that (0, 0, 0) should be transparent.
write_png('example3.png', z, transparent=(0, 0, 0))

例4

下面的脚本使用选项use_palette=True创建这个8位 索引的rgb文件。

Example 4

脚本:

import numpy as np
from numpngw import write_png


# Example 4
#
# Create an 8-bit indexed RGB image that uses a palette.

img_width = 300
img_height = 200
img = np.zeros((img_height, img_width, 3), dtype=np.uint8)

np.random.seed(222)
for _ in range(40):
    width = np.random.randint(5, img_width // 5)
    height = np.random.randint(5, img_height // 5)
    row = np.random.randint(5, img_height - height - 5)
    col = np.random.randint(5, img_width - width - 5)
    color = np.random.randint(80, 256, size=2)
    img[row:row+height, col:col+width, 1:] = color

write_png('example4.png', img, use_palette=True)

例5

此动画PNG

Example 5

由以下脚本创建。在其他例子中,大多数 脚本是生成要保存的数据的代码。创建 png文件很简单:

write_apng("example5.png", seq, delay=50, use_palette=True)

脚本:

import numpy as np
from numpngw import write_apng

# Example 5
#
# Create an 8-bit RGB animated PNG file.

height = 20
width = 200
t = np.linspace(0, 10*np.pi, width)
seq = []
for phase in np.linspace(0, 2*np.pi, 25, endpoint=False):
    y = 150*0.5*(1 + np.sin(t - phase))
    a = np.zeros((height, width, 3), dtype=np.uint8)
    a[:, :, 0] = y
    a[:, :, 2] = y
    seq.append(a)

write_apng("example5.png", seq, delay=50, use_palette=True)

例6

另一个动画rgb png。在本例中,参数seq 传递给write_apng的是具有形状的numpy数组 (num_frames, height, width, 3)

Example 6

脚本:

import numpy as np
from numpngw import write_apng

# Example 6
#
# Create an 8-bit RGB animated PNG file.

def smoother(w):
    # Return the periodic convolution of w with a 3-d Gaussian kernel.
    r = np.linspace(-3, 3, 21)
    X, Y, Z = np.meshgrid(r, r, r)
    kernel = np.exp(-0.25*(X*X + Y*Y + Z*Z)**2)
    fw = np.fft.fftn(w)
    fkernel = np.fft.fftn(kernel, w.shape)
    v = np.fft.ifftn(fw*fkernel).real
    return v

height = 40
width = 250
num_frames = 30
np.random.seed(12345)
w = np.random.randn(num_frames, height, width, 3)
for k in range(3):
    w[..., k] = smoother(w[..., k])

seq = (255*(w - w.min())/w.ptp()).astype(np.uint8)

write_apng("example6.png", seq, delay=40)

例7

创建一个动画PNG,每帧显示时间不同。

Example 7

脚本:

import numpy as np
from numpngw import write_apng

# Example 7
#
# Create an animated PNG file with nonuniform display times
# of the frames.

bits1 = np.array([
    [0,0,1,0,0],
    [0,1,1,0,0],
    [0,0,1,0,0],
    [0,0,1,0,0],
    [0,0,1,0,0],
    [0,0,1,0,0],
    [0,1,1,1,0],
    ])

bits2 = np.array([
    [0,1,1,1,0],
    [1,0,0,0,1],
    [0,0,0,0,1],
    [0,1,1,1,0],
    [1,0,0,0,0],
    [1,0,0,0,0],
    [1,1,1,1,1],
    ])

bits3 = np.array([
    [0,1,1,1,0],
    [1,0,0,0,1],
    [0,0,0,0,1],
    [0,0,1,1,0],
    [0,0,0,0,1],
    [1,0,0,0,1],
    [0,1,1,1,0],
    ])

bits_box1 = np.array([
    [0,0,0,0,0],
    [1,1,1,1,1],
    [1,0,0,0,1],
    [1,0,0,0,1],
    [1,0,0,0,1],
    [1,1,1,1,1],
    [0,0,0,0,0],
    ])

bits_box2 = np.array([
    [0,0,0,0,0],
    [0,0,0,0,0],
    [0,1,1,1,0],
    [0,1,0,1,0],
    [0,1,1,1,0],
    [0,0,0,0,0],
    [0,0,0,0,0],
    ])

bits_dot = np.array([
    [0,0,0,0,0],
    [0,0,0,0,0],
    [0,0,0,0,0],
    [0,0,1,0,0],
    [0,0,0,0,0],
    [0,0,0,0,0],
    [0,0,0,0,0],
    ])

bits_zeros = np.zeros((7, 5), dtype=bool)
bits_ones = np.ones((7, 5), dtype=bool)


def bits_to_image(bits, blocksize=32, color=None):
    bits = np.asarray(bits, dtype=np.bool)
    if color is None:
        color = np.array([255, 0, 0], dtype=np.uint8)
    else:
        color = np.asarray(color, dtype=np.uint8)

    x = np.linspace(-1, 1, blocksize)
    X, Y = np.meshgrid(x, x)
    Z = np.sqrt(np.maximum(1 - (X**2 + Y**2), 0))
    # The "on" image:
    img1 = (Z.reshape(blocksize, blocksize, 1)*color)
    # The "off" image:
    img0 = 0.2*img1

    data = np.where(bits[:, None, :, None, None],
                    img1[:, None, :], img0[:, None, :])
    img = data.reshape(bits.shape[0]*blocksize, bits.shape[1]*blocksize, 3)
    return img.astype(np.uint8)

# Create `seq` and `delay`, the sequence of images and the
# corresponding display times.

color = np.array([32, 48, 255])
blocksize = 24
# Images...
im3 = bits_to_image(bits3, blocksize=blocksize, color=color)
im2 = bits_to_image(bits2, blocksize=blocksize, color=color)
im1 = bits_to_image(bits1, blocksize=blocksize, color=color)
im_all = bits_to_image(bits_ones, blocksize=blocksize, color=color)
im_none = bits_to_image(bits_zeros, blocksize=blocksize, color=color)
im_box1 = bits_to_image(bits_box1, blocksize=blocksize, color=color)
im_box2 = bits_to_image(bits_box2, blocksize=blocksize, color=color)
im_dot = bits_to_image(bits_dot, blocksize=blocksize, color=color)

# The sequence of images:
seq = [im3, im2, im1, im_all, im_none, im_all, im_none, im_all, im_none,
       im_box1, im_box2, im_dot, im_none]
# The time duration to display each image, in milliseconds:
delay = [1000, 1000, 1000, 333, 250, 333, 250, 333, 500,
         167, 167, 167, 1000]

# Create the animated PNG file.
write_apng("example7.png", seq, delay=delay, default_image=im_all,
           use_palette=True)

例8

此示例显示如何将matplotlib动画另存为 带有numpngw.animatedpngwriter的动画PNG文件。(小心 有了这个类,它可以轻松地创建非常大的png文件。)

Example 8

脚本:

import numpy as np
from scipy.integrate import odeint
from scipy.fftpack import diff as psdiff

import matplotlib.pyplot as plt
from matplotlib import animation
from numpngw import AnimatedPNGWriter


def kdv_exact(x, c):
    """
    Profile of the exact solution to the KdV for a single soliton
    on the real line.
    """
    u = 0.5*c*np.cosh(0.5*np.sqrt(c)*x)**(-2)
    return u


def kdv(u, t, L):
    """
    Differential equations for the KdV equation, discretized in x.
    """
    # Compute the x derivatives using the pseudo-spectral method.
    ux = psdiff(u, period=L)
    uxxx = psdiff(u, period=L, order=3)

    # Compute du/dt.
    dudt = -6*u*ux - uxxx

    return dudt


def kdv_solution(u0, t, L):
    """
    Use odeint to solve the KdV equation on a periodic domain.

    `u0` is initial condition, `t` is the array of time values at which
    the solution is to be computed, and `L` is the length of the periodic
    domain.
    """
    sol = odeint(kdv, u0, t, args=(L,), mxstep=5000)
    return sol


def update_line(num, x, data, line):
    """
    Animation "call back" function for each frame.
    """
    line.set_data(x, data[num, :])
    return line,


# Set the size of the domain, and create the discretized grid.
L = 80.0
N = 256
dx = L / (N - 1.0)
x = np.linspace(0, (1-1.0/N)*L, N)

# Set the initial conditions.
# Not exact for two solitons on a periodic domain, but close enough...
u0 = kdv_exact(x-0.15*L, 0.8) + kdv_exact(x-0.4*L, 0.4)

# Set the time sample grid.
T = 260
t = np.linspace(0, T, 225)

print("Computing the solution.")
sol = kdv_solution(u0, t, L)

print("Generating the animated PNG file.")

fig = plt.figure(figsize=(7.5, 1.5))
ax = fig.gca(title="Korteweg de Vries interacting solitons in a periodic "
                   "domain (L = 80)")

# Plot the initial condition. lineplot is reused in the animation.
lineplot, = ax.plot(x, u0, 'c-', linewidth=3)
plt.tight_layout()

ani = animation.FuncAnimation(fig, update_line, frames=len(t),
                              init_func=lambda : None,
                              fargs=(x, sol, lineplot))
writer = AnimatedPNGWriter(fps=12)
ani.save('kdv.png', dpi=60, writer=writer)

plt.close(fig)

欢迎加入QQ群-->: 979659372 Python中文网_新手群

推荐PyPI第三方库


热门话题
java解析分数   xslt捕获java中的xsl:message输出   java Spring安全性:手动恢复默认配置   考虑到夏令时,java是比较Hibernate和Oracle日期的正确方法   java如何将主线程与创建的工作线程连接?   java Intellij无法导入Gradle项目,因为存在代理   解析如何在Java中使用String对象解析输入   javajavax。邮政AuthenticationFailedException:535身份验证失败(#5.7.1)   java MouseMotionListener:鼠标和触控板给出不同的结果   MBean的java SNMP监控(snmpadaptor.sar中的attributes.xml)(JBoss)   java以特定的时间间隔刷新令牌以供API使用   Android中的正则表达式是否与Java中的正则表达式相同?   java在以“我的应用”身份打开应用时获取文件路径   java将变量从valuechanged方法传输到actionperformed   java PDF“保存”旋转?   Android Studio、Java、TextView不反映我编写的代码