Название
поля
|
Размер
(в байтах)
|
Примечание
|
Признак
изображения
|
1
|
2Сhили «,» (ASCII) для
изображения
|
Координатылевого
края изображ.
|
2
|
|
Координаты
верхнего края изображ.
|
2
|
|
Ширина
|
2
|
|
Высота
|
2
|
|
Специальная
информация
|
1
|
Наличие
локальных палитр, прочие локальные параметры изображения
|
Каждый дескриптор изображения начинается с
символа-разделителя изображений. Роль разделителя изображений состоит просто в
синхронизации при входе в дескриптор изображения. Это желательно, если GIF-файл
состоит более, чем из одного изображения. Этот символ определен как
шестнадцатеричное 0x2C или ',' (запятая). Как только этот символ встречается
между изображениями, непосредственно за ним следует дескриптор изображения.
Специальная информация, в этом случае, - это
информация о наличие локальной палитры, в последовательном порядке или порядке
переплетения отформатировано изображение, число бит на пиксель в данном
изображении
Далее идет необязательная локальная палитра
изображения. Потом записываются данные. Сжатые данные хранятся в виде потока
блоков размером меньше 255 байтов. Каждый блок состоит из байта длины блока и,
собственно, данных. Когда данные изображения заканчиваются, идет блок нулевой
длины.
Поток графических данных может создаваться
локально (например, при чтении данных из некого файла), либо передаваться от
удаленного источника (например, по коммуникационным линиям). Данный формат
строится на предположении, что на транспортном уровне для передачи данных
используется такой протокол, который самостоятельно производит коррекцию
ошибок, возникающих при работе с коммуникационными линиями. Поэтому в формате
не предусмотрено никаких проверок с целью обнаружения и коррекции ошибок[4].
1.1.3 Сжатие по методу LZW
Данные файлов GIF
хранятся в упакованном виде сжатым алгоритмом LZW
(Lempel-ZivWelch). LZW - это способ сжатия данных, который извлекает
преимущества при повторяющихся цепочках данных. Поскольку растровые данные
обычно содержат довольно много таких повторений, LZW является хорошим методом
для их сжатия и раскрытия.
Основные понятия:
– "Символ": фундаментальный элемент
данных - индекс, который указывает цвет данного пиксела (K).
– "Цепочка": несколько
последовательных символов. Длина цепочки может изменяться от 1 до очень
большого числа символов ([...]K).
– "Префикс": префикс
непосредственно предшествует символу, может иметь нулевую длину ([...]).
– "Код": число, определяемое
известным количеством бит, которое кодирует цепочку.
– "Поток кодов": выходной поток
кодов, таких как "растровые данные".
– "Элемент": код и его цепочка.
– "Таблица цепочек": список
элементов обычно, но не обязательно, уникальных.
При сжатии и раскрытии LZW манипулирует тремя
объектами: потоком символов, потоком кодов и таблицей цепочек. При сжатии поток
символов является входным и поток кодов - выходным. При раскрытии входным
является поток кодов, а поток символов - выходным. Таблица цепочек порождается
и при сжатии и при раскрытии, однако она никогда не передается от сжатия к
раскрытию и наоборот.
Первым, что необходимо сделать при LZW-сжатии,
является инициализация цепочки символов. Для этого необходимо выбрать код
размера (количество бит), и знать, сколько возможных значений могут принимать
символы.Положим код размера равным 12 битам, что означает возможность
запоминания 0FFF, или 4096, элементов в таблице цепочек.
Чтобы инициализировать таблицу, установим
соответствие кода #0 символу #0, кода #1 to символу #1, и т.д., до кода #31 и
символа #31. Т. е. каждый код от 0 до 31 является корневым (больше в таблице не
будет других кодов, обладающих этим свойством).
Начнем сжатие данных: определим "текущий
префикс" и "текущую цепочку". Префикс изначально ничего не
содержит. "Текущая цепочка" ("[.c.]K) образуется текущим
префиксом и следующим символом в потоке символов.
Рассмотрим первый символ в потоке символов,
назовем его P. Сделаем [.c.]P текущей цепочкой, выполним поиск в таблице
цепочек, чтобы определить входит ли в нее [.c.]P. Если входит, то ничего не
делаем. Затем делаем текущим префикс [.c.]P.
Берем следующий символ из потока символов - Q,
добавим текущий префикс, чтобы сформировать текущую цепочку[.c.]Q. Выполняем
поиск в таблице цепочек, чтобы определить входит ли в нее [.c.]Q. В данном
случае не входит. Добавим [.c.]Q в таблицу цепочек под кодом #32,и выведем код
для [.c.] в поток кодов. Теперь начнем опять с текущего префикса. Продолжаем
добавление символов к [.c.], чтобы сформировать [.c.]K, до тех пор, пока не
сможем найти [.c.]K в таблице цепочек. Затем выводим код для [.c.] и добавляем
[.c.]K в таблицу цепочек.
Алгоритм компрессии LZW
выглядит следующим образом (см. рис. 1.4):
Рисунок 1.4 - Алгоритм компрессии LZW
1.2 Описание графического формата
ВМР
.2.1 Общие сведения
Формат файлов BMP- родной формат Windows. Он
поддерживается всеми графическими редакторами, работающими под управлением этой
операционной системы. Применяется для хранения растровых изображений,
предназначенных для использования в Windows и, по сути, больше ни на что не
пригоден. Способен хранить как индексированный (до 256 цветов), так и RGB-цвет
(16.700.000 оттенков). Возможно применение сжатия по принципу RLE, но делать
это не рекомендуется, так как очень многие программы таких файлов (они могут
иметь расширение .rle) «не понимают». Существует разновидность формата ВМР для
операционной системы OS/2 [2].
1.2.2 Общая структура файла ВМР
Таблица. BMP-файл состоит из четырёх частей (см.
рис. 1.5).
Название
поля
|
Размер
(в байтах)
|
Заголовок
файла
|
14
|
Заголовок
изображения
|
40
|
Палитра
|
Зависит
от количества цветов.
|
Само
изображение
|
Количество
байтов опред. размерами растра и колич. битов на пиксель.
|
Таблица. Структура заголовка ВМР-файла
Название
поля
|
Размер
(в байтах)
|
Примечание
|
bfType
|
2
|
Код
формата, соответствует «ВМ».
|
bfSize
|
4
|
Размер
файла в байтах.
|
bfReserved1
|
2
|
Зарезервировано.
Равно 0.
|
bfReserved2
|
2
|
Зарезервировано.
Равно 0.
|
bfOffBits
|
4
|
Адрес
битового массива в данном файле.
|
Далее в файле идет еще один заголовок -
заголовокизображения (BITMAPINFOHEADER,
можетотсутствовать), в котором хранится описание размеров растра и цветового
формата пикселов (см. рис. 1.7).
Таблица. Структура заголовка изображения
Название
поля
|
Размер
(в байтах)
|
Примечание
|
biSize
|
4
|
Размер
заголовка, равен 40 байт.
|
biWidth
|
4
|
Ширина
изображения.
|
biHeight
|
4
|
Высота
изображения.
|
biplanes
|
2
|
Содержит
1.
|
biBitCount
|
2
|
Битнапиксел.
Можетбыть 1, 4, 8, 16, 24 или 32.
|
biCompression
|
4
|
Компрессия:
0 - без компрессии; 1 - компрессия RLE8 (8 бит
на пиксел); 2 - компрессия RLE4 (4 бита на пиксел); 3 -
без компрессии для 16 и 32 бита на пиксел.
|
4
|
Указывает
размер изображения в байтах.
|
biXPelsPerMeter
|
4
|
Горизонтальное
разрешение в пикселях на метр.
|
biYPelsPerMeter
|
4
|
Вертикальное
разрешение в пикселях на метр.
|
biClrUsed
|
4
|
Количество
используемых цветовых индексов в палитре.
|
biCrlImportant
|
4
|
Указывает
количество индексов, необходимых для отображения изображения.
|
Далее в файле помещается палитра (может и
отсутствовать) в виде записей RGBQUADиз
четырех полей, длина каждого из которых разна 1 байту (см. рис. 1.8).
Таблица. Структура записи RGBQUAD
Название
поля
|
Примечание
|
rgbBlue
|
Компонент
Синий, от 0 до 255
|
rgbGreen
|
Компонент
Зеленый, от 0 до 255
|
rgbRed
|
Компонент
Красный, от 0 до 255
|
rgbReserved
|
Не
используется и равно 0.
|
Количество записей RGBQUAD
равняется количеству используемых цветов.
После палитры (если она есть) в файле ВМР записывается
растр в виде битового массива [5].
Изображение записано построчно.Каждая строка
изображения дополняется нулями до длины, кратной четырем.Надо еще помнить, что
изображение идет как бы перевернутое»вверх ногами», т.е. сначала записана
нижняя строка, потом предпоследняя и так далее до самого верха.
2. Описание алгоритма отображения
файла
.1 Открытие файла BMP
Открытие BMP
файла осуществляется методом LoadFromFile,
который загружает BMP-файл
с заданным именем, считывая его с диска в оперативную память. В процессе
загрузки сначала читается заголовок растрового файла, затем вычисляются размер
заголовка информационного блока в совокупности с цветовой таблицей, который
указывается в поле infoHeadSize.
Помимо этого в поле imageSize
указывается вычисленный размер изображения в байтах. Полученные величины
используются для указания размеров динамически выделяемой памяти под заголовок
информационного блока plnfoHead
и под массив пикселов aBitmapBits.
После выделения указанной памяти соответсвующие компоненты растра читаются из
файла.
На рисунке 2.1 показан алгоритм реализации
чтения BMP файла.
.3 Отображение изображения
Алгоритм отображения изображения представлен на
рисунке
Рисунок 2.4 - Алгоритм отображение файла
Рисунок 2.3 - Алгоритм чтения BMPфайла
2.2 Алгоритм сохранения изображения
в GIF-формате
Алгоритм сохранения изображения в GIF-файл
представлен на рисунке (см. рис. 2.2).
Рисунок 2.2 - Алгоритм сохранения изображения в
формат GIF
3.Описание алгоритмов реализации эффектов
.1 Преобразование цветов между
базисами RGB и CMY
(Cyan, Magenta, Yellow - голубой, пурпурный,
желтый) - аппаратно-ориентированная модель, используемая в полиграфии для
субтрактивного формирования оттенков, основанного на вычитании слоем краски
части падающего светового потока. Цвета модели CMY являются дополнительными к
цветам модели RGB, т.е. дополняющими их до белого.
Рисунок 3.1 - Цветовой куб модели CMY
Таким образом, система координат CMY - тот же
куб, что и для RGB, но с началом отсчета в точке с RGB координатами (1,1,1),
соответствующей белому цвету. Цветовой куб модели CMY показан на рисунке 2.4.
КонвертацияRGB
в CMY:C
:= 255 - R; M
:= 255 - G; Y
:= 255 - B;
КонвертацияCMY
в RGB: R
:= 255 - C; G
:= 255 - M; B
:= 255 - Y;
Рисунок3.3 - КонвертацияCMYвRGB
Рис.
3.2 Преобразование цветов между
базисами RGB и HSV
(Hue, Saturation, Value - цветовой тон,
насыщенность, количество света) - модель, ориентированная на человека и
обеспечивающая возможность явного задания требуемого оттенка цвета (рис. 3).
Подпространство, определяемое данной моделью - перевернутый шестигранный конус.
По вертикальной оси конуса задается V -
светлота, меняющаяся от 0 до 1. Значению V = 0 соответствует вершина конуса,
значению V = 1 - основание конуса; цвета при этом наиболее интенсивны.
Цветовой тон H задается углом, отсчитываемым
вокруг вертикальной оси. В частности, 0° - красный, 60° -
желтый, 120° - зеленый, 180° - голубой, 240° -
синий, 300° - пурпурный, т.е. дополнительные цвета расположены друг против
друга (отличаются на 180°).
Насыщенность S определяет насколько близок цвет
к "чистому" пигменту и меняется от 0 на вертикальной оси V до 1 на
боковых гранях шестигранного конуса.
Рисунок 3.4 - Разложение HSV
Точка V = 0, в которой находится вершина конуса,
соответствует черному цвету. Значение S при этом может быть любым в диапазоне
0-1. Точка с координатами V = 1, S = 0 - центр основания конуса соответствует
белому цвету. Промежуточные значения координаты V при S=0, т.е. на оси конуса,
соответствуют серым цветам. Если S = 0, то значение оттенка H считается
неопределенным.
Рисунок 3.5 - КонвертацияRGBвHSV
Рисунок 3.6 - КонвертацияHSV
в RGB
3.3 Зашумление составляющей M
Алгоритм зашумления изображения по составляющей Mпредставлен
на рисунке 3.7.
Рисунок 3.7 - Алгоритм зашумления изображения по
M
Для того чтобы зашумить составляющую M
в изображениинеобходимо если в файле есть палитра, то к каждому цвету палитры
параметра Mприбавить заданный
шум.
Если в файле нет палитры, то каждый пиксель
нужно разложить на CMY,
прибавить к Mзаданный шум,
вернуть пиксель в предыдущий формат и сохранить полученное значение.
В случае если полученное значение составляющей Mвыходит
за границы допустимого его корректируют в зависимости от максимально и
минимально возможного для значения пикселя данного размера.
3.4 Зашумление составляющей S
Алгоритм зашумления изображения составляющей S
представлен на рисунке 3.8.
Рисунок 3.8 - Алгоритм зашумления составляющей S.
Данные в программе хранятся в базисе RGB
и для зашумления составляющей S
базиса HSV необходимо
выполнить преобразование цвета каждого пикселя из базиса RGB в базис HSV,
которое выполняет процедура RGBtoHSV.
Далее требуется выполнить зашумление составляющей S,
прибавлением к ней шума, заданного пользователем, и обратное преобразование из
одного базиса в другой, выполняемое функцией HSVtoRGB.
3.5 Фильтрация изображения
Для реализации фильтрации изображения
использовался фильтр, который задается матрицей 3x3.
Матрица изображена на рис. 3.4.
Рисунок 3.9 - Матрица фильтра 6
Рисунок 3.10 - Алгоритм фильтрации изображения.
Изображение покрывается этой матрицей, в цикле
попиксельно. При этом каждый элемент матрицы умножается с каждой составляющей
соответствующего пикселя. При чем, если составляющая выходит за рамки 0...255,
то она приравнивается к ближайшей границе этого интервала.
Алгоритм фильтра представлен на рис. 3.5
.6 Эффект наложения кругов
Эффект наложения кругов выполняется при помощи
созданной вручную матрицы нулей и единиц, где нулями обозначен круг. Разложив
изображение в базис RGB,
каждая компонента умножается на элемент матрицы.
Рисунок 3.11 - Эффект наложения кругов
4. Структура приложения
Структура системы представлена в виде схемы (см.
рис. 4.1).
Рисунок 4.1 - Структура приложения
5.Выбор инструментальных средств для
реализации программы, обоснование выбора
В связи с тем, что сегодня уровень сложности
программного обеспечения очень высок, разработка приложений Windows с
использованием только одного какого-либо языка программирования значительно
затрудняется. Программист должен затратить массу времени на решение стандартных
задач по созданию многооконного интерфейса. Реализация технологии связывания и
встраивания объектов потребует от программиста еще более сложной работы.
Одним из самых популярных инструментов для
создания функциональных и удобных Windows-приложений
является язык программирования C++
и входящая в состав MicrosoftVisualStudio
2008, WindowsForms.
Она включает в себя практически весь программный интерфейс Windows и позволяют
пользоваться при программировании средствами более высокого уровня, чем обычные
вызовы функций. За счет этого значительно упрощается разработка приложений,
имеющих сложный интерфейс пользователя, облегчается поддержка технологии OLE и
взаимодействие с базами данных.
Данная курсовая работа выполнена на
объектно-ориентированном языкеС++. Это объясняется тем, что программные
продукты созданные в с помощью C++наиболее
просты в использовании и не требуют от пользователей глубоких знаний в
управлении программами.
6.Описание основных модулей
программы
Класс Formatпредназначен
для работы с файлом BMP.
Реализация класса показана на рисунке 6.1.
Рисунок 6.1 - Интерфейс класса Format
Кроме традиционных для класса методов, таких как
конструктори деструктор, класс Format
содержит методы, перечисленные ниже:
) Метод CreateDib24
создает в памяти 24-разрядный растр с заданными шириной и высотой. В процессе
создания осуществляется инициализация полей заголовкарастрового файла и
заголовка информационного блока. После этого выделяетсяпамять для хранения
массива пикселов. В завершение открывается дисковый файлс заданным именем,
предназначенный для сохранения в нем создаваемого растра.
) Метод SetPixel
осуществляет прямой доступ к пикселам в 24-разрядном растре.Цветовая информация
для синей, зеленой и красной составляющих цветапиксела записывается в
соответствующие элементы массива aBitmapBits.
Адресаэлементов вычисляются через номер строки развертки у и номер пиксела в
строке х.
) Метод StoreDib24
сохраняет созданный растр, записывая его на диск вформате GIF.
) Метод LoadFromFile
загружает BMP-файл с
заданным именем, считывая егос диска в оперативную память. В процессе загрузки
сначала читается заголовокрастрового файла, затем вычисляются размер заголовка
информационного блока в совокупности с цветовой таблицей, который указывается в
поле infoHeadSize.Помимо
этого в поле imageSize
указывается вычисленный размер изображенияв байтах. Полученные величины
используются для указания размеров динамически выделяемой памяти под заголовок
информационного блока plnfoHeadи
под массив пикселов aBitmapBits.
После выделения указанной памяти соответствующие компоненты растра читаются из
файла.
) Метод Draw
выводит растр наповерхность графического устройства, используя функцию StretchDIBits.
) Метод RgbToHlsпереводит
даныые изображения из RGBв
HLS.
) Метод HlsToRgbпереводит
данные изображения из HLSв
RGB.
) Метод NoiseMзашумляет
составляющую M
) Метод NoiseSпереводит
данные изображения из RGBв
HLS, зашумляет
составляющую Sи обратно переводит
из HLSв RGB.
) Метод Filterприменяет
фильтр «размытие» к изображению.
Таблица 6.1 Методы класса KDib.
Метод
|
Тип
|
Назначение
|
CreateDib24
|
BOOL
|
Создает
GIF - файл
|
StoreDib24
|
VOID
|
Пересылка
данных изображения
|
LoadFromFile
|
BOOL
|
Загружает
BMP
- файл
|
SetPixel
|
VOID
|
Устанавливает
пиксель в контексте
|
Draw
|
Вывод
на экран изображения
|
GetWidth
|
INT
|
Возвращает
ширину
|
GetHeight
|
INT
|
Возвращает
высоту
|
GetError
|
CHAR*
|
Возвращает
ошибку
|
RGBtoHSV
|
VOID
|
Переводит
из RGB в HSV
|
HSVToRGB
|
VOID
|
Переводит
из HSV в RGB
|
LoadFromFile
|
BOOL
|
Загружает
BMP - файл
|
GetA
|
BYTE*
|
Возвращает
массив пикселов
|
Draw
|
INT
|
Вывод
на экран изображения
|
GetWidth
|
INT
|
Возвращает
ширину
|
GetHeight
|
INT
|
Возвращает
высоту
|
NoiseB
|
VOID
|
ЗашумляетB
|
NoiseS
|
VOID
|
Защумляет
S
|
Filter
|
VOID
|
Фильтрует
|
7.Тестирование, результаты работы программы
Программа написана под операционную систему от
WindowsXP до WindowsVISTA.
Для установки системы нет необходимости в особых настройках.
Требованияк аппаратной платформе - процессор
должен быть типа Pentium или Celeron с тактовой частотой не ниже 166 МГц
(рекомендуется Pentium III800
МГц), оперативной памяти - 512 Мбайт (рекомендуется 1024 Мбайт), достаточное
количество свободного дискового пространства всего 50Mб.
В результате была разработана программа, имеющая
интерфейс, удобный и простой для пользователя, выполняющая открытие, сохранение
файлов графических форматов GIF
и BMP, и реализующая
спецэффекты.
Выводы
В разработанном приложении решены поставленные в
техническом заданиизадачи, и реализованы требуемые возможности для работы с
графическими форматами GIFи
ВМР.
Приложение является законченной программой,
однако, оно может быть дополнено многими другими возможностями, в
частности,работа с другими графическими форматами данных, реализованы
дополнительные графические эффекты: разложение по другим базисам, эффекты шума
для нескольких составляющих.
К недостаткам данного проекта можно отнести
ограниченность его применения только в учебных и методических целях.
Приложение
Листинг программы
Format.h
class Format {:* aBitmapBits;// массив пикселов*
aBitmapBits1;* aBitmapCMY;* aBitmapHSV;R;G;B;();
~Format();CreateDib24(int w, int h, constchar*
fileName);StoreDib24();LoadFromFile(constchar* fileName);SetPixel(int x, int y,
COLORREF color);Draw(HDC hdc, int xDst, int yDst, int wDst, int hDst,xSrc, int
ySrc, int wSrc, int hSrc, DWORD rop);GetWidth() { return width; }GetHeight() {
return height; }* GetError() { return
error.c_str();}RGBtoCMY();RGBtoHSV();CMYtoRGB();HSVtoRGB();BazisС();BazisM();BazisY();BazisH();BazisS();BazisV();NoiseM();NoiseS();Filter();Save();Circ();Transformtocirc(int
x,int y);Draw1(HDC hdc, int xDst, int yDst, int wDst, int hDst,xSrc, int ySrc,
int wSrc, int hSrc, DWORD rop);TransformPix(int x,int
y);:width;height;bytesPerLine;fileHead; // заголовокрастровогофайлаinfoHead; //
заголовокинформационногоблока* pInfoHead;fileHeadSize;infoHeadSize;imageSize;error;outFile;
};.cpp
#include"Format.h"
#include<math.h>::Format()
{= sizeof(BITMAPFILEHEADER);.bfType = 0x4d42;=
NULL;
}::~Format() {(pInfoHead) delete []
pInfoHead;(aBitmapBits) delete [] aBitmapBits;(outFile) outFile.close();
}Format::CreateDib24(int w, int h, constchar*
fileName) {= w;= h;= ((width * 24 + 31) / 32) * 4;= bytesPerLine * height;=
sizeof(BITMAPINFOHEADER);.bfSize = fileHeadSize + infoHeadSize + bytesPerLine *
height;.bfOffBits = fileHeadSize + infoHeadSize;.biSize = infoHeadSize;.biWidth
= width;.biHeight = height;.biPlanes = 1;.biBitCount = 24;.biCompression =
BI_RGB;.biSizeImage = imageSize;;.open(fileName, ios::out | ios::binary |
ios::trunc);(!outFile) return FALSE;TRUE;
}Format::LoadFromFile(constchar* fileName) {inpFile;.open(fileName,
ios::in | ios::binary);(!inpFile) {= "Неверное имя файла или
каталога.";FALSE;
}.read((char*)&fileHead,
fileHeadSize);(fileHead.bfType != 0x4d42) {= "Этоне BMP-файл";FALSE;
}= fileHead.bfOffBits - fileHeadSize;fileSize =
fileHead.bfSize;= fileSize - (fileHeadSize + infoHeadSize);=
(BITMAPINFOHEADER*)(new BYTE [infoHeadSize]);.read((char*)pInfoHead,
infoHeadSize);= pInfoHead->biWidth;= pInfoHead->biHeight;= new
BYTE[imageSize];.read((char*)aBitmapBits, imageSize);;
}Format::Draw(HDC hdc, int xDst, int yDst, int
wDst, int hDst,xSrc, int ySrc, int wSrc, int hSrc, DWORD rop)
{StretchDIBits(hdc, xDst, yDst, wDst, hDst, xSrc, ySrc, wSrc, hSrc,, (CONST
BITMAPINFO*)pInfoHead, DIB_RGB_COLORS, rop);
}Format::SetPixel(int x, int y, COLORREF color)
{row = y;col = 3 * x;[row*bytesPerLine + col] =
GetBValue(color);[row*bytesPerLine + col+1] =
GetGValue(color);[row*bytesPerLine + col+2] = GetRValue(color);;
}Format::StoreDib24() {
// Записьзаголовка
BMP-файла.write((char*)&fileHead, fileHeadSize);.write((char*)&infoHead,
infoHeadSize);
//
Записьмассивапикселей.write((char*)aBitmapBits, imageSize);
}Format::CMYtoRGB()
{hdc;R,G,B,C,M,Y;x = GetWidth();y =
GetHeight();bytesPerLine = ((x * 24 + 31) / 32) * 4;row = y;col = 3 * x;(int
row = 0;row < y;row++)(int col = 0;col < x;col++){=
aBitmapCMY[row*bytesPerLine + col*3 + 2];= aBitmapCMY[row*bytesPerLine +
(col*3)+ 1];= aBitmapCMY[row*bytesPerLine + (col*3)];= 255-C;= 255-M;=
255-Y;[row*bytesPerLine + (col*3)] = B;[row*bytesPerLine + (col*3)+ 1] =
G;[row*bytesPerLine + col*3 + 2] = R;
};
{R,G,B,C,M,Y;x = GetWidth();y = GetHeight();row
= y;col = 3 * x;bytesPerLine = ((x * 24 + 31) / 32) * 4;= x * y * 3;= new
BYTE[imageSize];(int row = 0;row < y;row++)(int col = 0;col < x;col++){=
aBitmapBits[row*bytesPerLine + col*3 + 2];= aBitmapBits[row*bytesPerLine +
(col*3)+ 1];= aBitmapBits[row*bytesPerLine + (col*3)];= 255-R;= 255-G;=
255-B;[row*bytesPerLine + (col*3)] = Y;[row*bytesPerLine + (col*3)+ 1]
= M;[row*bytesPerLine + col*3 + 2] = C;
}=aBitmapCMY;
}Format::RGBtoHSV(){R,G,B,H,S,V;rgbmin,rgbmax;rc,bc,gc;ht=0.0,st=0.0;x
= GetWidth();y = GetHeight();row = y;col = 3 * x;bytesPerLine = ((x * 24 + 31)
/ 32) * 4;= x * y * 3;= new BYTE[imageSize];(int row = 0;row < y;row++)(int
col = 0;col < x;col++)
{= aBitmapBits[row*bytesPerLine + col*3 + 2];=
aBitmapBits[row*bytesPerLine + (col*3)+ 1];= aBitmapBits[row*bytesPerLine +
(col*3)];= min(R,min(G,B));= max(R,max(G,B));(rgbmax > 0.0)= (rgbmax -
rgbmin) / rgbmax;(st > 0.0) {= (rgbmax - R) / (rgbmax - rgbmin);= (rgbmax -
G) / (rgbmax - rgbmin);= (rgbmax - B) / (rgbmax - rgbmin);(R == rgbmax) ht = bc
- gc;(G == rgbmax) ht = 2 + rc - bc;(B == rgbmax) ht = 4 + gc - rc;= ht *
60.0;(ht < 0.0) ht += 360.0;
}= ht / 360.0;= rgbmax;= st;[row*bytesPerLine +
(col*3)] = V;[row*bytesPerLine + (col*3)+ 1] = S;[row*bytesPerLine + col*3
+ 2] = H;
}
}Format::HSVtoRGB()
{R,G,B,H,S,V,i_H;ii;fr;c1, c2, c3;x =
GetWidth();y = GetHeight();row = y;col = 3 * x;bytesPerLine = ((x * 24 + 31) /
32) * 4;(int row = 0;row < y;row++)(int col = 0;col < x;col++){_H =
aBitmapHSV[row*bytesPerLine + col*3 + 2];= aBitmapHSV[row*bytesPerLine +
(col*3)+ 1];= aBitmapHSV[row*bytesPerLine + (col*3)];(!S)= G = B = V;
{(i_H >= 360)_H -= 360;= i_H;= (int)(H /=
60.0);= H - ii;= (V * (255 - S)) / 255;= (V * (255 - S * fr)) / 255;= (V * (255
- S * (1.0 - fr))) / 255;(ii)
{0: R = V; G = c3; B = c1; break;1: R = c2; G =
V; B = c1; break;2: R = c1; G = V; B = c3; break;3: R = c1; G = c2; B = V;
break;4: R = c3; G = c1; B = V; break;5: R = V; G = c1; B = c2; break;
} // switch
} // if (!sat)[row*bytesPerLine + (col*3)] =
B;[row*bytesPerLine + (col*3)+ 1] = G;[row*bytesPerLine + col*3 + 2] = R;
}
}Format::NoiseM(){M;x = GetWidth();y =
GetHeight();bytesPerLine = ((x * 24 + 31) / 32) * 4;(int row = 0;row <
y;row++)(int col = 0;col < x;col++){= aBitmapCMY[row*bytesPerLine +
(col*3)+1];+=rand();(M < 0) M = 0;(M > 255) M = 255;[row*bytesPerLine +
(col*3)+1] = M;
}= aBitmapCMY;
}Format::NoiseS(){S;x = GetWidth();y =
GetHeight();bytesPerLine = ((x * 24 + 31) / 32) * 4;(int row = 0;row <
y;row++)(int col = 0;col < x;col++){= aBitmapHSV[row*bytesPerLine +
(col*3)+1];+=rand();(S < 0) S = 0;(S > 255) S = 255;[row*bytesPerLine +
(col*3)+1] = S;
}= aBitmapHSV;
}Format::TransformPix(int x,int
y){NewBGR[3];Pixel[3];Pix[3];w = GetWidth();h = GetHeight();count =
9;Matrix[9]={1,2,1,
,4,2,
,2,1};bytesPerLine = ((w * 24 + 31) / 32) * 4;
// x y(int c = 0; c < 3; c++){[c] =
aBitmapBits[y*bytesPerLine + x*3 + c];[c] = NewBGR[c] * Matrix[4];
}
// x-1 y-1(int c = 0; c < 3; c++){[c] = aBitmapBits[(y-1)*bytesPerLine
+ (x-1)*3 + c];[c] += NewBGR[c] * Matrix[0];
}
// x y-1(int c = 0; c < 3; c++){[c] =
aBitmapBits[y*bytesPerLine + (x-1)*3 + c];[c] += NewBGR[c] * Matrix[1];
}
// x+1 y-1(int c = 0; c < 3; c++){[c] =
aBitmapBits[(y+1)*bytesPerLine + (x-1)*3 + c];[c] += NewBGR[c] * Matrix[2];
}
// x+1 y(int c = 0; c < 3; c++){[c] =
aBitmapBits[(y+1)*bytesPerLine + x*3 + c];[c] += NewBGR[c] * Matrix[5];
}
// x+1 y+1(int c = 0; c < 3; c++){[c] =
aBitmapBits[(y+1)*bytesPerLine + (x+1)*3 + c];[c] += NewBGR[c] * Matrix[8];
}
// x y+1(int c = 0; c < 3; c++){[c] =
aBitmapBits[y*bytesPerLine + (x+1)*3 + c];[c] += NewBGR[c] * Matrix[7];
}
// x-1 y+1(int c = 0; c < 3; c++){[c] =
aBitmapBits[(y-1)*bytesPerLine + (x+1)*3 + c];[c] += NewBGR[c] * Matrix[6];
}
// x-1 y(int c = 0; c < 3; c++){[c] =
aBitmapBits[(y-1)*bytesPerLine + x*3 + c];[c] += NewBGR[c] * Matrix[3];
}(int c = 0; c < 3; c++){(count!=0)[c] =
Pixel[c]/count;[c] = BYTE (Pixel[c]);(Pix[c] < 0)[c] = 0;(Pix[c] >
255)[c]=255;[y*bytesPerLine + x*3 + c] = Pix[c];
}
}Format::Filter(){w = GetWidth();h =
GetHeight();= w * h * 4;= new BYTE[imageSize];(int y = 1; y < h-1;y++)(int x
= 1;x < w-1;x++){(x,y);
}= aBitmapHSV;
}Format::BazisС()
{R,G,B,C,M,Y;x = GetWidth();y = GetHeight();row
= y;col = 3 * x;bytesPerLine = ((x * 24 + 31) / 32) * 4;= x * y * 3;= new
BYTE[imageSize];(int row = 0;row < y;row++)(int col = 0;col < x;col++){=
aBitmapBits[row*bytesPerLine + col*3 + 2];= aBitmapBits[row*bytesPerLine +
(col*3)+ 1];= aBitmapBits[row*bytesPerLine + (col*3)];= 255-R;= G-G;=
B-B;[row*bytesPerLine + (col*3)] = Y;[row*bytesPerLine + (col*3)+ 1] =
M;[row*bytesPerLine + col*3 + 2] = C;
}=aBitmapCMY;
}Format::BazisM()
{R,G,B,C,M,Y;x = GetWidth();y = GetHeight();row
= y;col = 3 * x;bytesPerLine = ((x * 24 + 31) / 32) * 4;= x * y * 3;= new
BYTE[imageSize];(int row = 0;row < y;row++)(int col = 0;col < x;col++){=
aBitmapBits[row*bytesPerLine + col*3 + 2];= aBitmapBits[row*bytesPerLine +
(col*3)+ 1];= aBitmapBits[row*bytesPerLine + (col*3)];= R-R;= 255-G;=
B-B;[row*bytesPerLine + (col*3)] = Y;[row*bytesPerLine + (col*3)+ 1] =
M;[row*bytesPerLine + col*3 + 2] = C;
}=aBitmapCMY;
}Format::BazisY()
{R,G,B,C,M,Y;x = GetWidth();y = GetHeight();row
= y;col = 3 * x;bytesPerLine = ((x * 24 + 31) / 32) * 4;= x * y * 3;= new
BYTE[imageSize];(int row = 0;row < y;row++)(int col = 0;col < x;col++){=
aBitmapBits[row*bytesPerLine + col*3 + 2];= aBitmapBits[row*bytesPerLine +
(col*3)+ 1];= aBitmapBits[row*bytesPerLine + (col*3)];= R-R;= G-G;=
255-B;[row*bytesPerLine + (col*3)] = Y;[row*bytesPerLine + (col*3)+ 1] =
M;[row*bytesPerLine + col*3 + 2] = C;
}=aBitmapCMY;
}Format::BazisH(){R,G,B,H,S,V;rgbmin,rgbmax;rc,bc,gc;ht=0.0,st=0.0;x
= GetWidth();y = GetHeight();row = y;col = 3 * x;bytesPerLine = ((x * 24 + 31)
/ 32) * 4;= x * y * 3;= new BYTE[imageSize];(int row = 0;row < y;row++)(int
col = 0;col < x;col++)
{= aBitmapBits[row*bytesPerLine + col*3 + 2];=
aBitmapBits[row*bytesPerLine + (col*3)+ 1];= aBitmapBits[row*bytesPerLine +
(col*3)];= min(R,min(G,B));= max(R,max(G,B));(rgbmax > 0.0)= (rgbmax -
rgbmin) / rgbmax;(st > 0.0) {= (rgbmax - R) / (rgbmax - rgbmin);= (rgbmax -
G) / (rgbmax - rgbmin);= (rgbmax - B) / (rgbmax - rgbmin);(R == rgbmax) ht = bc
- gc;(G == rgbmax) ht = 2 + rc - bc;(B == rgbmax) ht = 4 + gc - rc;= ht *
60.0;(ht < 0.0) ht += 360.0;
}= ht / 360.0;= rgbmin;= 0;[row*bytesPerLine +
(col*3)] = V;[row*bytesPerLine + (col*3)+ 1] = S;[row*bytesPerLine + col*3
+ 2] = H;
}=aBitmapHSV;
}Format::BazisS(){R,G,B,H,S,V;rgbmin,rgbmax;rc,bc,gc;ht=0.0,st=0.0;x
= GetWidth();y = GetHeight();row = y;col = 3 * x;bytesPerLine = ((x * 24 + 31)
/ 32) * 4;= x * y * 3;= new BYTE[imageSize];(int row = 0;row < y;row++)(int
col = 0;col < x;col++)
{= aBitmapBits[row*bytesPerLine + col*3 + 2];=
aBitmapBits[row*bytesPerLine + (col*3)+ 1];= aBitmapBits[row*bytesPerLine +
(col*3)];= min(R,min(G,B));= max(R,max(G,B));(rgbmax > 0.0)= (rgbmax -
rgbmin) / rgbmax;(st > 0.0) {= (rgbmax - R) / (rgbmax - rgbmin);= (rgbmax -
G) / (rgbmax - rgbmin);= (rgbmax - B) / (rgbmax - rgbmin);(R == rgbmax) ht = bc
- gc;(G == rgbmax) ht = 2 + rc - bc;(B == rgbmax) ht = 4 + gc - rc;= ht *
60.0;(ht < 0.0) ht += 360.0;
}= 0.0;= 0 ;= st;[row*bytesPerLine + (col*3)]
= V;[row*bytesPerLine + (col*3)+ 1] = S;[row*bytesPerLine + col*3 + 2] = H;
}=aBitmapHSV;
}Format::BazisV(){R,G,B,H,S,V;rgbmin,rgbmax;rc,bc,gc;ht=0.0,st=0.0;x
= GetWidth();y = GetHeight();row = y;col = 3 * x;bytesPerLine = ((x * 24 + 31)
/ 32) * 4;= x * y * 3;= new BYTE[imageSize];(int row = 0;row < y;row++)(int
col = 0;col < x;col++)
{= aBitmapBits[row*bytesPerLine + col*3 + 2];=
aBitmapBits[row*bytesPerLine + (col*3)+ 1];= aBitmapBits[row*bytesPerLine +
(col*3)];= min(R,min(G,B));= max(R,max(G,B));(rgbmax > 0.0)= (rgbmax -
rgbmin) / rgbmax;(st > 0.0) {= (rgbmax - R) / (rgbmax - rgbmin);= (rgbmax -
G) / (rgbmax - rgbmin);= (rgbmax - B) / (rgbmax - rgbmin);(R == rgbmax) ht = bc
- gc;(G == rgbmax) ht = 2 + rc - bc;(B == rgbmax) ht = 4 + gc - rc;= ht *
60.0;(ht < 0.0) ht += 360.0;
}= 0.0;= rgbmax ;= 0;[row*bytesPerLine +
(col*3)] = V;[row*bytesPerLine + (col*3)+ 1] = S;[row*bytesPerLine + col*3
+ 2] = H;
}=aBitmapHSV;
}Format::Save()
{x = GetWidth();y = GetHeight();bytesPerLine =
((x * 24 + 31) / 32) * 4;= x * y * 3;= new BYTE[imageSize];=aBitmapBits;
}Format::Draw1(HDC hdc, int xDst, int yDst, int
wDst, int hDst,xSrc, int ySrc, int wSrc, int hSrc, DWORD rop)
{x = GetWidth();y = GetHeight();bytesPerLine =
((x * 24 + 31) / 32) * 4;= x * y * 3;= new
BYTE[imageSize];=aBitmapBits1;StretchDIBits(hdc, xDst, yDst, wDst, hDst, xSrc,
ySrc, wSrc, hSrc,, (CONST BITMAPINFO*)pInfoHead, DIB_RGB_COLORS, rop);
}Format::Circ()
{Matrix[11][11]={1,1,1,1,0,0,0,1,1,1,1,
,1,1,0,0,1,0,0,1,1,1,
,1,0,0,1,1,1,0,0,1,1,
,0,1,1,1,1,1,1,1,0,0,
,1,1,1,1,1,1,1,1,1,0,
,0,1,1,1,1,1,1,1,0,0,
,0,0,1,1,1,1,1,0,0,1,
,1,0,0,1,1,1,0,0,1,1,
,1,1,0,0,1,0,0,1,1,1,
,1,1,1,0,0,0,1,1,1,1};R,G,B;I=0,J=0;w =
GetWidth();h = GetHeight();row = h;col = 3 * w;bytesPerLine = ((w * 24 + 31) /
32) * 4;(int i = 0;i < h; i++)
{(int j = 0;j < w; j++)
{= aBitmapBits[j*bytesPerLine + i*3 + 2];=
aBitmapBits[j*bytesPerLine + (i*3)+ 1];= aBitmapBits[j*bytesPerLine +
(i*3)];*=Matrix [I][J];*=Matrix [I][J];*=Matrix [I][J];[j*bytesPerLine + (i*3)]
= B;[j*bytesPerLine + (i*3)+ 1] = G;[j*bytesPerLine + i*3 + 2] = R;++;(J==11)
{=0;
//j+=1;
}
}++;=0;(I==11)
{=0;
//i+=1;
}
};
}