fix: align PNG export crop with displayed frequency axis
The spectrogram image spans the full Nyquist axis, but sel.freq* are fractions of the displayed axis (capped at EffectiveMaxFreqHz). ExportPNG mapped the selection straight onto the full image height, so when the display max frequency was below Nyquist the export grabbed a band higher in frequency than the box-select. Scale by DisplayFreqFraction() to match the on-screen texture sub-sampling. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -266,11 +266,16 @@ void ExportPNG(const SpectrogramApp* spa, const char* dirPath)
|
|||||||
int imgW = spa->spectrogramImage.width;
|
int imgW = spa->spectrogramImage.width;
|
||||||
int imgH = spa->spectrogramImage.height;
|
int imgH = spa->spectrogramImage.height;
|
||||||
|
|
||||||
// Selection region in image-pixel coordinates
|
// Selection region in image-pixel coordinates. The image spans the full
|
||||||
|
// Nyquist axis, but sel.freq* are fractions of the *displayed* axis (capped
|
||||||
|
// at EffectiveMaxFreqHz), so scale by DisplayFreqFraction() the same way the
|
||||||
|
// on-screen texture sub-sampling does — otherwise the export grabs a band
|
||||||
|
// higher in frequency than what was box-selected.
|
||||||
|
float cropFrac = DisplayFreqFraction();
|
||||||
int selX0 = (int)(spa->sel.timeStart * imgW);
|
int selX0 = (int)(spa->sel.timeStart * imgW);
|
||||||
int selX1 = (int)(spa->sel.timeEnd * imgW);
|
int selX1 = (int)(spa->sel.timeEnd * imgW);
|
||||||
int selY0 = (int)((1.0f - spa->sel.freqEnd) * imgH);
|
int selY0 = (int)((1.0f - spa->sel.freqEnd * cropFrac) * imgH);
|
||||||
int selY1 = (int)((1.0f - spa->sel.freqStart) * imgH);
|
int selY1 = (int)((1.0f - spa->sel.freqStart * cropFrac) * imgH);
|
||||||
|
|
||||||
// Clamp to image bounds
|
// Clamp to image bounds
|
||||||
selX0 = Clamp(selX0, 0, imgW);
|
selX0 = Clamp(selX0, 0, imgW);
|
||||||
|
|||||||
Reference in New Issue
Block a user