Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature Request: Image Rotation #47

Closed
wiiNinja opened this issue Jul 10, 2022 · 6 comments · Fixed by #48
Closed

Feature Request: Image Rotation #47

wiiNinja opened this issue Jul 10, 2022 · 6 comments · Fixed by #48

Comments

@wiiNinja
Copy link

I'm writing an app that has a visual audio waterfall component. This component is almost exactly what I need, except that the display flows from right to left instead of top to bottom. I found that before I draw the image, I can rotate it 270 degrees to achieve this effect, but it's not as clean as if the component itself can be configured to do so from the start. So this is a request for that feature. If you don't have time to do it, can you suggest a way to do this using your component? Thanks for giving a really nice and useful component.

@swharden
Copy link
Owner

Hi @wiiNinja,

I think the best way to implement this would be to write your own image generator (copy/pasting the existing one, making a few tactical edits). After creating a SpectrogramGenerator and loading it with data, instead of calling its GetBitmap() method you would instead call GetFFTs() and pass that result into your own method almost identical to the one below, but which creates a rotated image.

public static Bitmap GetBitmap(
List<double[]> ffts,
Colormap cmap,
double intensity = 1,
bool dB = false,
double dBScale = 1,
bool roll = false,
int rollOffset = 0)
{
if (ffts.Count == 0)
throw new ArgumentException("Not enough data in FFTs to generate an image yet.");
int Width = ffts.Count;
int Height = ffts[0].Length;
Bitmap bmp = new Bitmap(Width, Height, PixelFormat.Format8bppIndexed);
cmap.Apply(bmp);
var lockRect = new Rectangle(0, 0, Width, Height);
BitmapData bitmapData = bmp.LockBits(lockRect, ImageLockMode.ReadOnly, bmp.PixelFormat);
int stride = bitmapData.Stride;
byte[] bytes = new byte[bitmapData.Stride * bmp.Height];
Parallel.For(0, Width, col =>
{
int sourceCol = col;
if (roll)
{
sourceCol += Width - rollOffset % Width;
if (sourceCol >= Width)
sourceCol -= Width;
}
for (int row = 0; row < Height; row++)
{
double value = ffts[sourceCol][row];
if (dB)
value = 20 * Math.Log10(value * dBScale + 1);
value *= intensity;
value = Math.Min(value, 255);
int bytePosition = (Height - 1 - row) * stride + col;
bytes[bytePosition] = (byte)value;
}
});
Marshal.Copy(bytes, 0, bitmapData.Scan0, bytes.Length);
bmp.UnlockBits(bitmapData);
return bmp;
}
}

That should be enough to get you started! I'll try to implement this today and if it's as easy as I think it is I'll name it something like GetBitmapVertical and publish an updated package. I'll follow-up here to report what I find either way.

swharden added a commit that referenced this issue Jul 10, 2022
@swharden
Copy link
Owner

I added a rotate argument to Spectrogram.GetBitmap() in #48 and will release Spectrogram 1.6 in a few minutes

I hacked-in a checkbox to the demo app to show how it works, and you can see the spectrogram operates as expected but there is not support to draw a horizontal frequency scale. I hope you still find this useful!

rotate.mp4

@swharden swharden changed the title Feature Request: Make the image Feature Request: Image Rotation Jul 10, 2022
@swharden
Copy link
Owner

SpectrogramGenerator sg = new(44100, 4096, 500, maxFreq: 3000);
sg.Add(audio);

System.Drawing.Bitmap bmp1 = sg.GetBitmap(rotate: false);
bmp1.Save("test-image-original.png");

System.Drawing.Bitmap bmp2 = sg.GetBitmap(rotate: true);
bmp2.Save("test-image-rotated.png");
original rotated
test-image-original test-image-rotated

@swharden
Copy link
Owner

doh! I just realized it's upside-down 🤦

@swharden swharden reopened this Jul 10, 2022
@swharden
Copy link
Owner

Fixed

original rotated
test-image-original test-image-rotated

@wiiNinja
Copy link
Author

wiiNinja commented Jul 10, 2022

:) I do appreciate it very much. Definitely helps.
Edit: Snapshot of things working. The "Morse Keyer V4.3" in the screenshot is an external app that triggers the audio. Thanks again.
screenshot 3

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants