Обработка изображения в двоичных файлах

 

Министерство образования Российской Федерации

Новосибирский Государственный Технический Университет












Курсовой проект по дисциплине "Программирование"

Обработка изображения в двоичных файлах




Факультет: АВТФ

Группа: АВТ-919

Выполнил: Рожков А. Е.

Проверил: Романов Е. Л.







Новосибирск


Содержание


1.Задание

.Структурное описание разработки

.1Информация о графических форматах

.2Структура BMP файла

.3Хранение изображения в программе

.4Операции с изображением

.5Очередь как вспомогательная структура данных

.5.1 Структура очереди

.5.2 Операции с очередью

.Функциональное описание

.1.Класс BMP

.1.1 Данные класса BMP

.1.2 Методы класса BMP

.2.Класс QUEUE(очередь)

.2.1 Данные класса QUEUE

.2.2 Методы класса QUEUE

.Описание работы программы на контрольных примерах и выводы

.1Загрузка изображения из двоичного файла

.2Уменьшение разрешающей способности

.3 Увеличение размера изображения

.4Выводы

.Приложение

1.Задание


Программа «вручную» читает растровый файл изображения (bmp), выполняя заданные преобразования изображения. Допускаются ограничения на форматы обрабатываемых файлов (256-цветов и т.п).

  1. Изменение контрастности и яркости изображения.
  2. Изменение масштаба изображения.
  3. Уменьшение разрешающей способности путем усреднения групп пикселей (3х3).
  4. Искажение изображения («линза»).
  5. Рисование элементарных графических объектов (точки, линии, окружности, треугольники, четырёхугольники, закрашенные прямоугольники).
  6. Наложение одного изображения на другое, с прозрачностью задаваемого цвета.
  7. Заливка.

2.Структурное описание разработки


Данная программа представляет собой консольное приложение для работы с графическими изображениями. Вначале кратко изложим информацию о графических форматах и структуре их файлов. Затем рассмотрим структурное описание созданной программы.


2.1Информация о графических форматах


Для хранения графической информации в вычислительной технике существуют различные способы её записи, называемые графическими форматами. Графические форматы делятся на векторные и растровые.

В векторных форматах изображения хранятся в виде совокупности геометрических примитивов, таких как точки, линии, сплайны и многоугольники (например SVG формат).

В растровых форматах изображения хранятся в виде сетки пикселей или точек цветов (обычно прямоугольной). Растровых форматов очень много: BMP, ECW ,GIF, ICO, PNG, JPEG и др.

Подробно рассмотрим BMP формат. С данным форматом работает огромное количество программ, так как его поддержка интегрирована в операционные системы Windows и OS/2. Файлы формата BMP могут иметь расширения .bmp, .dib и .rle. Кроме того, данные этого формата включаются в двоичные файлы ресурсов RES и в PE-файлы.

Глубина цвета в данном формате может быть 1, 4, 8, 16, 24, 32, 48 бит на пиксел, максимальные размеры изображения 65535×65535 пикселов.

В формате BMP есть поддержка сжатия по алгоритму RLE, однако теперь существуют форматы с более сильным сжатием, и из-за большого объёма BMP редко используется в Интернете, где для сжатия без потерь используются PNG и более старый GIF.

.2Структура BMP файла


Моя программа работает с BMP форматом с глубиной цвета 24 бита на пиксель, без сжатия, без палитры. При таком хранении изображения, каждому пикселу соответствуют три последовательные байта, хранящие составляющие цвета B, G, R; (не R, G, B). Для загрузки изображения необходимо знать внутреннюю структуру файла:

-разрядный BMP-файл состоит из трёх частей:

)Заголовок файла

)Заголовок изображения

)Само изображение

В таблице 2.2 приведено подробное описание каждой части.


Таблица 2.2

Смещение от начала файла в байтахДлина поля в байтахОписание поляЗАГОЛОВОК ФАЙЛА02Код 424Dh - Буквы 'BM'24Размер файла в байтах620 (Резервное поле)820 (Резервное поле)104Смещение, с которого начинается само изображение (растр), равно 54ЗАГОЛОВОК ИЗОБРАЖЕНИЯ144Размер заголовка в байтах, равно 40184Ширина изображения в пикселях224Высота изображения в пикселях262Число плоскостей, должно быть 1282Бит/пиксел: 24304Тип сжатия, равно 03440 или размер сжатого изображения в байтах.384Горизонтальное разрешение, пиксел/м424Вертикальное разрешение, пиксел/м464Количество используемых цветов504Количество "важных" цветов, равно 0.САМО ИЗОБРАЖЕНИЕИзображение сохраняется построчно СНИЗУ-ВВЕРХ. Для хранения каждой строки выделяется кратное 4 количество байт. В незначащих байтах хранится мусор. Старшему биту или тетраде соответствует самый левый пиксел.

.3Хранение изображения в программе


Информация о изображении храниться в виде структуры данных(BMP), состоящей из: переменных, хранящих данные о изображении и графическом файле, и двумерного динамического массива указателей(MBMP), который хранит непосредственно цвета пикселей. Его структура такова: массив указателей на biHeight массивов байтов (строк изображения), которые содержат biWidth * 3 + n элементов. Каждые 3 элемента строки представляют собой цвет пикселя в формате RGB, начиная с нулевого элемента. Размер массива с пикселями кратен 4, это обеспечивается числом n. Вышесказанное иллюстрируется рисунком 2.3.


.4Операции с изображением:


Для работы с изображением предусмотрены следующие операции:

·загрузка и сохранение из двоичного файла с заданным именем (имя вводится пользователем с клавиатуры),

·создание пустого изображения (белого, с нужными размерами, которые вводятся пользователем с клавиатуры),

·получение размера файла с изображением (размер графического файла при сохранении данного изображения на жесткий диск),

·получение размера изображения (ширина и высота),

·рисование графических примитивов (точка, линия, окружность, треугольник, четырёхугольник, закрашенный прямоугольник. Их параметры задаются пользователем). Пример работы программы на рис.2.4.1

рис 2.4.1


·изменение яркости (на рис.2.4.2а исходное изображение, а на рис.2.4.2б с уменьшенной яркостью).


рис.2.4.2а рис 2.4.2б


·изменение контрастности (на рис.2.4.3а исходное изображение, а на рис.2.4.3б с увеличенной контрастностью).

рис.2.4.3а рис.2.4.3б


·изменение масштаба (изменение размера изображения). При увеличении изображения в n раз, каждый пиксель в стоке повторяется n раз и каждая строка повторяется n раз. При уменьшении изображения в n раз проходим исходное изображение с шагом n, и для каждой матрицы nxn считаем средний цвет, который и помещаем в новое изображение. Работу данного алгоритма иллюстрирует рис.2.4.4.


Рис.2.4.4

·наложение одного изображения на другое с прозрачностью какого-либо цвета второго (на рис.2.4.5а и рис.2.4.5б исходные изображения, а на рис.2.4.5в результат).


рис.2.4.5а

рис.2.4.5брис.2.4.5в


