# Переводит список байт в соответствующее ему число
def bytesToNumber(bs):
x = 0
for b in reversed(bs):
x = x * 256 + b
return x
# Возвращает ближайшее к x значение из отрезка [mn, mx]
def fit(x, mn, mx):
return min(max(x, mn), mx)
class Color:
def __init__(self, r, g, b):
self.r, self.g, self.b = r, g, b
# Доступ к компоненте цвета по индексу (c[1])
def __getitem__(self, k):
return [self.r, self.g, self.b][k]
# Запись в компоненту цвета по индексу (c[1] = 126)
def __setitem__(self, k, v):
if k == 0:
self.r = v
elif k == 1:
self.g = v
elif k == 2:
self.b = v
class Image:
def __init__(self, header, data):
self.header = header
self.data = data
self.width = bytesToNumber(header[18:22])
self.height = bytesToNumber(header[22:26])
self.row_size = (3 * self.width + 3) // 4 * 4
# Возвращает копию изображения
def copy(self):
return Image(self.header[:], self.data[:])
# Возвращает цвет пикселя с координатами (x, y)
def getPixel(self, x, y):
offset = y * self.row_size + 3 * x
return Color(
self.data[offset + 2], self.data[offset + 1], self.data[offset])
# Устанавливает цвет пикселя с координатами (x, y) в color
def setPixel(self, x, y, color):
offset = y * self.row_size + 3 * x
self.data[offset + 2] = fit(int(color.r), 0, 255)
self.data[offset + 1] = fit(int(color.g), 0, 255)
self.data[offset] = fit(int(color.b), 0, 255)
# Сохраняет изображение в файл file_name
def write(self, file_name):
with open(file_name, "wb") as f:
f.write(bytes(self.header))
f.write(bytes(self.data))
# Читает изображение из файла file_name
def readImage(file_name):
with open(file_name, 'rb') as f:
raw_data = f.read()
image_data_offset = bytesToNumber(raw_data[10:14])
return Image(
list(raw_data[:image_data_offset]),
list(raw_data[image_data_offset:]))
image = readImage('sample.bmp')
result = image.copy()
for y in range(image.height):
for x in range(image.width):
c = image.getPixel(x, y)
# Здесь мог бы быть ваш код
result.setPixel(x, y, new_color)
result.write('result.bmp')
|
#include <fstream>
#include <string>
#include <utility>
#include <vector>
using namespace std;
// Переводит список байт в соответствующее ему число
int bytesToNumber(const vector<char> &bytes, int start, int end) {
int x = 0;
for (int i = end - 1; i >= start; --i) {
x = x * 256 + (unsigned char)bytes[i];
}
return x;
}
// Возвращает ближайшее к x значение из отрезка [mn, mx]
int fit(int x, int mn, int mx) {
return min(max(x, mn), mx);
}
struct Color {
int r, g, b;
Color(int red, int green, int blue) {
r = red;
g = green;
b = blue;
}
// Доступ к компоненте цвета по индексу (c[1])
const int& operator [](int i) const {
if (i == 0) return r;
if (i == 1) return g;
if (i == 2) return b;
}
// Запись в компоненту цвета по индексу (c[1] = 126)
int& operator [](int i) {
if (i == 0) return r;
if (i == 1) return g;
if (i == 2) return b;
}
};
struct Image {
vector<char> header;
vector<char> data;
int width, height, row_size;
Image(const vector<char> &h, const vector<char> &d) {
header = h;
data = d;
width = bytesToNumber(header, 18, 22);
height = bytesToNumber(header, 22, 26);
row_size = (3 * width + 3) / 4 * 4;
}
// Возвращает цвет пикселя с координатами (x, y)
Color getPixel(int x, int y) {
int offset = y * row_size + 3 * x;
return Color(
(unsigned char)data[offset + 2],
(unsigned char)data[offset + 1],
(unsigned char)data[offset]);
}
// Устанавливает цвет пикселя с координатами (x, y) в color
void setPixel(int x, int y, const Color &color) {
int offset = y * row_size + 3 * x;
data[offset + 2] = (unsigned char)fit(color.r, 0, 255);
data[offset + 1] = (unsigned char)fit(color.g, 0, 255);
data[offset] = (unsigned char)fit(color.b, 0, 255);
}
// Сохраняет изображение в файл file_name
void write(const string &file_name) {
ofstream f(file_name, ios::binary);
f.write(header.data(), header.size());
f.write(data.data(), data.size());
}
};
// Читает изображение из файла file_name
Image readImage(const string &file_name) {
ifstream f(file_name, ios::binary);
std::vector<char> header(14);
std::vector<char> data;
f.read(header.data(), header.size());
int size = bytesToNumber(header, 2, 6);
int image_data_offset = bytesToNumber(header, 10, 14);
header.resize(image_data_offset);
f.read(header.data() + 14, image_data_offset - 14);
data.resize(size - image_data_offset);
f.read(data.data(), data.size());
return Image(header, data);
}
int main() {
Image image = readImage("roma.bmp");
Image result(image);
for (int y = 0; y < image.height; ++y) {
for (int x = 0; x < image.width; ++x) {
Color c = image.getPixel(x, y);
// Здесь мог бы быть ваш код
result.setPixel(x, y, new_color);
}
}
result.write("result.bmp");
return 0;
}
|