You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Python将WAV转PNG后反向还原为原WAV异常如何解决?

代码核心错误点
  • 字节总长度统计错误:w.getnframes()是音频的帧数,而非读取到的frames字节串的总长度,你遍历字节生成RGB三元组时误用帧数作为长度上限,直接丢弃了大部分音频原始数据。
  • 数据截断丢失:计算正方形边长时直接取整舍弃小数部分,无法填满正方形的剩余字节全部被丢弃,还原时数据天然不完整。
  • 音频回写格式完全错误:
    1. 写死采样宽度为2,若原音频采样宽度不匹配直接导致格式错乱
    2. 将单字节的像素值强制转换为8字节大端数据写入,每个有效字节被填充了7个无效字节,音频采样数据完全失真
  • 逐字节写入效率极低,wave库的writeframesraw支持直接传入完整字节串,无需循环逐个写入
修正后可正常运行的代码
import wave
from PIL import Image
import numpy as np
from math import sqrt, ceil

# 读取音频
w = wave.open("sample.wav", mode="rb")
frames = w.readframes(w.getnframes())
frame_bytes = list(frames)
total_bytes = len(frame_bytes)

# 填充字节到刚好可组成正方形RGB图像
need_pad = 3 * ceil(sqrt(total_bytes / 3)) ** 2 - total_bytes
frame_bytes += [0] * need_pad
total_padded = len(frame_bytes)

# 生成RGB像素列表
pixels = []
for i in range(0, total_padded, 3):
    pixels.append((frame_bytes[i], frame_bytes[i+1], frame_bytes[i+2]))

# 生成正方形图像
dim = int(sqrt(total_padded / 3))
img_array = np.array(pixels, dtype=np.uint8).reshape(dim, dim, 3)
new_image = Image.fromarray(img_array)
new_image.save('new.png')

# 从图像读取像素
p = Image.open("new.png", mode="r")
flatten = [x for sets in list(p.getdata()) for x in sets]
# 截断掉之前填充的无效字节
flatten = flatten[:total_bytes]
revert_bytes = bytes(flatten)

# 回写音频,参数完全复用原音频配置
obj = wave.open('sound.wav', 'w')
obj.setnchannels(w.getnchannels())
obj.setsampwidth(w.getsampwidth())
obj.setframerate(w.getframerate())
obj.writeframesraw(revert_bytes)
obj.close()
w.close()

内容的提问来源于stack exchange,提问作者Hunter G

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.09 16:09:03