·искажение уменьшающей линзой. Пользователем задается область, где нужно сделать такой эффект. На рис.2.4.6 пример работы программы.

рис.2.4.6


·получение цвета пикселя, с заданными пользователем координатами,

·уменьшение разрешающей способности. Под уменьшением разрешающей способности здесь понимается усреднение всех цветов пикселей изображения, относительно их 8 соседних пикселей.

Для каждого пикселя изображения подсчитывается сумма красного, зеленого и синего каналов цвета его и всех ближайших соседей(см. рис.2.4.7 соседи обозначены 1, а текущий пиксель 2, результирующий 3), затем эти суммы делятся на количество соседей + 1. Полученные значения каналов цвета записываются в текущий пиксель. В результате получается эффект размывания изображения.


рис.2.4.7


Пример работы программы на рис.2.4.8(а - исходный, б - результат)

рис.2.4.8арис.2.4.8б


·заливка. Заливка - определение области, «связанной» с определённым элементом (задается пользователем) в двумерном массиве точек растрового изображения, по критерию одного цвета у всех этих точек, и заполнения данной области другим цветом (заданным пользователем).

Пример работы программы на рис.2.4.8(а - исходный, б - результат)


рис.2.4.8а рис.2.4.8б


Пользователь задает начальные координаты точки, которая принадлежит перекрашиваемой области. Программа перекрашивает эту точку и проверяет своих «соседей» (точки сверху, снизу, слева, справа), если «сосед» имеет заменяемый цвет, то перекрашиваем его и проверяем его «соседей» и т.д.

Для реализации данного алгоритма удобно использовать очередь, для хранения координат «соседей», которые ещё не проверены.

.5Очередь как вспомогательная структура данных


.5.1Структура очереди

Очередь - структура данных с дисциплиной доступа к элементам «первый пришёл - первый вышел» (FIFO, First In - First Out). Добавление элемента возможно лишь в конец очереди, выборка - только из начала очереди, при этом выбранный элемент из очереди удаляется.

При программировании метода «заливка», используется очередь, которая представлена в программе в виде отдельной структуры данных (см. рис.2.5.1).


Рис.2.5.1


Очередь реализована в виде двухсвязного списка. Указатели beg и end типа node (элемент очереди) хранят адреса первого и последнего элемента соответственно. Целочисленная переменная sz хранит количество элементов очереди. Ниже приведена структура класса node:


Переменные x,y - это координаты пикселя, которые необходимо хранить в очереди для алгоритма «заливка». node * next, prev - это указатели на следующий и предыдущий элемент соответственно.


.5.2 Операции с очередью.

С очередью предусмотрены следующие операции:

·Вставка элемента в очередь.

Приведем псевдокод данного алгоритма:

Алгоритм вставки элемента в очередь(Push(x,y)):

Создаем новый элемент, с переданными значениями координат x,y

Помещаем его в конец очереди:

Если очередь пуста, то beg присвоить адрес этого элемента

Иначе добавляем перед end данный элемент

end присваиваем адрес этого элемента

увеличиваем значение счетчика элементов

Выход

·Изъятие элемента из очереди:

Приведем псевдокод данного алгоритма:

Алгоритм изъятия элемента из очереди(Pop(x,y)):

Если очередь пуста, то выход

Возвращаем значение первого элемента (координаты пиксела)

Удаляем первый элемент:

Если элемент один, то удаляем его и обнуляем указатели beg и end

Иначе перемещаем указатель beg на предыдущий элемент и удаляем первый элемент в очереди

уменьшаем значение счетчика элементов

Выход

·Получение количества элементов очереди.

.Функциональное описание


Изображения, с которыми работает данная программа, хранятся в объектах класса BMP. В данном классе реализованы различные методы обработки изображений. Рассмотрим их функциональное описание.


.1 Класс BMP


.1.1 Данные класса BMP

·ИМЕНА НОВЫХ ТИПОВ ДАННЫХ

Для описания типов переменных в данном кассе вводятся новые имена типов:

typedef short WORD;unsigned DWORD;long LONG;unsigned char BYTE;

·ДАННЫЕ О ФАЙЛЕbfType; // тип файла, символы "BM"bfSize; // размер всего файла в байтахbfReserved1;bfReserved2; // зарезервированные, должны //содержать нулиbfOffBits; // содержит смещение в байтах от //начала заголовка до битов изображения, равен 54

·ДАННЫЕ О ИЗОБРАЖЕНИИbiSize; // размер структуры данных о //изображении, равен 40biWidth; // ширина изображения в пикселахbiHeight; // высота изображения в пикселахbiPlanes; // число плоскостей, равно 1biBitCount; // указывает количество бит на пиксель, если 24 разрядное изображение то равно 24 т.к. каждый пиксель храниться в виде трёх байтов (RGB формат).biCompression; // тип сжатия. Если рано BI_RGB //= 0, то палитра не используетсяbiSizeImage; // 0 или размер сжатого //изображения в байтах. При 24 разрядном равно 0.biXPelsPerMet; // Горизонтальное разрешение, //пиксел/мbiYPelsPerMet; // Вертикальное разрешение, //пиксел/мbiClrUsed; // Количество используемых цветовbiClrImportant;// Количество "важных" цветов

·ИНФОРМАЦИЯ О ПИКСЕЛЯХ**MBMP; // массив указателей на пиксели изображения


.1.2 Методы класса BMP

Функция перевода цвета в формат RGB:

void Col_To_RGB(int, int*, int*, int*);

В функцию передается цвет, в виде целого числа(первый параметр):

0 - черный

- белый

- синий

- зелёный

- красный

- пурпурный

- желтый

- циановый,

Возвращается значение цвета в формате RGB(три последних параметра).

Функция загрузки изображения из двоичного файла:Load(char FileNames[]);

Параметр строка это имя графического файла. Функция возвращает 1, если изображение загрузилось и 0 в противном случае. Если изображение не загрузилось, старое изображение сохраняется.

Приведем псевдокод данной функции:

Загрузка изображения из файла:

Открытие файла с изображением

Чтение из двоичного файла информации о изображении: типе, размере и т.д. во временные переменные.

Если тип не соответствует 24-разрядному изображению в формате BMP, то выход

Удаление предыдущих данных изображения (запуск деструктора)

Запись новых значений о файле и изображении в объект

Создание динамического массива указателей нужного размера (количество элементов в строках массива делаем кратным 4)

Считывание информации о пикселях, причем изображение храниться в файле снизу вверх.

Закрытие файла

Функция сохранения изображения в двоичный файл:Save(char FileNames[]);

Параметр строка это имя графического файла, в который будет сохранено изображение. Если данный файл уже существует, то он будет перезаписан.

Выполняет открытие двоичного файла и запись в него информации о файле, изображении и самих цветов пикселей из динамического массива указателей.

Функция получения размера файла с изображением в байтах:FileSize();

Возвращает размер файла с изображением в байтах.

Функция получения размера изображения:

void Dimensions(int *W, int *H);

Возвращаемые параметры функции это ширина(W) и высота(H) изображения в пикселах.

Функция рисования пиксела:PutPixel(int x, int y, int color);

