首页 > 解决方案 > 需要帮助将 .wav 音频文件转换为 .PNG ,然后再转换回相同的 .wav 文件

问题描述

我正在尝试将声音文件转换为图像,然后在 Python 中转换回相同的声音文件。首先,我正在使用 python 的wave库读取 .wav,提取帧,然后将字节排列为方形图像中的 RGB 元组。

输出很酷,看起来像这样

但是当我尝试将图像转换回声音文件时,结果很糟糕。不知道我在这里做错了什么

import wave
from PIL import Image
import numpy as np
from math import sqrt


w = wave.open("sample.wav", mode = "rb")
frames = w.readframes(w.getnframes())
pixels = []

#####FRAMES CONVERTED TO PIXEL TUPLES######

for i in range(0,w.getnframes(),3):
    pixels.append((frames[i],frames[i+1],frames[i+2]))

#####FIT TO SQUARE IMAGE#####
dimensions = int(sqrt(w.getnframes()/3))

img = []

for x in range(0,dimensions):
    row = []
    for y in range(0,dimensions):
        row.append(pixels[x*dimensions+y])
    img.append(row)

array = np.array(img, dtype=np.uint8)
new_image = Image.fromarray(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]


###### WAV RE-CREATION ######

sampleRate = w.getframerate() # hertz

obj = wave.open('sound.wav','w')
obj.setnchannels(w.getnchannels())
obj.setsampwidth(2)
obj.setframerate(sampleRate)
for i in range(0,len(flatten)):
   obj.writeframesraw(( flatten[i]).to_bytes(8,"big") )
obj.close()

标签: pythonimageaudioencodingcompression

解决方案


您在转换为像素时引入了损失。

for i in range(0,w.getnframes(),3):首先,当帧数不是三的倍数时,最后会丢失一两帧。

其次,当帧数除以三不是正方形时,您dimensions = int(sqrt(w.getnframes()/3))然后编写平方像素将丢失许多帧。dimensions

第三,也是最重要的,您忽略了样本宽度以及通道数。您只保存图像中每个样本的低八位。如果样本宽度为 16 位,则本质上是在图像中节省噪声。


推荐阅读