Создание изображения из текста и накладывание одного изображения на другое.
This commit is contained in:
parent
9af7778b77
commit
38655e9c1b
5 changed files with 69 additions and 27 deletions
45
bmpimage.cpp
45
bmpimage.cpp
|
@ -94,11 +94,20 @@ BMPImage BMPImage::appendRight(BMPImage &img) {
|
|||
return {newPixelArray};
|
||||
}
|
||||
|
||||
BMPImage BMPImage::overlay(BMPImage &img, uint32_t pos_x, uint32_t pos_y) {
|
||||
if (pos_x + img.width() > this->width() || pos_y + img.height() > this->height())
|
||||
throw std::runtime_error("The overlaid image is outside the image");
|
||||
auto pixels = this->pixels_copy();
|
||||
for (int i = 0; i < img.height(); ++i) {
|
||||
std::copy(img.pixels()(i), img.pixels()(i) + img.width(), pixels(pos_y + i) + pos_x);
|
||||
}
|
||||
return {pixels};
|
||||
}
|
||||
|
||||
|
||||
BMPImage readBMPImage(const std::string &filename) {
|
||||
BitmapFileHeader bitmapFileHeader;
|
||||
BITMAPINFOHEADER bitmapInfoHeader;
|
||||
// Pixel **pixelArray;
|
||||
uint32_t DIB_Header_Size;
|
||||
{
|
||||
std::ifstream ifs(filename, std::ios_base::binary);
|
||||
|
@ -207,13 +216,10 @@ Pixel operator-(const Pixel &p, const uint8_t &n) {
|
|||
|
||||
BMPImage upscale2x(BMPImage &img) {
|
||||
auto oldPixels = img.pixels();
|
||||
// Pixel **newPixelArray;
|
||||
const uint32_t newHeight = img.height() * 2;
|
||||
const uint32_t newWidth = img.width() * 2;
|
||||
// newPixelArray = new Pixel *[newHeight];
|
||||
PixelArray newPixelArray(newWidth, newHeight);
|
||||
for (int i = 0; i < newHeight; i += 2) {
|
||||
// newPixelArray(i) = new Pixel[newWidth];
|
||||
for (int j = 0; j < newWidth; ++j) {
|
||||
if (j % 2 == 0)
|
||||
newPixelArray(i, j) = oldPixels(i / 2, j / 2);
|
||||
|
@ -224,7 +230,6 @@ BMPImage upscale2x(BMPImage &img) {
|
|||
}
|
||||
}
|
||||
for (int i = 1; i < newHeight; i += 2) {
|
||||
// newPixelArray(i) = new Pixel[newWidth];
|
||||
if (i == newHeight - 1)
|
||||
for (int j = 0; j < newWidth; ++j) {
|
||||
newPixelArray(i, j) = newPixelArray(i - 1, j) / 2;
|
||||
|
@ -235,35 +240,27 @@ BMPImage upscale2x(BMPImage &img) {
|
|||
}
|
||||
}
|
||||
return {newPixelArray};
|
||||
// return BMPImage(newPixelArray, newWidth, newHeight);
|
||||
}
|
||||
|
||||
BMPImage downscale2x(BMPImage &img) {
|
||||
// Pixel **newPixelArray;
|
||||
auto oldPixels = img.pixels_copy();
|
||||
const uint32_t newHeight = img.height() / 2;
|
||||
const uint32_t newWidth = img.width() / 2;
|
||||
PixelArray newPixelArray(newWidth, newHeight);
|
||||
// newPixelArray = new Pixel *[newHeight];
|
||||
for (int i = 0; i < newHeight; ++i) {
|
||||
// newPixelArray(i) = new Pixel[newWidth];
|
||||
for (int j = 0; j < newWidth; ++j) {
|
||||
newPixelArray(i, j) = oldPixels(i * 2, j * 2);
|
||||
}
|
||||
}
|
||||
// return BMPImage(newPixelArray, newWidth, newHeight);
|
||||
return {newPixelArray};
|
||||
}
|
||||
|
||||
BMPImage upscale1_5x(BMPImage &img) {
|
||||
auto oldPixels = img.pixels();
|
||||
// Pixel **newPixelArray;
|
||||
const uint32_t newHeight = img.height() * 3 / 2;
|
||||
const uint32_t newWidth = img.width() * 3 / 2;
|
||||
PixelArray newPixelArray(newWidth, newHeight);
|
||||
// newPixelArray = new Pixel *[newHeight];
|
||||
for (int i = 0; i < newHeight; ++i) {
|
||||
// newPixelArray(i) = new Pixel[newWidth];
|
||||
if ((i + 1) % 3 == 0) continue;
|
||||
for (int j = 0; j < newWidth; ++j) {
|
||||
int oldi = i * 2 / 3;
|
||||
|
@ -290,6 +287,28 @@ BMPImage upscale1_5x(BMPImage &img) {
|
|||
|
||||
}
|
||||
|
||||
BMPImage textImg(const std::u16string &str, Font *font, uint8_t scale, Pixel background_color, Pixel font_color) {
|
||||
auto strSize = str.size();
|
||||
uint32_t glyphHeight = font->glyphHeight;
|
||||
uint32_t glyphWidth = font->glyphWidth;
|
||||
uint32_t imgWidth = strSize * glyphWidth * scale;
|
||||
uint32_t imgHeight = glyphHeight * scale;
|
||||
PixelArray pixels(imgWidth, imgHeight);
|
||||
for (int i = 0; i < strSize; ++i) {
|
||||
auto glyph = font->_glyphs[str[i]];
|
||||
for (int j = 0; j < glyphHeight * scale; ++j) {
|
||||
for (int l = 0; l < glyphWidth * scale; ++l) {
|
||||
if (glyph.glyph[j / scale][l / scale])
|
||||
pixels(j, glyphWidth * scale * i + l) = font_color;
|
||||
else
|
||||
pixels(j, glyphWidth * scale * i + l) = background_color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return {pixels};
|
||||
}
|
||||
|
||||
PixelArray::PixelArray(uint32_t width, uint32_t height) {
|
||||
this->_width = width;
|
||||
this->_height = height;
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <fstream>
|
||||
#include "psf.h"
|
||||
|
||||
const char PADDING_ZEROES[3] = {0, 0, 0};
|
||||
|
||||
|
@ -88,6 +89,8 @@ public:
|
|||
void save(const std::string &);
|
||||
|
||||
BMPImage appendRight(BMPImage &);
|
||||
|
||||
BMPImage overlay(BMPImage &, uint32_t, uint32_t);
|
||||
};
|
||||
|
||||
BMPImage readBMPImage(const std::string &filename);
|
||||
|
@ -112,4 +115,7 @@ BMPImage downscale2x(BMPImage &);
|
|||
|
||||
BMPImage upscale1_5x(BMPImage &);
|
||||
|
||||
BMPImage textImg(const std::u16string &, Font *font, uint8_t scale = 1, Pixel background_color = Pixel{0, 0, 0},
|
||||
Pixel font_color = Pixel{255, 255, 255});
|
||||
|
||||
uint8_t ui8_clamp(int value, uint8_t min = 0, uint8_t max = 255);
|
33
main.cpp
33
main.cpp
|
@ -4,6 +4,7 @@
|
|||
|
||||
const std::string FILENAME = "../elef.bmp";
|
||||
const std::string FILENAME_OUT = "../elef_out.bmp";
|
||||
auto font = readPSF("../fonts/ruscii_8x16_2.psf");
|
||||
|
||||
//
|
||||
void lab01() {
|
||||
|
@ -16,12 +17,18 @@ void lab01() {
|
|||
pixels2(i, j) = pixels2(i, j) * 2;
|
||||
}
|
||||
}
|
||||
auto darkenImg = BMPImage(pixels1);
|
||||
auto lighterImg = BMPImage(pixels2);
|
||||
auto invert_img = invertColors(og_image); // TODO
|
||||
auto grayscale_img = grayscale(og_image);
|
||||
og_image.appendRight(lighterImg).appendRight(darkenImg).appendRight(invert_img).appendRight(grayscale_img).save(
|
||||
"../lab01/elef1.bmp");
|
||||
auto orig_text = textImg(u"Оригинал", &font, 3);
|
||||
auto darken_text = textImg(u"Темнее", &font, 3);
|
||||
auto lighter_text = textImg(u"Светлее", &font, 3);
|
||||
auto invert_text = textImg(u"Инвертирован", &font, 3);
|
||||
auto grayscale_text = textImg(u"Оттенки серого", &font, 3);
|
||||
auto darkenImg = BMPImage(pixels1).overlay(darken_text, 0, 0);
|
||||
auto lighterImg = BMPImage(pixels2).overlay(lighter_text, 0, 0);
|
||||
auto invert_img = invertColors(og_image).overlay(invert_text, 0, 0); // TODO
|
||||
auto grayscale_img = grayscale(og_image).overlay(grayscale_text, 0, 0);
|
||||
|
||||
og_image.appendRight(lighterImg).appendRight(darkenImg).appendRight(invert_img).appendRight(grayscale_img).overlay(
|
||||
orig_text, 0, 0).save("../lab01/elef1.bmp");
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -123,13 +130,12 @@ void test() {
|
|||
void test2() {
|
||||
auto background_color = Pixel{0, 0, 0};
|
||||
auto font_color = Pixel{255, 255, 255};
|
||||
auto font = readPSF("../fonts/ruscii_8x16_2.psf");
|
||||
auto glyph = font._glyphs[u'б'];
|
||||
auto w = glyph.width;
|
||||
auto h = glyph.height;
|
||||
|
||||
int imgWidth = 16 * glyph.width;
|
||||
int imgHeight = 16 * glyph.height;
|
||||
uint32_t imgWidth = 16 * glyph.width;
|
||||
uint32_t imgHeight = 16 * glyph.height;
|
||||
PixelArray test(imgWidth, imgHeight);
|
||||
std::u16string str = u"Hello, World! Привет, Мир!";
|
||||
uint32_t k = 0;
|
||||
|
@ -151,12 +157,17 @@ void test2() {
|
|||
BMPImage(test).save("test_font.bmp");
|
||||
}
|
||||
|
||||
void test3() {
|
||||
textImg(u"Привет, Мир!", &font).save("../font_test.bmp");
|
||||
}
|
||||
|
||||
int main() {
|
||||
// lab01();
|
||||
lab01();
|
||||
// lab02_01();
|
||||
// lab02_02();
|
||||
// lab02_03();
|
||||
// test();
|
||||
test2();
|
||||
// test2();
|
||||
// test3();
|
||||
return 0;
|
||||
}
|
||||
|
|
7
psf.cpp
7
psf.cpp
|
@ -24,7 +24,7 @@ Font readPSF(const std::string &filename) {
|
|||
if (magicNumber[0] != 0x72 || magicNumber[1] != 0xb5 || magicNumber[2] != 0x4a || magicNumber[3] != 0x86)
|
||||
throw std::runtime_error("Invalid font file");
|
||||
ifs.read((char *) &psf2Header, sizeof(psf2Header));
|
||||
auto font = Font(psf2Header.numberOfGlyphs);
|
||||
auto font = Font(psf2Header.numberOfGlyphs, psf2Header.glyphWidth, psf2Header.glyphHeight);
|
||||
Glyph glyphs[psf2Header.numberOfGlyphs];
|
||||
for (int i = 0; i < psf2Header.numberOfGlyphs; ++i) {
|
||||
auto glyph = Glyph(psf2Header.glyphWidth, psf2Header.glyphHeight);
|
||||
|
@ -83,7 +83,10 @@ Glyph::Glyph() {
|
|||
|
||||
}
|
||||
|
||||
Font::Font(uint32_t glyphs) {
|
||||
Font::Font(uint32_t glyphsCount, uint32_t glyphWidth, uint32_t glyphHeight) {
|
||||
this->glyphsCount = glyphsCount;
|
||||
this->glyphWidth = glyphWidth;
|
||||
this->glyphHeight = glyphHeight;
|
||||
}
|
||||
|
||||
Font::Font() {
|
||||
|
|
5
psf.h
5
psf.h
|
@ -40,10 +40,13 @@ public:
|
|||
class Font {
|
||||
public:
|
||||
std::map<char16_t, Glyph> _glyphs;
|
||||
uint32_t glyphWidth;
|
||||
uint32_t glyphHeight;
|
||||
uint32_t glyphsCount;
|
||||
|
||||
Font();
|
||||
|
||||
Font(uint32_t glyphs);
|
||||
explicit Font(uint32_t glyphs, uint32_t glyphWidth, uint32_t glyphHeight);
|
||||
};
|
||||
|
||||
Font readPSF(const std::string &filename);
|
Loading…
Add table
Reference in a new issue