В функцию передаются координаты точки x,y и цвет color в виде целого числа (см. первый параметр функции void Col_To_RGB).

Если координаты точки принадлежат изображению, то данный пиксель закрашивается и функция возвращает 1, иначе ничего не происходит и возвращается 0.

Процесс рисования происходит следующим образом: сначала цвет переводится в формат RGB при помощи функции Col_To_RGB, затем в массив указателей вносятся изменения нужной троки элементов, при этом учитывается, что в массиве строки расположены снизу-вверх и компоненты цвета расположены в порядке BGR.

Функция рисования пиксела(RGB):PutPixelRGB(int x,int y,int red,int green,int blue);

В функцию передаются координаты точки x,y и цвет в формате RGB(три целых числа от 0 до 255 отвечающие за яркость красного, зеленого и синего канала цвета - три последних параметра).

Если координаты точки принадлежат изображению, то данный пиксель закрашивается и функция возвращает 1, иначе ничего не происходит и возвращается 0.

Процесс рисования происходит также как в функции PutPixel, только без перевода цвета в другой формат.

Функция считывания цвета заданного пикселя:

int GetPixel(int x,int y,int *red,int *green,int *blue);

В функцию передаются координаты точки x,y. Возвращаемыми являются три последних параметра, которые представляют цвет формате RGB.

Если координаты точки принадлежат изображению, то red, green, blue примут значение цвета данного пиксела и функция возвратит 1, иначе ничего не произойдет и возвратится 0.

Функция рисования линии:DrawLine(int x1, int y1, int x2, int y2, int color);

Функция получает координаты начала x1,y1 и конца x2,y2 линии, цвет color в виде целого числа(см. первый параметр функции void Col_To_RGB).

Если координаты начала и конца линии принадлежат изображению, то линия нарисуется и функция возвратит 1, иначе ничего не произойдет и возвратиться 0.

Используется алгоритм Брезенхема.

Функция рисования четырёхугольника:

int DrawQuadrangle(int x1,int y1,int x2,int y2,int x3,int y3,int x4,int y4,int color);

В функцию передаются координаты вершин четырёхугольника x1,y1, x2,y2, x3,y3, x4,y4 и цвет color в виде целого числа(см. первый параметр функции void Col_To_RGB).

Если координаты вершин принадлежат изображению, то рисуется четырёхугольник и функция возвращает 1, иначе ничего не произойдет и возвратиться 0.

Процесс рисования происходит следующим образом: последовательно рисуются четыре линии с данными координатами.

Функция рисования треугольника:DrawTriangle(int x1,int y1,int x2,int y2,int x3,int y3, int color);

В функцию передаются координаты вершин треугольника x1,y1, x2,y2, x3,y3 и цвет color в виде целого числа(см. первый параметр функции void Col_To_RGB).

Если координаты вершин принадлежат изображению, то рисуется треугольник и функция возвращает 1, иначе ничего не произойдет и возвратиться 0.

Процесс рисования происходит следующим образом: последовательно рисуются три линии с данными координатами.

Функция рисования окружности:DrawCircle(int x0, int y0, int radius, int color);

В функцию передаются координаты центра окружности x0,y0, радиус и цвет color в виде целого числа(см. первый параметр функции void Col_To_RGB).

Если координаты центра принадлежат изображению, то рисуется окружность и функция возвращает 1, иначе ничего не произойдет и возвратиться 0.

Используется алгоритм Брезенхема для окружностей.

Функция изменения яркости изображения:

void Bright(int x);

В функцию передается коэффициент x изменения яркости от -255 до 255. При положительном коэффициенте яркость увеличивается, иначе уменьшается.

Процесс изменения яркости выполняется следующим образом: к каждой компоненте цвета всех пикселей прибавляется (уменьшение) или отнимается (увеличение) коэффициент x.

Функция изменения контрастности изображения:Contrast(int e);

В функцию передается коэффициент e изменения контрастности от -100 до 100. При положительном коэффициенте контрастность увеличивается, иначе уменьшается.

Процесс изменения контрастности выполняется следующим образом: вычисляется средняя яркость изображения Y, а затем все компоненты цвета всех пикселей изменяются по формуле .

Функция изменения цвета прямоугольника:

void QuadrangleRGB(int x1,int y1,int x2,int y2,int rr,int gg, int bb);

В функцию передаются координаты верхнего левого x1,y1 и нижнего правого x2,y2 углов прямоугольника и три значения цвета в формате RGB. Если компонента цвета равна -1, то данный канал останется в изображении неизменным. Если вершины прямоугольника не принадлежат изображению, то изменения цвета не произойдет.

Функция наложения одного изображения на другое:

void Imposition(BMP &T, int x, int y, int r, int g, int b);

В функцию передаются: ссылка на объект с изображением &T, которое нужно наложить, координаты верхнего левого угла x,y накладываемого изображения в исходном изображении и три значения цвета в формате RGB, который будет прозрачным в накладываемом изображении. Если значения каналов цвета равны -1 -1 -1, то прозрачными будут пиксели цвета верхнего левого угла, если -2 -2 -2, то прозрачности не будет.

Функция уменьшения разрешающей способности изображения:

void Resolution();

Функция уменьшает разрешающую способность путем усреднения групп пикселей 3х3.

Приведем данный алгоритм в псевдокоде:

Создаем временный объект, в который помещаем исходное изображение

Перебираем все пиксели временного изображения

Для каждого подсчитываем сумму каналов цвета его и 8 ближайших соседей

Находим средние значения каналов, при помощи деления сумм на 9

Помещаем полученный цвет в результирующее изображение

Выход

Функция изменения масштаба изображения:

void Zoom(int k);

В функцию передается коэффициент k изменения масштаба, если положительный, то происходит увеличение изображения в k раз, иначе уменьшение в k раз. Если k=0 ничего не происходит.

Алгоритм данной функции рассмотрен в структурном описании программы.

Функция заливки:FloodFill(int x, int y, int rz, int gz, int bz);

В функцию передаются координаты начальной точки заливки x,y и три значения rz,gz,bz цвета в формате RGB, которым будет заполнена область, которая содержит точку с координатами x,y и имеющая цвет этой точки.

Ниже приведен псевдокод алгоритма «заливки», использующего очередь для хранения непроверенных «соседей»:

Заливка (элемент, заменяемый цвет, цвет заливки):

Присвоить Q пустую очередь.

Если цвет элемента - не заменяемый цвет, выход.

Поместить элемент в конец Q.

До тех пор, пока Q не пуста:

Присвоить n первый элемент Q

Если цвет n - заменяемый цвет, установить его в цвет заливки.

Взять первый элемент из Q

Если цвет элемента к западу от n - заменяемый цвет:

Установить цветом этого элемента цвет заливки

Поместить этот элемент в конец Q

То же самое для остальных соседей

Выход.

Функция изменения изображения, уменьшающей линзой:

void Lens(int x, int y, int r, int k);

В функцию передаются координаты центра линзы x,y, значение её радиуса r и коэффициент уменьшения k.

