Punchcard

image.h

Mar 27th, 2024
362
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.13 KB | Source Code | 0 0
  1. #pragma once
  2.  
  3. #include <ostream>
  4. #include <sstream>
  5. #include <stdexcept>
  6. #include <vector>
  7.  
  8. #include "cow.h"
  9. #include "geom.h"
  10. #include "tile.h"
  11.  
  12. class Image {
  13. public:
  14.     /**
  15.      * Конструирует изображение заданного размера. Если размеры не являются положительными,
  16.      * выбрасывает исключение std::out_of_range.
  17.      */
  18.     explicit Image(Size size, char color = ' ')
  19.         : size_{size.width > 0 && size.height > 0 ? size
  20.                                                   : throw std::out_of_range("Invalid image size")}
  21.         , size_in_tiles_{(size_.width + Tile::SIZE - 1) / Tile::SIZE,
  22.                          (size_.height + Tile::SIZE - 1) / Tile::SIZE}
  23.         , tiles_{static_cast<size_t>(size_in_tiles_.width * size_in_tiles_.height),
  24.                  CoWTile{Tile{color}}} {
  25.     }
  26.  
  27.     // Возвращает размер изображения в пикселях.
  28.     Size GetSize() const noexcept {
  29.         /* Реализуйте метод самостоятельно. */
  30.  
  31.         return {size_.width, size_.height};
  32.     }
  33.  
  34.     /**
  35.      * Возвращает «цвет» пикселя в указанных координатах.Если координаты выходят за пределы
  36.      * изображения, возвращает «пробел».
  37.      */
  38.     char GetPixel(Point p) const noexcept {
  39.         /* Реализуйте метод самостоятельно. */
  40.         if (!IsPointInSize(p, size_)) return ' ';
  41.         int tile_no = GetTileIndex(p);
  42.         return tiles_[tile_no]->GetPixel({p.x%Tile::SIZE, p.y%Tile::SIZE});
  43.     }
  44.  
  45.     /**
  46.      * Задаёт «цвет» пикселя в указанных координатах. Если координаты выходят за пределы изображения
  47.      * действие игнорируется.
  48.      */
  49.     void SetPixel(Point p, char color) {
  50.         /* Реализуйте метод самостоятельно. */
  51.         if (IsPointInSize(p, size_)) {
  52.             int tile_no = GetTileIndex(p);         
  53.             tiles_[tile_no].Write()->SetPixel({p.x%Tile::SIZE, p.y%Tile::SIZE}, color);
  54.         }
  55.     }
  56.  
  57. private:
  58.     using CoWTile = CoW<Tile>;
  59.  
  60.     // Возвращает порядковый номер тайла, в котором находится пиксель с координатами p
  61.     int GetTileIndex(Point p) const noexcept {
  62.         assert((p.x >= 0) && (p.x < size_.width) && (p.y >= 0) && (p.y < size_.height));
  63.         return (p.y / Tile::SIZE) * size_in_tiles_.width + (p.x / Tile::SIZE);
  64.     }
  65.  
  66.     Size size_;                   // Размер изображения в пикселях.
  67.     Size size_in_tiles_;          // Размер изображения в тайлах.
  68.     std::vector<CoWTile> tiles_;  // Тайлы изображения (строка за строкой).
  69. };
  70.  
  71. /**
  72.  * Выводит в поток out изображение в виде символов.
  73.  */
  74. inline void Print(const Image& img, std::ostream& out) {
  75.     const auto size = img.GetSize();
  76.     for (int y = 0; y < size.height; ++y) {
  77.         for (int x = 0; x < size.width; ++x) {
  78.             out.put(img.GetPixel({x, y}));
  79.         }
  80.         out.put('\n');
  81.     }
  82. }
  83.  
  84. /**
  85.  * Загружает изображение из pixels. Линии изображения разделяются символами \n.
  86.  * Размеры картинки определяются по количеству переводов строки и самой длинной линии.
  87.  */
  88. inline Image LoadImage(const std::string& pixels) {
  89.     std::istringstream s(pixels);
  90.     Size size;
  91.     std::string line;
  92.     while (std::getline(s, line)) {
  93.         size.width = std::max(size.width, static_cast<int>(line.length()));
  94.         ++size.height;
  95.     }
  96.  
  97.     Image img(size);
  98.  
  99.     s = std::istringstream(pixels);
  100.     for (int y = 0; y < size.height; ++y) {
  101.         if (!std::getline(s, line)) break;
  102.  
  103.         int x = 0;
  104.         for (char ch : line) {
  105.             img.SetPixel({x++, y}, ch);
  106.         }
  107.     }
  108.  
  109.     return img;
  110. }
Advertisement
Add Comment
Please, Sign In to add comment