Files
HPPA/HPPA/RasterRenderer.cpp
tangchao0503 bdf956ed99 1、为图层添加渲染器和读取器,分离图层基础信息、渲染和读写;
2、LayerTreeLayerNode持有MapLayer图层引用,为右键菜单做准备;
3、改名:imageviewer → mapcavas,mapcavas持有MapLayer图层引用,为刷新图像做准备;
2026-03-02 11:49:46 +08:00

87 lines
3.0 KiB
C++

#include "RasterRenderer.h"
#include "RasterDataProvider.h"
#include <QDebug>
#include <algorithm>
RasterRenderer::RasterRenderer(RasterDataProvider* provider)
: m_provider(provider)
{
}
void RasterRenderer::stretchTo8bit(const std::vector<float>& in, std::vector<unsigned char>& out, float minVal, float maxVal)
{
size_t n = in.size();
out.resize(n);
if (maxVal <= minVal) {
std::fill(out.begin(), out.end(), 0);
return;
}
float denom = 1.0f / (maxVal - minVal);
for (size_t i = 0; i < n; ++i) {
float v = (in[i] - minVal) * denom;
v = std::min(std::max(v, 0.0f), 1.0f);
out[i] = static_cast<unsigned char>(v * 255.0f);
}
}
QImage RasterRenderer::render(const Params& params)
{
if (!m_provider) return QImage();
int bands = m_provider->bandCount();
int w = m_provider->width();
int h = m_provider->height();
if (w <= 0 || h <= 0) return QImage();
// Find nearest bands for requested wavelengths if wavelengths available
std::vector<double> wavelengths = m_provider->bandWavelengths();
auto chooseBandIndexForWave = [&](double wave)->int {
if (wavelengths.empty()) {
// fallback: select R,G,B as first three bands
if (bands >= 3) return (wave==params.rWave?0:(wave==params.gWave?1:2));
if (bands >= 1) return 0;
return -1;
}
int best = -1; double bestDiff = 1e12;
for (int i = 0; i < (int)wavelengths.size(); ++i) {
if (wavelengths[i] < 0) continue;
double d = std::abs(wavelengths[i] - wave);
if (d < bestDiff) { bestDiff = d; best = i; }
}
if (best >= 0) return best;
// fallback
return std::min(2, bands-1);
};
int rIdx = chooseBandIndexForWave(params.rWave);
int gIdx = chooseBandIndexForWave(params.gWave);
int bIdx = chooseBandIndexForWave(params.bWave);
std::vector<float> rbuf, gbuf, bbuf;
if (rIdx >= 0) m_provider->readBandAsFloat(rIdx, rbuf);
if (gIdx >= 0) m_provider->readBandAsFloat(gIdx, gbuf);
if (bIdx >= 0) m_provider->readBandAsFloat(bIdx, bbuf);
std::vector<unsigned char> r8, g8, b8;
float minV = static_cast<float>(params.minValue);
float maxV = static_cast<float>(params.maxValue);
if (!rbuf.empty()) stretchTo8bit(rbuf, r8, minV, maxV);
if (!gbuf.empty()) stretchTo8bit(gbuf, g8, minV, maxV);
if (!bbuf.empty()) stretchTo8bit(bbuf, b8, minV, maxV);
QImage out(w, h, QImage::Format_RGB888);
for (int y = 0; y < h; ++y) {
unsigned char* scan = out.scanLine(y);
for (int x = 0; x < w; ++x) {
int idx = y * w + x;
unsigned char rc = (r8.size() > (size_t)idx) ? r8[idx] : 0;
unsigned char gc = (g8.size() > (size_t)idx) ? g8[idx] : 0;
unsigned char bc = (b8.size() > (size_t)idx) ? b8[idx] : 0;
scan[x*3 + 0] = rc;
scan[x*3 + 1] = gc;
scan[x*3 + 2] = bc;
}
}
return out;
}