Выполняется процедура искажения заданного круга с центром с координатами x,y и радиусом r, эффектом линзы. Процесс искажения реализуется следующим образом: каждой координате данного круга дается приращение по двум направлениям. Приведем фрагмент программы:

for(i = -ro; i <= ro; i++)// перебор всех точек круга

{ogr = sqrt((float)(ro*ro - i*i));(int j = -ogr; j <= ogr; j++)

{= -k*sin(3.14*i/(2*ro));// искажение по y= -k*sin(3.14*j/(2*abs(ogr)));// искажение по x

// если точка с новыми координатами не вышла за гравницу круга, рисуем её(abs(i + yy) < ro && abs(j + xx) < abs(ogr))

{

// считываем цвет точки со старыми координатами.GetPixel(x + j, y + i, r, g, b);

// записываем пиксель на новое место(x + j + xx, y + i + yy, *r, *g, *b);

}}}


.2 Класс QUEUE и вложенный класс NODE


Класс QUEUE представляет собой структуру данных, в которой реализован двусвязный список


.2.1 Данные класса очередь и класса элемента очереди

int x, y - элементы класса node, предназначенные для хранения координат пикселя*next - элемент класса node, указывает на следующий элемент в очереди*prev - элемент класса node, указывает на предыдущий элемент в очередиsz - элемент класса QUEUE, предназначенный для хранения текущего количество элементов в очереди*beg, *end - элемент класса QUEUE, указывают на начало и конец очереди


.2.2 Методы класса QUEUE

Функция, возвращающая размер очереди:

int Size();

Функция возвращает количество элементов очереди.

Функция, помещающая элемент в очередь:

void Push(int x1, int y1);

В функцию передаются два значения (координаты пиксела) x1, y1, которые помещаются в виде одного элемента в конец очереди.

Функция, изымающая элемент из очереди:

void Pop(int *x1, int *y1)

Функция возвращает два значения (координаты пиксела) x1, y1, которые являются значениями первого элемента в очереди. Данный элемент из очереди удаляется.

.Описание работы программы на контрольных примерах


Для описания работы программы, определения производительности и чувствительности к данным протестируем ее основные методы работы с изображением, затратные по времени, а точнее: уменьшение разрешающей способности, загрузка изображения из двоичного файла, увеличение размера изображения (метод масштабирования с положительным коэффициентом).

Теоритически, в основном, все алгоритмы компьютерной графики имеют линейную трудоемкость т.к. обрабатывают все точки изображения или некоторое подмножество точек, которое, опять же, зависит от общего числа точек.


.1Загрузка изображения из двоичного файла


Таблица 4.1

Количество точек изображенияВремя работы225000016400000047625000063900000094122500001101600000015620250000188

Рис.4.1


.2Уменьшение разрешающей способности


Таблица 4.2

Количество точек изображенияВремя работы25000020310000008282250000178140000003172625000049689000000715612250000975016000000126562025000016093

Рис.4.2


Таблица 4.3

Количество точек изображенияКоличество сравнений25000030000001000000120000002250000270000004000000480000006250000750000009000000108000000122500001470000001600000019200000020250000243000000

Рис. 4.3


.3Увеличение размера изображения


Таблица 4.4

Коэффициент увеличения изображенияВремя работы212532654406557868437114181484

Рис.4.4


Таблица 4.5

Коэффициент увеличения изображенияКоличество сравнений2100000032250000440000005625000069000000712250000816000000

Рис.4.5

.4Выводы


Из приведённых таблиц и графиков, видно, что экспериментальные зависимости практически согласуются с теоретическими сведениями, а именно:

·При увеличении количества точек изображения пропорционально увеличивается количество массовых операций (в данных примерах сравнений) в программе (см. рис. 4.3, 4.5).

·Также при увеличении количества точек линейно растет «грязное» время (время с учетом всех других работ, выполняющихся в операционной системе) работы программы (см. рис. 4.1, 4.2, 4.4).

·Все остальные методы, реализованные в программе, будут иметь примерно такие же зависимости т.к. обрабатывают все точки изображения или некоторое подмножество точек, которое зависит от общего числа точек.

графический формат изображение загрузка

5.Приложение


Исходный текст программы:

Файл main.cpp

#include "BMP.h";

#include "conio.h"

#include <iostream>

#include <clocale>main()

