Система фильтрации

This commit is contained in:
Евгений Титаренко 2024-04-11 19:33:22 +03:00
parent 38655e9c1b
commit 24e2cbb354
3 changed files with 232 additions and 34 deletions

View file

@ -1,3 +1,4 @@
#include <cmath>
#include "bmpimage.h"
BMPImage::BMPImage(const BitmapFileHeader &fileHeader, const BITMAPINFOHEADER &infoHeader, const PixelArray &pixelArray)
@ -149,9 +150,9 @@ BMPImage readBMPImage(const std::string &filename) {
}
Pixel operator+(const Pixel &p1, const Pixel &p2) {
const uint8_t r = p1.r + p2.r;
const uint8_t g = p1.g + p2.g;
const uint8_t b = p1.b + p2.b;
const uint8_t r = ui8_clamp((int) p1.r + p2.r);
const uint8_t g = ui8_clamp((int) p1.g + p2.g);
const uint8_t b = ui8_clamp((int) p1.b + p2.b);
return {r, g, b};
}
@ -284,7 +285,6 @@ BMPImage upscale1_5x(BMPImage &img) {
}
}
return {newPixelArray};
}
BMPImage textImg(const std::u16string &str, Font *font, uint8_t scale, Pixel background_color, Pixel font_color) {
@ -309,6 +309,128 @@ BMPImage textImg(const std::u16string &str, Font *font, uint8_t scale, Pixel bac
return {pixels};
}
BMPImage upscale1_5x_ver2(BMPImage &img) {
auto oldPixels = img.pixels();
const uint32_t newHeight = img.height() * 3 / 2;
const uint32_t newWidth = img.width() * 3 / 2;
PixelArray newPixelArray(newWidth, newHeight);
for (int i = 0; i < newHeight; ++i) {
int oldi = std::round(i * 2 / 3.);
if ((i + 1) % 3 == 0) {
if (i == newHeight - 1)
newPixelArray(i, 0) = oldPixels(oldi, 0) / 2;
else {
newPixelArray(i, 0) = oldPixels(oldi, 0) / 2 + oldPixels(oldi + 1, 0) / 2;
}
continue;
}
for (int j = 0; j < newWidth; ++j) {
int oldj = std::round(j * 2 / 3.);
if ((j + 1) % 3 != 0)
newPixelArray(i, j) = oldPixels(oldi, oldj);
else if (j == newWidth - 1)
newPixelArray(i, j) = oldPixels(oldi, oldj) / 2;
else
newPixelArray(i, j) = oldPixels(oldi, oldj) / 2 + oldPixels(oldi, oldj + 1) / 2;
}
}
for (int i = 2; i < newHeight; i += 3) {
if (i == newHeight - 1)
for (int j = 0; j < newWidth; ++j) {
newPixelArray(i, j) = newPixelArray(i - 1, j) / 2;
}
else
for (int j = 1; j < newWidth; ++j) {
if (j == newWidth - 1) {
newPixelArray(i, j) = newPixelArray(i, j - 1) / 2;
continue;
}
auto f00 = newPixelArray(i - 1, j - 1);
auto f10 = newPixelArray(i - 1, j + 1);
auto f01 = newPixelArray(i + 1, j - 1);
auto f11 = newPixelArray(i + 1, j + 1);
newPixelArray(i, j) = f10 / 4 + f00 / 4 + f01 / 4 + f11 / 4;
}
}
return {newPixelArray};
}
Pixel operator-(const Pixel &p1, const Pixel &p2) {
auto r = ui8_clamp((int) p1.r - p2.r);
auto g = ui8_clamp((int) p1.g - p2.g);
auto b = ui8_clamp((int) p1.b - p2.b);
return {r, g, b};
}
BMPImage upscale2x_ver2(BMPImage &img) {
auto oldPixels = img.pixels();
const uint32_t newHeight = img.height() * 2;
const uint32_t newWidth = img.width() * 2;
PixelArray newPixelArray(newWidth, newHeight);
for (int i = 0; i < newHeight; ++i) {
if ((i + 1) % 2 == 0) {
if (i == newHeight - 1)
newPixelArray(i, 0) = oldPixels(i / 2, 0) / 2;
else
newPixelArray(i, 0) = oldPixels(i / 2, 0) / 2 + oldPixels(i / 2 + 1, 0) / 2;
continue;
}
for (int j = 0; j < newWidth; ++j) {
if (j % 2 == 0)
newPixelArray(i, j) = oldPixels(i / 2, j / 2);
else if (j == newWidth - 1)
newPixelArray(i, j) = oldPixels(i / 2, j / 2) / 2;
else
newPixelArray(i, j) = oldPixels(i / 2, j / 2) / 2 + oldPixels(i / 2, j / 2 + 1) / 2;
}
}
for (int i = 1; i < newHeight; i += 2) {
if (i == newHeight - 1)
for (int j = 1; j < newWidth; ++j) {
newPixelArray(i, j) = newPixelArray(i - 1, j) / 2;
}
else
for (int j = 1; j < newWidth; ++j) {
if (j == newWidth - 1) {
newPixelArray(i, j) = newPixelArray(i, j - 1) / 2;
continue;
}
auto f00 = newPixelArray(i - 1, j - 1);
auto f10 = newPixelArray(i - 1, j + 1);
auto f01 = newPixelArray(i + 1, j - 1);
auto f11 = newPixelArray(i + 1, j + 1);
newPixelArray(i, j) = f10 / 4 + f00 / 4 + f01 / 4 + f11 / 4;
}
}
return {newPixelArray};
}
BMPImage filter(BMPImage &img, int mask[9], uint8_t modifier) {
auto origPixels = img.pixels_copy();
PixelArray pixels(img.width(), img.height());
for (int y = 1; y < img.height() - 1; ++y) {
for (int x = 1; x < img.width() - 1; ++x) {
auto p1 = origPixels(y - 1, x - 1);
auto p2 = origPixels(y - 1, x);
auto p3 = origPixels(y - 1, x + 1);
auto p4 = origPixels(y, x - 1);
auto p5 = origPixels(y, x);
auto p6 = origPixels(y, x + 1);
auto p7 = origPixels(y + 1, x - 1);
auto p8 = origPixels(y + 1, x);
auto p9 = origPixels(y + 1, x + 1);
auto r = p1.r * mask[0] + p2.r * mask[1] + p3.r * mask[2] + p4.r * mask[3] + p5.r * mask[4] +
p6.r * mask[5] + p7.r * mask[6] + p8.r * mask[7] + p9.r * mask[8];
auto g = p1.g * mask[0] + p2.g * mask[1] + p3.g * mask[2] + p4.g * mask[3] + p5.g * mask[4] +
p6.g * mask[5] + p7.g * mask[6] + p8.g * mask[7] + p9.g * mask[8];
auto b = p1.b * mask[0] + p2.b * mask[1] + p3.b * mask[2] + p4.b * mask[3] + p5.b * mask[4] +
p6.b * mask[5] + p7.b * mask[6] + p8.b * mask[7] + p9.b * mask[8];
pixels(y, x) = {ui8_clamp(r / modifier), ui8_clamp(g / modifier), ui8_clamp(b / modifier)};
}
}
return {pixels};
}
PixelArray::PixelArray(uint32_t width, uint32_t height) {
this->_width = width;
this->_height = height;