Files
Renderive/Core/primitive/Raster_Image_p.h
T
2026-08-02 16:02:15 +08:00

83 lines
3.1 KiB
C++

#pragma once
#include <algorithm>
#include <cmath>
#include <utility>
#include "../architecture/Render_Lease.h"
#include "../base/Color.h"
#include "../base/Geometry.h"
#include "../plottable/Interpolation_p.h"
#include "../render/Canvas.h"
#include "../render/Image.h"
#include "Color_Map.h"
#include "Raster_Image.h"
namespace renderive {
class Raster_Image_Buffer {
public:
[[nodiscard]] int width() const {
return image_data.width();
}
[[nodiscard]] int height() const {
return image_data.height();
}
[[nodiscard]] bool is_null() const {
return image_data.empty();
}
[[nodiscard]] const Image& image() const {
return image_data;
}
Image& image() {
return image_data;
}
void set_image(Image image) {
image_data = std::move(image);
}
void resize(int width, int height) {
image_data.resize(width, height);
}
void fill(Color color) {
image_data.fill(color);
}
Pixel* row(int row) {
return image_data.row(row);
}
void write_color_mapped_row(int row_index, const double* values, int first_col, int last_col, double value_start_coord, double rate, const Color_Map& color_map, Color background_color) {
Pixel* line = row(row_index);
Pixel bg = premultiply(background_color);
std::fill(line, line + image_data.width(), bg);
for (int col = first_col; col <= last_col; ++col) {
int color_offset = static_cast<int>((values[col] - value_start_coord) * rate);
line[col] = color_map.at_offset(color_offset);
}
}
void write_normalized_grid(const double* values, int width, int height, const Color_Map& color_map) {
for (int row_index = 0; row_index < height; ++row_index) {
Pixel* line = row(row_index);
const double* source = values + row_index * width;
for (int col = 0; col < width; ++col) {
line[col] = color_map.at_normalized(source[col]);
}
}
}
void draw(Canvas& canvas, const RectF& target_rect, Image_Interpolation_Mode mode = Image_Interpolation_Mode::Nearest) const {
draw(canvas, target_rect, RectF{0.0, 0.0, static_cast<double>(image_data.width()), static_cast<double>(image_data.height())}, mode);
}
void draw(Canvas& canvas, const RectF& target_rect, const RectF& source_rect, Image_Interpolation_Mode mode) const {
if (image_data.empty())
return;
canvas.save();
if (mode == Image_Interpolation_Mode::Bicubic) {
Size target_size{std::max(1, static_cast<int>(std::ceil(std::abs(target_rect.width)))), std::max(1, static_cast<int>(std::ceil(std::abs(target_rect.height))))};
Image scaled_image = bicubic_scale(image_data, source_rect, target_size);
canvas.draw_image(target_rect, scaled_image);
}
else {
canvas.set_image_interpolation(mode);
canvas.draw_image(target_rect, image_data, source_rect);
}
canvas.restore();
}
private:
Image image_data;
};
} // namespace renderive