{( LC_ALL, "rus" );

// корректная работа с русским текстом*IMG1, *IMG2;H, W;name[200];*r = new int, *g = new int, *b = new int, *w = new int, *h = new int;rz, gz, bz;x1, y1, x2, y2, x3, y3, x4, y4;val;(" 1 - Создать изображение\n");(" 2 - Открыть изображение\n Введите номе операции:");("%d", &val);(val == 1)

{(" Введите размеры нового изображения :");("%d %d", &H, &W);= new BMP(H, W);

}(val == 2)

{(" Введите имя файла, загружаемого изображения :");("%s", name);= new BMP(name);

}("cls"); // очистка экрана( val == 1 || val == 2)

{

{(" 1 - Загрузить изображение\n");(" 2 - Сохранить изображение\n");(" 3 - Получить размер файла изображения\n");(" 4 - Получить размеры изображения\n");(" -----------------------------------------\n");(" 5 - Нарисовать точку\n");(" 6 - Нарисовать линию\n");(" 7 - Нарисовать окружность\n");(" 8 - Нарисовать четырёхугольник\n");(" 9 - Нарисовать треугольник\n");(" 10 - Нарисовать закрашенный прямоугольник\n");(" 11 - Получить цвет точки\n");(" -----------------------------------------\n");(" 12 - Изменение яркости\n");(" 13 - Изменение контрастности\n");(" 14 - Наложение другого изображения\n");(" 15 - Уменьшение разрешающей способности\n");(" 16 - Масштабирование\n");(" 17 - Заливка\n");(" 18 - Искажение изображения. Эффект линзы\n");(" -----------------------------------------\n");(" 0 - Выход\n");("\n==========================================\n");(" Введите номер операции :");("%d", &val);(val)

{1:

{(" Введите имя файла, загружаемого изображения :");("%s", name);(IMG1->Load(name))printf("Изображение загружено");printf("Нет данного файла или его формат не подходит!");();

};break;2:

{(" Введите имя файла, сохраняемого изображения :");("%s", name);->Save(name);

};break;3:

{("Размер файла изображения %d В", IMG1->FileSize());();

}break;4:

{->Dimensions(w, h);(" Размер изображения %d x %d", *w, *h);();

};break;5:

{(" Введите координаты точки: ");("%d %d", w, h);(" Введите цвет в формате R G B:");("%d %d %d", r, g , b);->PutPixelRGB(*w, *h, *r, *g, *b);

};break;6:

{(" Введите координаты начала: ");("%d %d", &x1, &y1);(" Введите координаты конца: ");("%d %d", &x2, &y2);(" Введите цвет:\n0 - черный\n1 - белый\n2 - синий\n3 - зелёный\n4 - красный\n5 - пурпурный\n6 - желтый\n7 - циановый\n");("%d", r);->DrawLine(x1, y1, x2, y2, *r);

};break;7:

{(" Введите координаты центра окружности: ");("%d %d", &x1, &y1);(" Введите радиус окружности: ");("%d", r);(" Введите цвет:\n0 - черный\n1 - белый\n2 - синий\n3 - зелёный\n4 - красный\n5 - пурпурный\n6 - желтый\n7 - циановый\n");("%d", b);->DrawCircle(x1, y1, *r, *b);

};break;8:

{(" Введите координаты первой вершины: ");("%d %d", &x1, &y1);(" Введите координаты второй вершины: ");("%d %d", &x2, &y2);(" Введите координаты третий вершины: ");("%d %d", &x3, &y3);(" Введите координаты четвертой вершины: ");("%d %d", &x4, &y4);(" Введите цвет:\n0 - черный\n1 - белый\n2 - синий\n3 - зелёный\n4 - красный\n5 - пурпурный\n6 - желтый\n7 - циановый\n");("%d", r);->DrawQuadrangle(x1, y1, x2, y2, x3, y3, x4, y4, *r);

};break;9:

{(" Введите координаты первой вершины: ");("%d %d", &x1, &y1);(" Введите координаты второй вершины: ");("%d %d", &x2, &y2);(" Введите координаты третий вершины: ");("%d %d", &x3, &y3);(" Введите цвет:\n0 - черный\n1 - белый\n2 - синий\n3 - зелёный\n4 - красный\n5 - пурпурный\n6 - желтый\n7 - циановый\n");("%d", r);->DrawTriangle(x1, y1, x2, y2, x3, y3, *r);

};break;10:

{(" Введите координаты верхнего левого угла: ");("%d %d", &x1, &y1);(" Введите координаты нижнего правого угла: ");("%d %d", &x2, &y2);(" Введите цвет в формате R G B:( если значение равно -1,");(" то исходная компонента цвета не изменяется)");("%d %d %d", r, g, b);->QuadrangleRGB(x1, y1, x2, y2, *r, *g, *b);

};break;11:

{(" Введите координаты точки: ");("%d %d", &x1, &y1);(IMG1->GetPixel(x1, y1, r, g, b))printf(" Цвет точки с координатами (%d, %d) в формате R G B: %d %d %d", x1, y1, *r, *g, *b);printf(" Точки с данными координатами на рисунке нет!");();

};break;12:

{(" Введите коеффициент изменения яркости (-255 < k < 255):");("%d", &x1);->Bright(x1);

};break;13:

{(" Введите коеффициент изменения контрастности (-100 < k < 100):");("%d", &x1);->Contrast(x1);

};break;14:

{(" Введите имя файла с изображением, которое будет накладываться :");("%s", name);= new BMP(100, 100);(IMG2->Load(name))

{(" Введите координаты верхнего левого угла накладываемого ");(" изображения в исходном изображении:");("%d %d", &x1, &y1);(" Введите цвет, который будет прозрачным, у накладываемого изображения в формате R G B:");(" Если ввести -1 -1 -1, то прозрачными будут пиксели цвета верхнего левого угла,");(" если -2 -2 -2, то прозрачности не будет :");("%d %d %d", r, g , b);->Imposition(*IMG2, x1, y1, *r, *g, *b);

}printf("Нет данного файла или его формат не подходит!");IMG2;();

};break;15:

{(" Уменьшение разрешающей способности путем\n");(" усреднения групп пикселей 3x3 выполнена!");->Resolution();();

};break;16:

{(" Введите коеффициент масштабирования: при уменьшении k < 0,");(" при увеличении масштаба k > 0 (k - целое): ");("%d", &x1);->Zoom(x1);

};break;17:

{(" Введите координаты точки, принадлежащей\n");(" области, которую нужно закрасить :");("%d %d", w, h);(" Введите цвет заливки в формате R G B:");("%d %d %d", &rz, &gz , &bz);->FloodFill(*w, *h, rz, gz, bz);

};break;18:

{(" Введите координаты центра линзы: ");("%d %d", &x1, &y1);(" Введите радиус линзы: ");("%d", r);(" Введите коэффициент уменьшения:");("%d", b);->Lens(x1, y1, *r, *b);

};break;

}("cls"); // очистка экрана

}(val != 0);

}IMG1;}

Файл BMP.h:

#include <fstream>namespace std;short WORD;unsigned DWORD;long LONG;unsigned char BYTE;BMP

{

// ДАННЫЕ О ФАЙЛЕbfType; // тип файла, символы "BM"bfSize; // размер всего файла в байтахbfReserved1;bfReserved2;

// зарезервированные, должны содержать нулиbfOffBits; // содержит смещение в байтах от //начала заголовка до битов изображения

// ДАННЫЕ О ИЗОБРАЖЕНИИbiSize; // размер структуры данных о изображенииbiWidth; // ширина изображения в пикселахbiHeight; // высота изображения в пикселахbiPlanes; // число плоскостей, равно 1biBitCount;

// указывает количество бит на пиксель.biCompression;

// тип сжатия. Если рано BI_RGB, то палитра не используетсяbiSizeImage;

// 0 или размер сжатого изображения в байтахbiXPelsPerMet;

// Горизонтальное разрешение, пиксел/мbiYPelsPerMet;

// Вертикальное разрешение, пиксел/мbiClrUsed; // Количество используемых цветовbiClrImportant;// Количество "важных" цветов

// ИНФОРМАЦИЯ О ПИКСЕЛЯХ**MBMP;

// массив указателей на пиксели изображенияCol_To_RGB(int col, int* red, int* green, int* blue); // перевод цвета:(const BMP &M);

// конструктор копирования(char FileNames[]);

// конструктор с параметром строкой(имя графического фйла)(long H, long W);// конструктор с размером нового изображения

~BMP();// деструктор* Copy();

// создание копии объекта (клонирование)Load(char FileNames[]);

// чтение изображения из файлаSave(char FileNames[]);

// запись изображения в файлаFileSize();// размер файлаDimensions(int *W, int *H);// размеры изображенияPutPixel(int x, int y, int color);

// нарисовать пиксельGetPixel(int x, int y, int *red, int *green, int *blue); // взять цвет пикселяPutPixelRGB(int x, int y, int red, int green, int blue); // нарисовать пиксель, задавая цвет в формате RGBDrawLine(int x1, int y1, int x2, int y2, int color); // нарисовать линиюDrawQuadrangle(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4, int color);

// нарисовать четырёхугольникDrawTriangle(int x1, int y1, int x2, int y2, int x3, int y3, int color); // нарисовать треугольникDrawCircle(int x0, int y0, int radius, int color); // нарисовать окружностиBright(int x);

// изменение яркости -255 < x < 255Contrast(int e);

// изменение контрастности -100 < e < 100QuadrangleRGB(int x1, int y1, int x2, int y2, int rr, int gg, int bb); // изменение цвета прямоугольникаImposition(BMP &T, int x, int y, int r, int g, int b); // наложение изображений с прозрачностью цвета rgbResolution(); // уменьшение разрешающей способностиZoom(int k); // масштабированияFloodFill(int x, int y, int rz, int gz, int bz); // заливкаLens(int x, int y, int r, int k); // эффект линзы

};

