Формат PPM (Portable Pixmap Format) — это простой формат графических файлов, используемый для хранения цветных растровых изображений. Он принадлежит к семейству форматов Netpbm, которые также включают PBM (Portable Bitmap) и PGM (Portable Graymap). PPM-файлы являются текстовыми или бинарными и предназначены для простого хранения и обмена изображениями между разными системами. Простота формата делает его удобным для учебных целей и быстрой реализации в различных языках программирования.
Структура PPM-файла
PPM-файл имеет следующую структуру:
- Магическое число: определяет тип файла и формат хранения данных. Для текстового формата PPM это «P3», для бинарного — «P6».
- Число колонок (ширина изображения): количество пикселей по горизонтали.
- Число рядов (высота изображения): количество пикселей по вертикали.
- Максимальное значение яркости: максимальное значение цвета для одного канала (обычно 255).
- Информация о пикселях: данные о цвете каждого пикселя, представлены в виде тройки значений (красный, зеленый, синий).
Пример структуры текстового PPM-файла:
P3
4 4
255
255 0 0 0 255 0 0 0 255 255 255 0
255 255 255 128 128 128 64 64 64 0 0 0
255 0 255 0 255 255 192 192 192 32 32 32
128 0 128 0 128 0 0 0 128 255 255 255
Пример PPM-файла
Пример простого PPM-файла в текстовом формате (P3):
P3
3 2
255
255 0 0 0 255 0 0 0 255
255 255 0 255 255 255 0 0 0
Этот файл описывает изображение размером 3×2 пикселя. Первая строка содержит магическое число «P3», указывающее на текстовый формат. Вторая строка задает ширину и высоту изображения. Третья строка определяет максимальное значение яркости (255). Далее следуют данные о пикселях: первые три числа — это значения RGB для первого пикселя, следующие три — для второго и так далее.
Инструкции по созданию и чтению PPM-файлов на языке программирования D (Dlang)
Для работы с PPM-файлами в языке программирования D создадим два класса: Pixel
и Image
. Класс Pixel
будет представлять отдельный пиксель изображения, а класс Image
— все изображение целиком.
Класс Pixel
class Pixel {
uint r;
uint g;
uint b;
this(uint r, uint g, uint b) {
this.r = r;
this.g = g;
this.b = b;
}
}
Класс Image
import std.stdio;
import std.file;
class Image {
uint width;
uint height;
uint maxColorValue;
Pixel[][] pixels;
this(uint width, uint height, uint maxColorValue = 255) {
this.width = width;
this.height = height;
this.maxColorValue = maxColorValue;
this.pixels = new Pixel[][](height, width);
}
void setPixel(uint x, uint y, Pixel pixel) {
pixels[y][x] = pixel;
}
Pixel getPixel(uint x, uint y) {
return pixels[y][x];
}
void saveToFile(string filename) {
File file = File(filename, "w");
file.writefln("P3");
file.writefln("%d %d", width, height);
file.writefln("%d", maxColorValue);
foreach (row; pixels) {
foreach (pixel; row) {
file.writefln("%d %d %d", pixel.r, pixel.g, pixel.b);
}
}
file.close();
}
static Image loadFromFile(string filename) {
File file = File(filename, "r");
string header = file.readln().strip();
if (header != "P3") {
throw new Exception("Invalid PPM file format");
}
auto dimensions = file.readln().strip().split();
uint width = dimensions[0].to!uint;
uint height = dimensions[1].to!uint;
uint maxColorValue = file.readln().strip().to!uint;
Image img = new Image(width, height, maxColorValue);
foreach (y; 0 .. height) {
foreach (x; 0 .. width) {
auto rgb = file.readln().strip().split();
uint r = rgb[0].to!uint;
uint g = rgb[1].to!uint;
uint b = rgb[2].to!uint;
img.setPixel(x, y, new Pixel(r, g, b));
}
}
file.close();
return img;
}
}
Пример кода для сохранения и загрузки PPM-файлов
import std.stdio;
void main() {
// Создание нового изображения 3x2
auto img = new Image(3, 2);
// Установка пикселей
img.setPixel(0, 0, new Pixel(255, 0, 0));
img.setPixel(1, 0, new Pixel(0, 255, 0));
img.setPixel(2, 0, new Pixel(0, 0, 255));
img.setPixel(0, 1, new Pixel(255, 255, 0));
img.setPixel(1, 1, new Pixel(255, 255, 255));
img.setPixel(2, 1, new Pixel(0, 0, 0));
// Сохранение изображения в файл
img.saveToFile("output.ppm");
// Загрузка изображения из файла
auto loadedImg = Image.loadFromFile("output.ppm");
// Проверка загруженных данных
foreach (y; 0 .. loadedImg.height) {
foreach (x; 0 .. loadedImg.width) {
auto pixel = loadedImg.getPixel(x, y);
writeln("Pixel at (", x, ",", y, "): ", pixel.r, " ", pixel.g, " ", pixel.b);
}
}
}
Этот пример демонстрирует создание и сохранение изображения в формате PPM, а затем загрузку и вывод данных о пикселях загруженного изображения.
Автор статьи:
Обновлено:
Добавить комментарий