Wav 到 C# 中的位图转换
Wav to bitmap conversion in C#
我正在尝试编写一个程序来读取 .wav 文件,将其转换为位图,然后将位图转换回 wav 文件。我已经在 python 中使用 Wave 模块做到了这一点,并且能够通过这种方式创建一些声音上有趣的衰减。
我的代码运行了,但没有得到预期的结果,只有白噪音。
Wav转位图
private void button1_Click(object sender, EventArgs e)
{
System.IO.Stream load_wav = new System.IO.MemoryStream();
openFileDialog1.Filter = "WAV|*.wav";
openFileDialog1.ShowDialog();
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
try
{
if ((load_wav = openFileDialog1.OpenFile()) != null)
{
using (load_wav)
{
using (WaveFileReader reader = new WaveFileReader(load_wav))
{
int BitsPerSample;
int SampleRate;
BitsPerSample = reader.WaveFormat.BitsPerSample;
SampleRate = reader.WaveFormat.SampleRate;
string config = SampleRate.ToString();
// Write sample config to .ini
System.IO.StreamWriter file = new System.IO.StreamWriter(".\config.ini");
file.WriteLine(config);
file.Close();
if (BitsPerSample == 16) // Check 16bit
{
// Read WAV
byte[] in_buffer = new byte[reader.Length];
int read = reader.Read(in_buffer, 0, in_buffer.Length);
MessageBox.Show("Load OK");
// Convert byte array to stream
Bitmap output = new Bitmap(600, 600);
Rectangle rect = new Rectangle(0, 0, output.Width, output.Height);
BitmapData bmpData = output.LockBits(rect, ImageLockMode.ReadWrite, output.PixelFormat);
IntPtr ptr = bmpData.Scan0;
System.Runtime.InteropServices.Marshal.Copy(in_buffer, 0, ptr, in_buffer.Length);
output.UnlockBits(bmpData);
pictureBox1.Image = output;
output.Save(".\output.bmp");
}
else
{
MessageBox.Show("16 bit WAV files only :-(");
}
位图转 Wav
private void button2_Click(object sender, EventArgs e)
{
if ((pictureBox1.Image == null))
{
}
else
{
// Read sample .ini
System.IO.StreamReader file = new System.IO.StreamReader(".\config.ini");
string config = file.ReadLine();
file.Close();
int SampleRate = Convert.ToInt32(config);
// Convert bmp to byte array
Bitmap output = Image.FromFile(".\output.bmp") as Bitmap;
ImageConverter converter = new ImageConverter();
byte[] out_bytes = (byte[])converter.ConvertTo(output, typeof(byte[]));
// Convert byte array to stream
System.IO.MemoryStream out_stream = new System.IO.MemoryStream(out_bytes);
// Append valid WAV header to stream
WaveFormat waveformat = new WaveFormat(SampleRate, 16, 2);
var reader = new RawSourceWaveStream(out_stream, waveformat);
using (var convertedStream = WaveFormatConversionStream.CreatePcmStream(reader))
{
// Save dialog
SaveFileDialog savefiledialog1 = new SaveFileDialog();
savefiledialog1.Title = "export wav";
savefiledialog1.Filter = "wav|*.wav";
savefiledialog1.ShowDialog();
if (savefiledialog1.FileName != "")
{
WaveFileWriter.CreateWaveFile(savefiledialog1.FileName, convertedStream);
}
}
out_stream.Close();
}
}
我认为问题在于我将字节数组转换为流的方式。
查看我的 python 代码的 bmp 输出,生成的位图是 24 位的。我的 C# 代码生成的位图是 32 位的。
使用 EncoderParameters 解决
// Setup 24 bit bmp encoder
System.Drawing.Imaging.Encoder myEncoder = System.Drawing.Imaging.Encoder.ColorDepth;
myEncoder = System.Drawing.Imaging.Encoder.ColorDepth;
EncoderParameters myEncoderParameters = new EncoderParameters(1);
EncoderParameter myEncoderParameter = new EncoderParameter(myEncoder, 24L);
myEncoderParameters.Param[0] = myEncoderParameter;
var codec = GetEncoderInfo("image/bmp");
根据需要,音频输出现在是音频输入的降级版本。
我正在尝试编写一个程序来读取 .wav 文件,将其转换为位图,然后将位图转换回 wav 文件。我已经在 python 中使用 Wave 模块做到了这一点,并且能够通过这种方式创建一些声音上有趣的衰减。
我的代码运行了,但没有得到预期的结果,只有白噪音。
Wav转位图
private void button1_Click(object sender, EventArgs e)
{
System.IO.Stream load_wav = new System.IO.MemoryStream();
openFileDialog1.Filter = "WAV|*.wav";
openFileDialog1.ShowDialog();
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
try
{
if ((load_wav = openFileDialog1.OpenFile()) != null)
{
using (load_wav)
{
using (WaveFileReader reader = new WaveFileReader(load_wav))
{
int BitsPerSample;
int SampleRate;
BitsPerSample = reader.WaveFormat.BitsPerSample;
SampleRate = reader.WaveFormat.SampleRate;
string config = SampleRate.ToString();
// Write sample config to .ini
System.IO.StreamWriter file = new System.IO.StreamWriter(".\config.ini");
file.WriteLine(config);
file.Close();
if (BitsPerSample == 16) // Check 16bit
{
// Read WAV
byte[] in_buffer = new byte[reader.Length];
int read = reader.Read(in_buffer, 0, in_buffer.Length);
MessageBox.Show("Load OK");
// Convert byte array to stream
Bitmap output = new Bitmap(600, 600);
Rectangle rect = new Rectangle(0, 0, output.Width, output.Height);
BitmapData bmpData = output.LockBits(rect, ImageLockMode.ReadWrite, output.PixelFormat);
IntPtr ptr = bmpData.Scan0;
System.Runtime.InteropServices.Marshal.Copy(in_buffer, 0, ptr, in_buffer.Length);
output.UnlockBits(bmpData);
pictureBox1.Image = output;
output.Save(".\output.bmp");
}
else
{
MessageBox.Show("16 bit WAV files only :-(");
}
位图转 Wav
private void button2_Click(object sender, EventArgs e)
{
if ((pictureBox1.Image == null))
{
}
else
{
// Read sample .ini
System.IO.StreamReader file = new System.IO.StreamReader(".\config.ini");
string config = file.ReadLine();
file.Close();
int SampleRate = Convert.ToInt32(config);
// Convert bmp to byte array
Bitmap output = Image.FromFile(".\output.bmp") as Bitmap;
ImageConverter converter = new ImageConverter();
byte[] out_bytes = (byte[])converter.ConvertTo(output, typeof(byte[]));
// Convert byte array to stream
System.IO.MemoryStream out_stream = new System.IO.MemoryStream(out_bytes);
// Append valid WAV header to stream
WaveFormat waveformat = new WaveFormat(SampleRate, 16, 2);
var reader = new RawSourceWaveStream(out_stream, waveformat);
using (var convertedStream = WaveFormatConversionStream.CreatePcmStream(reader))
{
// Save dialog
SaveFileDialog savefiledialog1 = new SaveFileDialog();
savefiledialog1.Title = "export wav";
savefiledialog1.Filter = "wav|*.wav";
savefiledialog1.ShowDialog();
if (savefiledialog1.FileName != "")
{
WaveFileWriter.CreateWaveFile(savefiledialog1.FileName, convertedStream);
}
}
out_stream.Close();
}
}
我认为问题在于我将字节数组转换为流的方式。
查看我的 python 代码的 bmp 输出,生成的位图是 24 位的。我的 C# 代码生成的位图是 32 位的。
使用 EncoderParameters 解决
// Setup 24 bit bmp encoder
System.Drawing.Imaging.Encoder myEncoder = System.Drawing.Imaging.Encoder.ColorDepth;
myEncoder = System.Drawing.Imaging.Encoder.ColorDepth;
EncoderParameters myEncoderParameters = new EncoderParameters(1);
EncoderParameter myEncoderParameter = new EncoderParameter(myEncoder, 24L);
myEncoderParameters.Param[0] = myEncoderParameter;
var codec = GetEncoderInfo("image/bmp");
根据需要,音频输出现在是音频输入的降级版本。