Файл BMP.cpp:

#include "BMP.h"

#include "math.h"

#include "queue.h"::BMP(const BMP &M)// конструктор копирования

{= M.bfType;= M.bfSize;= M.bfReserved1;= M.bfReserved2;= M.bfOffBits;= M.biSize;= M.biWidth;= M.biHeight;= M.biPlanes;= M.biBitCount;= M.biCompression;= M.biSizeImage;= M.biXPelsPerMet;= M.biYPelsPerMet;= M.biClrUsed;= M.biClrImportant;sz_line = biWidth * 3;(sz_line % 4 != 0) sz_line++;

// выравнивание до СЛОВА (кратно 4)= new BYTE *[biHeight];(int i = 0; i < biHeight; i++)

{[i] = new BYTE[sz_line];(int j = 0; j < sz_line; j++)MBMP[i][j] = M.MBMP[i][j];

}

}::BMP(char FileNames[])

// конструктор с параметрок строкой(имя графического файла)

{= 19778;= 0;= 0;= 0;= 54;= 40;= 0;= 0;= 1;= 24;= 0;= 0;= 0;= 0;= 0;= 0;= NULL;(FileNames);

}::BMP(long H, long W)

// конструктор создания пустого(белого) изображения

{= 19778;= H * W * 3 + 54;= 0;= 0;= 54;= 40;= W;= H;= 1;= 24;= 0;= H * W * 3;= 0;= 0;= 0;= 0;sz_line = biWidth * 3;(sz_line % 4 != 0) sz_line++;

// выравнивание до СЛОВА (кратно 4)= new BYTE *[biHeight];(int i = 0; i < biHeight; i++)

{[i] = new BYTE[sz_line];(int j = 0; j < sz_line; j++)MBMP[i][j] = 255;

}

}::~BMP()

// деструктор

{(int i = 0; i < biHeight; i++)MBMP[i];MBMP;= NULL;

}* BMP::Copy()// создание копии объекта (клонирование)

{new BMP(*this);

}BMP::Load(char FileNames[])

// загрузка изображения из файла

{

// ВРЕМЕННЫЕ ДАННЫЕ О ФАЙЛЕbfTypet;bfSizet;bfReserved1t;bfReserved2t;bfOffBitst;

// ВРЕМЕННЫЕ ДАННЫЕ О ИЗОБРАЖЕНИИbiSizet;biWidtht;biHeightt;biPlanest;biBitCountt;biCompressiont;biSizeImaget;biXPelsPerMett;biYPelsPerMett;biClrUsedt;biClrImportantt;F;.open(FileNames, ios::in | ios::binary);

// Двоичный для чтения

// ЧТЕНИЕ ДАННЫХ О ФАЙЛЕ.read((char*)&bfTypet,sizeof(WORD));.read((char*)&bfSizet,sizeof(DWORD));.read((char*)&bfReserved1t,sizeof(WORD));.read((char*)&bfReserved2t,sizeof(WORD));.read((char*)&bfOffBitst,sizeof(DWORD));

// ЧТЕНИЕ ДАНННЫХ О ИЗОБРАЖЕНИИ.read((char*)&biSizet,sizeof(DWORD));.read((char*)&biWidtht,sizeof(LONG));.read((char*)&biHeightt,sizeof(LONG));.read((char*)&biPlanest,sizeof(WORD));.read((char*)&biBitCountt,sizeof(WORD));.read((char*)&biCompressiont,sizeof(DWORD));.read((char*)&biSizeImaget,sizeof(DWORD));.read((char*)&biXPelsPerMett,sizeof(LONG));.read((char*)&biYPelsPerMett,sizeof(LONG));.read((char*)&biClrUsedt,sizeof(DWORD));.read((char*)&biClrImportantt,sizeof(DWORD));(biBitCountt == 24)

{>~BMP();// удаление предыдущих значений

// ЗАПИСЬ НОВЫХ ЗНАЧЕНИЙ= bfTypet;= bfSizet;= bfReserved1t;= bfReserved2t;= bfOffBitst;= biSizet;= biWidtht;= biHeightt;= biPlanest;= biBitCountt;= biCompressiont;= biSizeImaget;= biXPelsPerMett;= biYPelsPerMett;= biClrUsedt;= biClrImportantt;

// чтение данных о пикселяхsz_line = biWidth * 3;(sz_line % 4 != 0) sz_line++;

// выравнивание до СЛОВА (кратно 4)= new BYTE *[biHeight];(int i = 0; i < biHeight; i++)

{[i] = new BYTE[sz_line];.read((char*)MBMP[i], sz_line);

}.close();1;

}.close();0;

}BMP::Save(char FileNames[])

// сохранение изображение в файл

{F;.open(FileNames, ios::out | ios::binary);

// Двоичный для записи

// ЗАПИСЬ ДАННЫХ О ФАЙЛЕ.write((char*)&bfType,sizeof(WORD));.write((char*)&bfSize,sizeof(DWORD));.write((char*)&bfReserved1,sizeof(WORD));.write((char*)&bfReserved2,sizeof(WORD));.write((char*)&bfOffBits,sizeof(DWORD));

// ЗАПИСЬ ДАНННЫХ О ИЗОБРАЖЕНИИ.write((char*)&biSize,sizeof(DWORD));.write((char*)&biWidth,sizeof(LONG));.write((char*)&biHeight,sizeof(LONG));.write((char*)&biPlanes,sizeof(WORD));.write((char*)&biBitCount,sizeof(WORD));.write((char*)&biCompression,sizeof(DWORD));.write((char*)&biSizeImage,sizeof(DWORD));.write((char*)&biXPelsPerMet,sizeof(LONG));.write((char*)&biYPelsPerMet,sizeof(LONG));.write((char*)&biClrUsed,sizeof(DWORD));.write((char*)&biClrImportant,sizeof(DWORD));

// запись данных о пикселяхsz_line = biWidth * 3;(sz_line % 4 != 0) sz_line++;

// выравнивание до СЛОВА (кратно 4)(int i = 0; i < biHeight; i++)

{.write((char*)MBMP[i], sz_line);

}.close();

}BMP::FileSize()// размер файла

{bfSize;

}BMP::Dimensions(int *W, int *H)// размеры изображения

{

*W = biWidth;

*H = biHeight;

}BMP::Col_To_RGB(int col, int* red, int* green, int* blue) // перевод цвета

{(col)

{0: {*red = 0; *green = 0; *blue = 0;}break;

// черный1: {*red = 255; *green = 255; *blue = 255;}break;

// белый2: {*red = 0; *green = 0; *blue = 255;}break;// синий3: {*red = 0; *green = 255; *blue = 0;}break;// зеленый4: {*red = 255; *green = 0; *blue = 0;}break;// красный5: {*red = 255; *green = 0; *blue = 255;}break;// пурпурный6: {*red = 255; *green = 255; *blue = 0;}break;// желтый7: {*red = 0; *green = 255; *blue = 255;}break;// циановый:{*red = 255; *green = 255; *blue = 255;};

}

}BMP::PutPixel(int x, int y, int color) // нарисовать пиксель

