forked from swharden/Spectrogram
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathImage.cs
More file actions
104 lines (88 loc) · 3.61 KB
/
Image.cs
File metadata and controls
104 lines (88 loc) · 3.61 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;
namespace Spectrogram
{
class Image
{
public static Bitmap BitmapFromFFTs(float[][] ffts, Settings.DisplaySettings displaySettings)
{
if (ffts == null || ffts.Length == 0)
throw new ArgumentException("ffts must contain float arrays");
Bitmap bmp = new Bitmap(ffts.Length, displaySettings.height, PixelFormat.Format8bppIndexed);
ApplyColormap(bmp, displaySettings.colormap);
var rect = new Rectangle(0, 0, bmp.Width, bmp.Height);
BitmapData bitmapData = bmp.LockBits(rect, ImageLockMode.ReadOnly, bmp.PixelFormat);
byte[] pixels = new byte[bitmapData.Stride * bmp.Height];
for (int col = 0; col < bmp.Width; col++)
{
if (col >= bmp.Width)
continue;
if (col == displaySettings.highlightColumn)
{
for (int row = 0; row < bmp.Height; row++)
{
int bytePosition = (bmp.Height - 1 - row) * bitmapData.Stride + col;
pixels[bytePosition] = 255;
}
continue;
}
if (ffts[col] == null)
continue;
for (int row = 0; row < bmp.Height; row++)
{
int bytePosition = (bmp.Height - 1 - row) * bitmapData.Stride + col;
float pixelValue;
pixelValue = ffts[col][row + displaySettings.pixelLower];
if (displaySettings.decibels)
pixelValue = (float)(Math.Log10(pixelValue) * 20);
pixelValue = (pixelValue * displaySettings.brightness);
pixelValue = Math.Max(0, pixelValue);
pixelValue = Math.Min(255, pixelValue);
pixels[bytePosition] = (byte)(pixelValue);
}
}
Marshal.Copy(pixels, 0, bitmapData.Scan0, pixels.Length);
bmp.UnlockBits(bitmapData);
return bmp;
}
public static Bitmap Rotate(Bitmap bmpIn, float angle = 90)
{
// TODO: this could be faster with byte manipulation since it's 90 degrees
if (bmpIn == null)
return null;
Bitmap bmp = new Bitmap(bmpIn);
Bitmap bmpRotated = new Bitmap(bmp.Height, bmp.Width);
Graphics gfx = Graphics.FromImage(bmpRotated);
gfx.RotateTransform(angle);
gfx.DrawImage(bmp, new Point(0, -bmp.Height));
return bmpRotated;
}
public static void ApplyColormap(Bitmap bmp, Colormap colormap)
{
switch (colormap)
{
case Colormap.grayscale:
new Colormaps.Grayscale().Apply(bmp);
break;
case Colormap.grayscaleInverted:
new Colormaps.GrayscaleInverted().Apply(bmp);
break;
case Colormap.vdBlue:
new Colormaps.VdBlues().Apply(bmp);
break;
case Colormap.vdGreen:
new Colormaps.VdGreens().Apply(bmp);
break;
case Colormap.viridis:
new Colormaps.Viridis().Apply(bmp);
break;
default:
throw new NotImplementedException();
}
}
}
}