Дипломная работа: Разработка программного обеспечения для фильтрации растровых изображений
Саму фильтрацию изображения можно выполнять по-разному. Например, можно передать фильтру всю исходную картинку и ожидать от него уже полностью преобразованного изображения. А можно пропускать через фильтр исходное изображение по одному пикселу. В последнем случае не придется дублировать цикл обработки всего изображения в каждом фильтре, и вызывающая фильтр процедура получит полный контроль над областью изображения, к которой будет применено преобразование.
Реализуем на практике второй способ организации "фильтрации". При этом сам процесс преобразования изображения вынесем в отдельный поток (назовем его "рабочим" потоком) выполнения программы. Это даст нам возможность контролировать не только область применения фильтра, но и продолжительность выполнения операции, т.е. возможность остановить выполнение "фильтрации". Общая схема преобразования в этом случае будет выглядеть следующим образом:
1. Пришла команда выполнить преобразование - создаем рабочий поток.
2. Уведомляем объекты-облики о том, что начали преобразование. Приэтом облик запускает таймер и начинает периодически интересоваться,сколько процентов работы выполнено, показывая пользователю процентвыполнения.
3. В рабочем потоке выполняется преобразование и увеличивается процент выполнения.
4. По окончании преобразования (или если пользователь прервал выполнение) в объекты-облики посылаются сообщения о завершении работы ипоказывается преобразованная картинка.
Поскольку данными в программе ВМViewer заведует класс CBMDoc, именно в него и поместим "фильтрацию". Для создания рабочего потока потребуется добавить в класс CBMDoc несколько методов:
Transform() - создает рабочий поток;
ThreadProc () - функция потока, запускает "фильтрацию" для конкретного объекта-документа;
TransformLoop() - сама "фильтрация";
InformAllViews() - передает сообщения всем обликам документа; Рассмотрим метод TransformLoop() (Листинг 3.6.1).
Листинг 3.6.1 – Метод CBMDoc::TransformLoop(). Файл BMDoc.cpp
void CBMDoc::TransformLoop()
{if(m_pCurFilter==NULL) return;
if(!CreateCompatibleBuffer()) return;
m_EventDoTransform.SetEvent();
m_bEditable=FALSE;
InformAllViews(UM_STARTTRANSFORM);
CRaster*pSBM=GetCurrentBMPtr(),//источник
*pDBM=GetBufferBMPtr();// приёмник
// Установили в фильтр источник и приёмник преобразований
m_pCurFilter->SetBuffers(pSBM, pDBM);
for(LONG y=0; y<pSBM->GetBMHeight(); y++)
{// Процент выполнения
InterlockedExchange(&m_lExecutedPercent, 100*y/pSBM->GetBMHeight());
//Проверка не решили ли прервать преобразование
if(!m_EventDoTransform.Lock(0))
{InformAllViews(UM_ENDOFTRANSFORM, FALSE, 0);
m_bEditable=TRUE;