{(x < biWidth && y < biHeight)

{*r = new int, *g = new int, *b = new int;_To_RGB(color, r, g, b);[biHeight - y - 1][x*3] = *b;[biHeight - y - 1][x*3 + 1] = *g;[biHeight - y - 1][x*3 + 2] = *r;1;

}0;

}BMP::GetPixel(int x, int y, int *red, int *green, int *blue) // взять цвет пикселя

{(x <= biWidth && y <= biHeight && x >= 0 && y >= 0)

{

*blue = MBMP[biHeight - y - 1][x*3];

*green = MBMP[biHeight - y - 1][x*3 + 1];

*red = MBMP[biHeight - y - 1][x*3 + 2];1;

}0;

}BMP::PutPixelRGB(int x, int y, int red, int green, int blue) // нарисовать пиксель задавая цвет в формате RGB

{(x < biWidth && y < biHeight && x >= 0 && y >= 0)

{[biHeight - y - 1][x*3] = blue;[biHeight - y - 1][x*3 + 1] = green;[biHeight - y - 1][x*3 + 2] = red;1;

}0;

}BMP::DrawLine(int x1, int y1, int x2, int y2, int color) // нарисовать линию

{(x1 <= biWidth && x1 >= 0 && y1 <= biHeight && y1 >= 0 && x2 <= biWidth && x2 >= 0 && y2 <= biHeight && y2 >= 0)

{deltaX = abs(x2 - x1);deltaY = abs(y2 - y1);signX = x1 < x2 ? 1 : -1;signY = y1 < y2 ? 1 : -1;error = deltaX - deltaY;(1)

{(x1, y1, color);(x1 == x2 && y1 == y2)1;error2 = error * 2;(error2 > -deltaY)

{-= deltaY;+= signX;

}(error2 < deltaX)

{+= deltaX;+= signY;

}

}

}0;

}BMP::DrawQuadrangle(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4, int color) // четырёхугольник

{(x1<=biWidth && x1>=0 && y1<=biHeight && y1>=0 && x2<=biWidth && x2>=0 && y2<=biHeight && y2>=0 && x3<=biWidth && x3>=0 && y3<=biHeight && y3>=0 && x4<=biWidth && x4>=0 && y4<=biHeight && y4>=0)

{(x1, y1, x2, y2, color);(x2, y2, x3, y3, color);(x3, y3, x4, y4, color);(x4, y4, x1, y1, color);1;

}0;

}BMP::DrawTriangle(int x1, int y1, int x2, int y2, int x3, int y3, int color) // треугольник

{(x1<=biWidth && x1>=0 && y1<=biHeight && y1>=0 && x2<=biWidth && x2>=0 && y2<=biHeight && y2>=0 && x3<=biWidth && x3>=0 && y3<=biHeight && y3>=0)

{(x1, y1, x2, y2, color);(x2, y2, x3, y3, color);(x3, y3, x1, y1, color);1;

}0;

}BMP::DrawCircle(int x0, int y0, int radius, int color) // рисование окружности

{(x0 < biWidth && y0 < biHeight)

{x = 0;y = radius;delta = 2 - 2 * radius;error = 0;(y >= 0)

{(x0 + x, y0 + y, color);(x0 + x, y0 - y, color);(x0 - x, y0 + y, color);(x0 - x, y0 - y, color);= 2 * (delta + y) - 1;(delta < 0 && error <= 0)

{

++x;+= 2 * x + 1;;

}= 2 * (delta - x) - 1;(delta > 0 && error > 0)

{

-y;+= 1 - 2 * y;;

}

++x;+= 2 * (x - y);

-y;

}1;

}0;

}BMP::Bright(int x) // изменение яркости

{(int i = 0; i < biHeight; i++)(int j = 0; j < biWidth*3; j++)

{(MBMP[i][j] - x > 255)MBMP[i][j] = 255;if(MBMP[i][j] - x < 0)MBMP[i][j] = 0;MBMP[i][j] = MBMP[i][j] - x;

}

}BMP::Contrast(int e) // изменение контрастности

{Y0 = 0;// средняя яркостьk = 1 + e*0.01;// коэффициент

// вычисляется средняя яркость(int i = 0; i < biHeight; i++)(int j = 0; j < biWidth*3; j = j + 3)+= MBMP[i][j] * 0.114 + MBMP[i][j + 1] * 0.587 + MBMP[i][j + 2] * 0.299;= Y0/(biWidth*biHeight);

// изменение цветов пикселей(int i = 0; i < biHeight; i++)(int j = 0; j < biWidth*3; j++)(Y0 + k * (MBMP[i][j] - Y0) > 255)MBMP[i][j] = 255;if(Y0 + k * (MBMP[i][j] - Y0) < 0)MBMP[i][j] = 0;MBMP[i][j] = Y0 + floor(k * (MBMP[i][j] - Y0));

}BMP::QuadrangleRGB(int x1, int y1, int x2, int y2, int rr, int gg, int bb) // изменение цвета прямоугольника

{(x1>biWidth || x1<0 || y1>biHeight || y1<0 || x2>biWidth || x2<0 || y2>biHeight || y2<0)return;(rr > 255)rr = 255;(gg > 255)gg = 255;(bb > 255)bb = 255;*r = new int, *g = new int, *b = new int;(int i = y1; i < y2; i++)(int j = x1; j < x2; j++)

{(j, i, r, g, b);(rr > -1)*r = rr;(gg > -1)*g = gg;(bb > -1)*b = bb;(j, i, *r, *g, *b);

}

}BMP::Imposition(BMP &T, int x, int y, int r, int g, int b) // наложение изображений с прозрачностью цвета rgb

{*rr = new int, *gg = new int, *bb = new int, *w = new int, *h = new int;.Dimensions(w, h);

// получить размерность изображения параметра(r == -1 && g == -1 && b == -1)

// прозрачными будут пиксели цвета верхнего левого угла

{.GetPixel(0, 0, rr, gg, bb);

// получаем цвет левого верхнего угла= *rr; g = *gg; b = *bb;

}(int i = y; i < *h + y && i < biHeight; i++)

// перебираем все пиксели накладываемого изображения(int j = x; j < *w + x && j < biWidth; j++)

{.GetPixel(j - x, i - y, rr, gg, bb);((r == -2 && g == -2 && b == -2) || (*rr != r || *gg != g || *bb != b))PutPixelRGB(j, i, *rr, *gg, *bb);// если не прозрачный, то рисуем

}

}BMP::Resolution()

// уменьшение разрешающей способности

