是否有任何開源C#代碼或庫提供給定字節數組的圖形波形?開源C#代碼呈現波形?
35
A
回答
44
這是作爲開源,因爲它得到:
public static void DrawNormalizedAudio(ref float[] data, PictureBox pb,
Color color)
{
Bitmap bmp;
if (pb.Image == null)
{
bmp = new Bitmap(pb.Width, pb.Height);
}
else
{
bmp = (Bitmap)pb.Image;
}
int BORDER_WIDTH = 5;
int width = bmp.Width - (2 * BORDER_WIDTH);
int height = bmp.Height - (2 * BORDER_WIDTH);
using (Graphics g = Graphics.FromImage(bmp))
{
g.Clear(Color.Black);
Pen pen = new Pen(color);
int size = data.Length;
for (int iPixel = 0; iPixel < width; iPixel++)
{
// determine start and end points within WAV
int start = (int)((float)iPixel * ((float)size/(float)width));
int end = (int)((float)(iPixel + 1) * ((float)size/(float)width));
float min = float.MaxValue;
float max = float.MinValue;
for (int i = start; i < end; i++)
{
float val = data[i];
min = val < min ? val : min;
max = val > max ? val : max;
}
int yMax = BORDER_WIDTH + height - (int)((max + 1) * .5 * height);
int yMin = BORDER_WIDTH + height - (int)((min + 1) * .5 * height);
g.DrawLine(pen, iPixel + BORDER_WIDTH, yMax,
iPixel + BORDER_WIDTH, yMin);
}
}
pb.Image = bmp;
}
這個函數將產生這樣的事情:
這需要採樣的陣列中的浮點格式(其中所有采樣值範圍從-1到+1)。如果您的原始數據實際上是以byte []數組的形式存在,那麼您必須執行一些工作才能將其轉換爲float []。讓我知道你是否也需要這個。
更新:由於技術上的要求使用一些問題來呈現一個字節數組,這裏有一對夫婦的輔助方法:
public float[] FloatArrayFromStream(System.IO.MemoryStream stream)
{
return FloatArrayFromByteArray(stream.GetBuffer());
}
public float[] FloatArrayFromByteArray(byte[] input)
{
float[] output = new float[input.Length/4];
for (int i = 0; i < output.Length; i++)
{
output[i] = BitConverter.ToSingle(input, i * 4);
}
return output;
}
更新2:我忘了還有一個更好的辦法來做到這一點:
public float[] FloatArrayFromByteArray(byte[] input)
{
float[] output = new float[input.Length/4];
Buffer.BlockCopy(input, 0, output, 0, input.Length);
return output;
}
我只是很喜歡for
循環,我猜。
3
我一直是ZedGraph多年的粉絲,並用它來顯示各種項目中的各種數據。
以下示例代碼圖表雙打的-1和1之間變化的數組:
void DisplayWaveGraph(ZedGraphControl graphControl, double[] waveData)
{
var pane = graphControl.GraphPane;
pane.Chart.Border.IsVisible = false;
pane.Chart.Fill.IsVisible = false;
pane.Fill.Color = Color.Black;
pane.Margin.All = 0;
pane.Title.IsVisible = false;
pane.XAxis.IsVisible = false;
pane.XAxis.Scale.Max = waveData.Length - 1;
pane.XAxis.Scale.Min = 0;
pane.YAxis.IsVisible = false;
pane.YAxis.Scale.Max = 1;
pane.YAxis.Scale.Min = -1;
var timeData = Enumerable.Range(0, waveData.Length)
.Select(i => (double) i)
.ToArray();
pane.AddCurve(null, timeData, waveData, Color.Lime, SymbolType.None);
graphControl.AxisChange();
}
將上述樣品模擬音頻編輯器通過抑制軸以及改變顏色,以產生以下的式:
3
在NAudio,有代碼來繪製在兩個WinForms和WPF音頻波形。查看演示項目,瞭解如何使用它的示例。
10
我修改了MusiGenesis的解決方案。 這給了我一個更好的結果,尤其是在音樂房子:)
public static Bitmap DrawNormalizedAudio(List<float> data, Color foreColor, Color backColor, Size imageSize)
{
Bitmap bmp = new Bitmap(imageSize.Width, imageSize.Height);
int BORDER_WIDTH = 0;
float width = bmp.Width - (2 * BORDER_WIDTH);
float height = bmp.Height - (2 * BORDER_WIDTH);
using (Graphics g = Graphics.FromImage(bmp))
{
g.Clear(backColor);
Pen pen = new Pen(foreColor);
float size = data.Count;
for (float iPixel = 0; iPixel < width; iPixel += 1)
{
// determine start and end points within WAV
int start = (int)(iPixel * (size/width));
int end = (int)((iPixel + 1) * (size/width));
if (end > data.Count)
end = data.Count;
float posAvg, negAvg;
averages(data, start, end, out posAvg, out negAvg);
float yMax = BORDER_WIDTH + height - ((posAvg + 1) * .5f * height);
float yMin = BORDER_WIDTH + height - ((negAvg + 1) * .5f * height);
g.DrawLine(pen, iPixel + BORDER_WIDTH, yMax, iPixel + BORDER_WIDTH, yMin);
}
}
return bmp;
}
private static void averages(List<float> data, int startIndex, int endIndex, out float posAvg, out float negAvg)
{
posAvg = 0.0f;
negAvg = 0.0f;
int posCount = 0, negCount = 0;
for (int i = startIndex; i < endIndex; i++)
{
if (data[i] > 0)
{
posCount++;
posAvg += data[i];
}
else
{
negCount++;
negAvg += data[i];
}
}
posAvg /= posCount;
negAvg /= negCount;
}
5
與適應代碼羅比和使用Graphics.Fill/DrawClosedCurve抗鋸齒,我得到一個非常漂亮的結果。
下面的代碼:
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
namespace Soundfingerprinting.Audio.Services
{
public static class AudioVisualizationService
{
public class WaveVisualizationConfiguration
{
public Nullable<Color> AreaColor { get; set; }
public Nullable<Color> EdgeColor { get; set; }
public int EdgeSize { get; set; }
public Nullable<Rectangle> Bounds { get; set; }
public double Overlap { get; set; }
public int Step { get; set; }
}
public static void DrawWave(float[] data, Bitmap bitmap, WaveVisualizationConfiguration config = null)
{
Color areaColor = Color.FromArgb(0x7F87CEFA);// Color.LightSkyBlue; semi transparent
Color edgeColor = Color.DarkSlateBlue;
int edgeSize = 2;
int step = 2;
double overlap = 0.10f; // would better use a windowing function
Rectangle bounds = Rectangle.FromLTRB(0, 0, bitmap.Width, bitmap.Height);
if (config != null)
{
edgeSize = config.EdgeSize;
if (config.AreaColor.HasValue)
areaColor = config.AreaColor.GetValueOrDefault();
if (config.EdgeColor.HasValue)
edgeColor = config.EdgeColor.GetValueOrDefault();
if (config.Bounds.HasValue)
bounds = config.Bounds.GetValueOrDefault();
step = Math.Max(1, config.Step);
overlap = config.Overlap;
}
float width = bounds.Width;
float height = bounds.Height;
using (Graphics g = Graphics.FromImage(bitmap))
{
Pen edgePen = new Pen(edgeColor);
edgePen.LineJoin = LineJoin.Round;
edgePen.Width = edgeSize;
Brush areaBrush = new SolidBrush(areaColor);
float size = data.Length;
PointF[] topCurve = new PointF[(int)width/step];
PointF[] bottomCurve = new PointF[(int)width/step];
int idx = 0;
for (float iPixel = 0; iPixel < width; iPixel += step)
{
// determine start and end points within WAV
int start = (int)(iPixel * (size/width));
int end = (int)((iPixel + step) * (size/width));
int window = end - start;
start -= (int)(overlap * window);
end += (int)(overlap * window);
if (start < 0)
start = 0;
if (end > data.Length)
end = data.Length;
float posAvg, negAvg;
averages(data, start, end, out posAvg, out negAvg);
float yMax = height - ((posAvg + 1) * .5f * height);
float yMin = height - ((negAvg + 1) * .5f * height);
float xPos = iPixel + bounds.Left;
if (idx >= topCurve.Length)
idx = topCurve.Length - 1;
topCurve[idx] = new PointF(xPos, yMax);
bottomCurve[bottomCurve.Length - idx - 1] = new PointF(xPos, yMin);
idx++;
}
PointF[] curve = new PointF[topCurve.Length * 2];
Array.Copy(topCurve, curve, topCurve.Length);
Array.Copy(bottomCurve, 0, curve, topCurve.Length, bottomCurve.Length);
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
g.SmoothingMode = SmoothingMode.AntiAlias;
g.FillClosedCurve(areaBrush, curve, FillMode.Winding, 0.15f);
if (edgeSize > 0)
g.DrawClosedCurve(edgePen, curve, 0.15f, FillMode.Winding);
}
}
private static void averages(float[] data, int startIndex, int endIndex, out float posAvg, out float negAvg)
{
posAvg = 0.0f;
negAvg = 0.0f;
int posCount = 0, negCount = 0;
for (int i = startIndex; i < endIndex; i++)
{
if (data[i] > 0)
{
posCount++;
posAvg += data[i];
}
else
{
negCount++;
negAvg += data[i];
}
}
if (posCount > 0)
posAvg /= posCount;
if (negCount > 0)
negAvg /= negCount;
}
}
}
相關問題
- 1. 在iPhone上呈現波形
- 2. Magento主頁呈現爲源代碼HTML
- 3. 顯示HTML源代碼而不是在GAE中呈現代碼
- 4. GWT setInnerSafeHtml呈現HTML源碼
- 5. 正常化音頻波形代碼實現(峯值,有效值)
- 6. A律波文件轉換源代碼
- 7. 載波圖像未加載源代碼
- 8. 你知道任何開源asp.net web控件來呈現的代碼?
- 9. 是Google代碼開放源代碼的源代碼
- 10. 如何在HTML5畫布上呈現音頻波形?
- 11. 如何在sapui5中呈現javascript源代碼
- 12. 保存爲客戶端呈現爲.txt文件的源代碼
- 13. 如何獲取webkitgtk呈現的源代碼?
- 14. Firebug:如何保存呈現的源代碼?
- 15. 如何查看JavaScript呈現的源代碼?
- 16. 從Web組件站點獲取呈現的源代碼?
- 17. 如何通過使用硒獲取HTML呈現源代碼
- 18. 如何使用NSURLConnection獲取呈現的javascript源代碼
- 19. 輸出/呈現文字無法在源代碼中看到
- 20. 內容查詢Web部件呈現HTML源代碼
- 21. WkHtmlToXSharp一旦更改源代碼,就不會呈現HTML元素
- 22. Objective-C源代碼
- 23. Google.Apis.Auth源代碼c#
- 24. C源代碼DLL
- 25. c#.net源代碼
- 26. C庫源代碼
- 27. 在C源代碼
- 28. 在C++中呈現矢量圖形(.svg)
- 29. C++ SFML 2.2圖形不呈現
- 30. 現有開源項目實施的源代碼管理/管理
除非你對其進行許可,並收取每OP使用:) – Martin 2009-10-01 18:56:41
$ @馬丁20:我負責的說只是看着* *它。我的20美元在哪裏? :) – MusiGenesis 2009-10-02 00:58:36
酷算法。我只是計算最接近我的像素的樣本,並在那裏放了一個點,但是做該像素範圍的最大值和最小值看起來好多了! – andrewrk 2010-05-06 06:15:51