Pull to refresh

Быстрый поворот Bitmap в Win32/Winapi на C++ без GDI+

Привет, Хабр!

Впервые столкнувшись с Bitmap в Winapi, сразу осознал все свое бессилие перед возможностью transform и rotate данного дьявольского создания объекта.

Из исследования, проведенного по сети, были выделены несколько основных вариантов поворота изображения:

  1. Повернуть изображение, представив его в виде BYTE* (массив байтов)

  2. Повернуть не изображение, а контекст в котором оно находится

Первое, понятно! Получаем через BITMAPINFOHEADER массив байтов и поворачиваем его с помощью матрицы поворота x = x'*cos(angle)-y'*sin(angle), y=x'*sin(angle)+y'*cos(angle)

Со вторым оказалось куда сложнее. Контексты, созданные при помощи CreateCompatibleDC() не поддавались.

Но родился данный вариант решения проблемы:

HBITMAP RotateHBITMAPFlip()
{
	POINT point[3];
	point[1].x = point[1].y = 0;
	point[0].x = bitmap.bmWidth; point[0].y = 0;
	point[2].x = bitmap.bmWidth; point[2].y = bitmap.bmHeight;
	HDC hdc = CreateCompatibleDC(NULL);
	SelectObject(hdc, hBitmap);
	PlgBlt(hdc, point, hdc, 0, 0, bitmap.bmWidth, bitmap.bmHeight, NULL, 0, 0);
	HBITMAP hb = (HBITMAP)CopyImage(GetCurrentObject(hdc, OBJ_BITMAP), IMAGE_BITMAP, bitmap.bmWidth, bitmap.bmHeight, LR_COPYRETURNORG);
	DeleteDC(hdc);
	return hb;
}

В чем его суть?!

Данный вариант функции/метода применяется для поворота исходного изображения hBitmap, с которого создан BITMAP bitmap. Первым делом, создаем структуру из 3-х точек, которые будут отвечать за новые углы BITMAP изображения:

  1. Верхний левый угол

  2. Верхний правый угол

  3. Нижний левый угол

Как итог, эти 3 точки формируют прямоугольник — некое представление нашего изображения в виде «полигона». Следующий этап — создание контекста, выбор в него HBITMAP и применение функции PlgBlt, которая позволяет перенести из контекста в контекст изображения, сформированное относительно полигонов, представленных аргументом типа POINT * (2-ой аргумент).

После всех проделанных действий, мы можем получить готовое изображения с помощью функции GetCurrentObject(hdc,typeobject).

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

Вот таким, довольно, кратким способом без применения GDI+ можно повернуть изображение на любой угол.

Спасибо за внимание!

Tags:
Hubs:
You can’t comment this publication because its author is not yet a full member of the community. You will be able to contact the author only after he or she has been invited by someone in the community. Until then, author’s username will be hidden by an alias.