{

// весовая маскаmaska[3][3] = {{1,1,1},{1,1,1},{1,1,1}};*r = new int, *g = new int, *b = new int;sr, sg, sb;TMP(*this);// создание временного изображения(int i = 0; i < TMP.biHeight; i++)

// перебор всех пикселей изображения(int j = 0; j < TMP.biWidth; j++)

{= 0; sg = 0; sb = 0;

// обнуление суммы значений цветов пикселей(int k1 = -1; k1 <= 1; k1++)

// подсчитывание для каждого матрицу(int k2 = -1; k2 <= 1; k2++)(j+k2 < biWidth && i+k1 < biHeight && i+k1 >= 0 && j+k2 >= 0)

{.GetPixel(j + k2, i + k1, r, g, b);

*r = *r * maska[1 + k1][1 + k2];

*g = *g * maska[1 + k1][1 + k2];

*b = *b * maska[1 + k1][1 + k2];+= *r; sg+= *g; sb+= *b;

}

// вычисление средних значений каналов цвета= sr/9;= sg/9;= sb/9;(sr > 255)sr = 255;(sg > 255)sg = 255;(sb > 255)sb = 255;(j, i, sr, sg, sb);

// помещение нового значения в результирующее изображение

}

}BMP::Zoom(int k) // масштабирование

{*r = new int, *g = new int, *b = new int, end;(k > 1)

{TMP(*this);// создание временного изображения>~BMP();

// задание новых размеров и изменение данных о изображении= biWidth * k;= biHeight * k;= biHeight * biWidth * 3 + 54;= biHeight * biWidth * 3;sz_line = biWidth * 3;(sz_line % 4 != 0) sz_line++;

// выравнивание до СЛОВА (кратно 4)= new BYTE *[biHeight];(int i = 0; i < biHeight; i++)

{[i] = new BYTE[sz_line];(int j = 0; j < sz_line; j++)MBMP[i][j] = 255;

}

// перебор всех пикселей изображения(int i = 0; i < TMP.biHeight; i++)(int j = 0; j < TMP.biWidth; j++)

{.GetPixel(j, i, r, g, b);(int k1 = 0; k1 < k; k1++)(int k2 = 0; k2 < k; k2++)(j*k + k1, i*k + k2, *r, *g, *b);

};

}(k < 0)

{TMP(*this);// создание временного изображения>~BMP();

// задание новых размеров и изменение данных о изображении= biWidth / -k;= biHeight / -k;= biHeight * biWidth * 3 + 54;= biHeight * biWidth * 3;sz_line = biWidth * 3;(sz_line % 4 != 0) sz_line++;

// выравнивание до СЛОВА (кратно 4)= new BYTE *[biHeight];(int i = 0; i < biHeight; i++)

{[i] = new BYTE[sz_line];(int j = 0; j < sz_line; j++)MBMP[i][j] = 255;

}

// перебор всех пикселей изображенияsr, sg, sb;(int i = 0; i < biHeight; i++)(int j = 0; j < biWidth; j++)

{(-k % 2 == 0)end = -k/2;end = -k/2 + 1;= 0; sg = 0; sb = 0;

// обнуление суммы значений цветов пикселей(int k1 = k/2; k1 < end; k1++)(int k2 = k/2; k2 < end; k2++)(-j*k+k2 < TMP.biWidth && -i*k+k1 < TMP.biHeight && -i*k+k1 >= 0 && -j*k+k2 >= 0)

{.GetPixel(-j*k + k2, -i*k + k1, r, g, b);+= *r; sg+= *g; sb+= *b;

}= sr/(k*k);= sg/(k*k);= sb/(k*k);(sr > 255)sr = 255;(sg > 255)sg = 255;(sb > 255)sb = 255;(j, i, sr, sg, sb);

// помещаем новое значение в результирующую матрицу

};

}

}BMP::FloodFill(int x, int y, int rz, int gz, int bz) // заливка

{Q;*rn = new int, *gn = new int, *bn = new int;(x, y, rn, gn, bn);// заменяемый цвет*xx = new int, *yy = new int, *r = new int, *g = new int, *b = new int;.Push(x, y); // поместить в очередь(x, y, rz, gz, bz);(Q.Size() != 0)

{.Pop(xx, yy);// изъять из очереди

// пиксель слева(GetPixel(*xx - 1, *yy, r, g ,b))// если этот //цвет заменяемый, то установить его в цвет заливки(*r == *rn && *g == *gn && *b == *bn)

{(*xx - 1, *yy, rz, gz, bz);.Push(*xx - 1, *yy);

}

// пиксель справа(GetPixel(*xx + 1, *yy, r, g ,b))// если этот //цвет заменяемый, то установить его в цвет заливки(*r == *rn && *g == *gn && *b == *bn)

{(*xx + 1, *yy, rz, gz, bz);.Push(*xx + 1, *yy);

}

// пиксель сверху(GetPixel(*xx, *yy - 1, r, g ,b))// если этот //цвет заменяемый, то установить его в цвет заливки(*r == *rn && *g == *gn && *b == *bn)

{(*xx, *yy - 1, rz, gz, bz);.Push(*xx, *yy - 1);

}

// пиксель снизу(GetPixel(*xx, *yy + 1, r, g ,b))// если этот //цвет заменяемый, то установить его в цвет заливки(*r == *rn && *g == *gn && *b == *bn)

{(*xx, *yy + 1, rz, gz, bz);.Push(*xx, *yy + 1);

}

}

}BMP::Lens(int x, int y, int ro, int k) // эффект линзы

{TMP(*this); // временное изображение*r = new int, *g = new int, *b = new int;xx, yy, i;(i = -ro; i <= ro; i++)// перебор всех точек круга

{ogr = sqrt((float)(ro*ro - i*i));(int j = -ogr; j <= ogr; j++)

{= -k*sin(3.14*i/(2*ro));// искажение= -k*sin(3.14*j/(2*abs(ogr)));(abs(i + yy) < ro && abs(j + xx) < abs(ogr))

{.GetPixel(x + j, y + i, r, g, b);

// считываем цвет(x + j + xx, y + i + yy, *r, *g, *b);// записываем пиксель на новое место

}

}

}}

Файл queue.h:QUEUE

{node

{:x, y; // хранимые координаты*next;*prev;(int x1, int y1)

{= x1;= y1;= next = NULL;

}

};sz;*beg, *end;:()// конструктор

{= end = NULL;= 0;

}

~QUEUE()// деструктор

{(beg != NULL)

{*tmp = beg;= beg->prev;tmp;

}= NULL;

}Size(){return sz;}// текущий размерPush(int x1, int y1)// внести в очередь

{*tmp = new node(x1, y1);

// создание нового элемента, с переданными параметрами

// помещение его в конец очереди>next = end;(end == NULL)// если очередь пустая

{= tmp;= tmp;

}

{>prev = tmp;= tmp;

}++;// увеличить счетчик элементов

}Pop(int *x1, int *y1)// взять из очереди

{(sz == 0)return;// очередь пуста

// возврат значений первого элемента

*x1 = beg->x;

*y1 = beg->y;

// удаление первого элемента(sz == 1)// один элемент -> после удаления //очередь становиться пустой

{beg;= end = NULL;-;;

}*tmp = beg;= beg->prev;>next = NULL;tmp;-;

}

};


Министерство образования Российской Федерации Новосибирский Государственный Технический Университет Курсовой п

Больше работ по теме:

КОНТАКТНЫЙ EMAIL: [email protected]

Скачать реферат © 2017 | Пользовательское соглашение

Скачать      Реферат

ПРОФЕССИОНАЛЬНАЯ ПОМОЩЬ СТУДЕНТАМ