Манипуляции с цветом и некоторые другие возможности GDI+
В главе 21 вы уже встречались с описанием функций GdipDrawImageRectRect и GdipDrawImageRectRectI, которые копируют выделенную область изображения на указанное место растра. Особенностью этих функций является то, что в процессе рисования они используют объект ImageAttributes. В этом разделе мы рассмотрим, как с помощью этого объекта можно менять баланс цветов изображения. Объект ImageAttributesСоздаётся объект ImageAttributes функцией GdipCreateImageAttributes. Вот её объявление: DECLARE Long GdipCreateImageAttributes IN Gdiplus.dll Long @ nativeImageAttributes где nativeImageAttributes — возвращаемый дескриптор объекта ImageAttributes. Функция GdipDisposeImageAttributes уничтожает этот объект. Вот её объявление: DECLARE Long GdipDisposeImageAttributes IN Gdiplus.dll Long nativeImageAttributes где nativeImageAttributes — дескриптор объекта ImageAttributes. Объект ImageAttributes позволяет выполнять множество операций над изображением, позволяя создавать многофункциональные графические редакторы. Наша же задача предельно проста: научиться изменять цветовую гамму и степень прозрачности для конкретного изображения. Для этого мы должны при помощи функции GdipSetImageAttributesColorMatrix передать этому объекту цветовую матрицу размером 5x5, представляющую собой массив, состоящий из пяти строк и пяти столбцов вещественных чисел. Структура матрицы показана на рис. 23.7. Рис. 23.7. Матрица преобразования цветов Каждый столбец матрицы (кроме последнего) определяет, как
будет изменена цветовая компонента (Red, Green, Blue)
или прозрачность (Alpha). Последний столбец выполняет служебные
функции. Ячейки матрицы, в которых на рис. 23.7 указаны числовые значения (0
или 1), не могут содержать никаких других значений, кроме указанных. А вот
ячейки, в которых написано слово Val, могут содержать различные значения
(конечно, в допустимых пределах — но об этом чуть позже) и предназначены они
для вычисления нового значения каждой цветовой компоненты. Как вы полагаете, как изменится цветовая гамма изображения, если массив будет отображать следующую матрицу (рис. 23.8)? При использовании такой матрицы цветовая гамма изображения никак не изменится: действительно, значение каждой цветовой компоненты должно быть умножено на единицу, а цветовые векторы пикселей суммируются с нулевыми значениями пятой строки матрицы. А как изменится цветовая гамма после обработки вот такой цветовой матрицы (рис. 23.9)? Рис. 21.9. Матрица, корректирующая цветовую гамму изображения Сначала вычисления выполняются над первыми четырьмя
строками матрицы, в результате чего значение красной цветовой компоненты
удваивается (но оно не может быть более чем 255), значения цветов остальных
компонент и прозрачность остаются без изменения.
Как применить всё вышеизложенное на практике? Нужно
создать объект ImageAttributes и при помощи функции
GdipSetImageAttributesColorMatrix передать ему массив, содержащий цветовую
матрицу. DECLARE Long GdipSetImageAttributesColorMatrix IN Gdiplus.dll ; Long nativeImageAttributes, Long type, Long enable, String colorMatrix, ; String grayMatrix, Long flags Передаваемые функции параметры:
Таблица 23.4. Значения параметра flags функции GdipSetImageAttributesColorMatrix
Пример корректировки цветовой гаммы изображенияВ листинге 23.28 показан код примера, позволяющего изменить цветовую гамму изображения (предполагается, что в переменной nativeImage находится указатель на область памяти, в которую загружено изображение).
DECLARE Long GdipDrawImageRectRectI IN Gdiplus.dll Long, Long, Long, Long, Long, Long, ; Long, Long, Long, Long, Long, Long, Long, Long DECLARE Long GdipGetImagePixelFormat IN Gdiplus.dll Long, Long @ DECLARE Long GdipCreateImageAttributes IN Gdiplus.dll Long @ DECLARE Long GdipSetImageAttributesColorMatrix IN Gdiplus.dll ; Long nativeImageAttributes, Long, Long, String, String, Long DECLARE Long GdipDisposeImageAttributes IN Gdiplus.dll Long DECLARE Long GdipGetImageWidth IN Gdiplus.dll Long, Long @ DECLARE Long GdipGetImageHeight IN Gdiplus.dll Long, Long @ DECLARE Long GdipDeleteGraphics IN Gdiplus.dll Long * Получаем размеры исходного изображения nSrcX = 0 nSrcY = 0 nSrcWidth = 0 nSrcHeight = 0 = GdipGetImageWidth(nativeImage, @nSrcWidth) = GdipGetImageHeight(nativeImage, @nSrcHeight) * Размеры конечного изображения должны быть равны * размерам исходного изображения nDstX = nSrcX nDstY = nSrcY nDstWidth = nSrcWidth nDstHeight = nSrcHeight * Создаём объект Graphics, связанный с исходным изображением nativeGraphics = 0 GdipGetImagePixelFormat(nativeImage, @nativeGraphics) * Создаём массив, содержащий цветовую матрицу. DIMENSION aColorMatrix[5,5] STORE 0 TO aColorMatrix aColorMatrix[1,1] = 1 && Кратность для цветов не меняется aColorMatrix[2,2] = 1 aColorMatrix[3,3] = 1 aColorMatrix[4,4] = 1 aColorMatrix[5,5] = 1 * Установка приращений для цветов aColorMatrix[5,1] = -0.2 && Уменьшаем интенсивность красного на 20% aColorMatrix[5,2] = 0 && Зелёный цвет не изменяем aColorMatrix[5,3] = 0.25 && Увеличиваем интенсивность синего на 25% aColorMatrix[5,4] = 1 && Растр полностью непрозрачный * Заносим массив в строку cColorMatrix = '' FOR i = 1 TO 25 cColorMatrix = cColorMatrix + BINTOC(aColorMatrix[i], 'F') ENDFOR * Создаём объект ImageAttributes nativeImageAttributes = 0 GdipCreateImageAttributes(@nativeImageAttributes) * Передаём объекту цветовую матрицу GdipSetImageAttributesColorMatrix(nativeImageAttributes, 1, 1, cColorMatrix, 0, 0) * Теперь можно рисовать GdipDrawImageRectRectI(nativeGraphics, nativeImage, nDstX, nDstY, nDstWidth, nDstHeight, ; nSrcX, nSrcY, nSrcWidth, nSrcHeight, 0, cColorMatrix, 0, 0) * Убираем "мусор" GdipDisposeImageAttributes(nativeImageAttributes) GdipDeleteGraphics(nativeGraphics) Ещё несколько функций GDIPlus…Вы уже познакомились с достаточно большим количеством функций GDIPlus. Но значительно большее их количество осталась за рамками изложенного материала. В этом разделе вы познакомитесь ещё с несколькими функциями, которые позволяют:
Перо, рисующее кистьюДо сих пор мы рассматривали перо как инструмент для рисования линий.
Возможность рисовать линии кистью позволяет получить очень интересные
эффекты. Например, представьте себе перо, рисующее градиентной кистью.
Нарисованные им линии будут переливаться всеми цветами радуги! DECLARE Long GdipCreatePen2 IN diplus.dll ; Long nativeBrush, Single width, Long unit, Long @ nativePen Передаваемые функции параметры:
Изменение вида начала или конца линииФункция GdipSetPenStartCap «пририсовывает» элемент к началу линии, а функция GdipSetPenEndCap — к концу. Вот их объявление в Visual FoxPro: DECLARE Long GdipSetPenStartCap IN Gdiplus.dll Long nativePen, Long startCap DECLARE Long GdipSetPenEndCap IN Gdiplus.dll Long nativePen, Long endCap Передаваемые функциям параметры:
Таблица 23.5. Виды «наконечников» линий
Получение и установка цвета пикселейВозвращает цвет пикселя функция GdipBitmapGetPixel, а устанавливает — функция GdipBitmapSetPixel. Вот их объявление в Visual FoxPro: DECLARE Long GdipBitmapGetPixel IN Gdiplus.dll Long nativeImage, Long x, Long y, Long @ color DECLARE Long GdipBitmapSetPixel IN Gdiplus.dll ; Long nativeImage, Long x, Long y, Long color Параметры функций:
|