Как стать автором
Обновить

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

C++ *
Ожидает приглашения

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

Впервые столкнувшись с 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+ можно повернуть изображение на любой угол.

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

Теги:
Хабы:
Данная статья не подлежит комментированию, поскольку её автор ещё не является полноправным участником сообщества. Вы сможете связаться с автором только после того, как он получит приглашение от кого-либо из участников сообщества. До этого момента его username будет скрыт псевдонимом.