Студопедия КАТЕГОРИИ: АвтоАвтоматизацияАрхитектураАстрономияАудитБиологияБухгалтерияВоенное делоГенетикаГеографияГеологияГосударствоДомЖурналистика и СМИИзобретательствоИностранные языкиИнформатикаИскусствоИсторияКомпьютерыКулинарияКультураЛексикологияЛитератураЛогикаМаркетингМатематикаМашиностроениеМедицинаМенеджментМеталлы и СваркаМеханикаМузыкаНаселениеОбразованиеОхрана безопасности жизниОхрана ТрудаПедагогикаПолитикаПравоПриборостроениеПрограммированиеПроизводствоПромышленностьПсихологияРадиоРегилияСвязьСоциологияСпортСтандартизацияСтроительствоТехнологииТорговляТуризмФизикаФизиологияФилософияФинансыХимияХозяйствоЦеннообразованиеЧерчениеЭкологияЭконометрикаЭкономикаЭлектроникаЮриспунденкция |
Сохранение изображения в файле
Для того чтобы сохранить изображение в файл, как минимум необходимо знать дескриптор сохраняемого изображения. После того как дескриптор нам известен, требуется заполнить структуру BITMAPINFOHEADER, которая содержит информацию о размере и формате цвета изображения, не зависящего от устройства (device-independent bitmap (DIB)). Для этих целей используется дескриптор нашего изображения и дескриптор контекста устройства. Контекст устройства удобно взять от окна рабочего стола.
hwndScreen=GetDesktopWindow(); hdcScreen = GetDC( hwndScreen );
Для заполнения структуры потребуется несколько раз вызвать функцию GetDIBits. Эта функция применяется для выборки двоичных данных указанного растрового изображения в буфер с использованием указанного формата. В неё мы передаем дескрипторы контекста устройства и изображения, и основываясь на из данных заполняем поля нашей структуры. В качестве массива для данных изображения указываем NULL, так как первоначально нам требуется определить свойства самого изображения заносимого в структуру BITMAPINFO.
GetDIBits( hdcScreen, // дескриптор контекста устройства bitmap, // дескриптор изображения 0, // первая строка развертки, которая должна // быть выбрана 0, // число копируемых линий NULL, // адрес массива для битов изображения (BITMAPINFO*)info, // адрес структуры для данных изображения DIB_RGB_COLORS // RGB или индекс палитры ); После того как структура будет заполнена, требуется определить количество бит приходящихся на один пиксель. Если это число не является 4, 8 или 24, то устанавливаем количество бит в 24, и указываем, что изображение не сжато. После этого определяем размер изображения основываясь на данных полученных в предыдущем шаге. После того как размер изображения будет определен, необходимо заполнить массив битов изображения, путем вторичного вызова функции GetDIBits. Если массив успешно заполнен, следует инициализировать структуру содержащую информацию о типе, размере и местоположении файла в котором будет сохранено изображение. Для этого потребуется заполнить поле bfOffBits, характеризующее сдвиг от начала структуры BITMAPFILEHEADER до массива бит и bfSize – характеризующее размер в байтах файла изображения.
//Сдвиг от начала структуры BITMAPFILEHEADER до массива бит finfo.bfOffBits=sizeof(BITMAPFILEHEADER)+ sizeof(BITMAPINFOHEADER)+ (sizeof(RGBQUAD)*ctsize); // Размер файла изображения в байтах finfo.bfSize=finfo.bfOffBits+imgsize; finfo.bfReserved1=0; finfo.bfReserved2=0; Когда все манипуляции со структурами и данными будут завершены, потребуется создать файл для изображения и последовательно записать в него структуру содержащую заголовок файла, затем структуру с информацией о изображении и в завершении массив бит этого изображения. Ну и соответственно не забыть закрыть открытые дескрипторы и освободить контекст устройства. Ниже приведен исходный код, позволяющий сохранить изображение окна в файл.
void PrintWindow(HWND hWnd) { HDC hDCMem = CreateCompatibleDC(NULL); RECT rect; GetWindowRect(hWnd, & rect);
HBITMAP hBmp = NULL; HDC hDC = GetDC(hWnd); hBmp = CreateCompatibleBitmap(hDC, rect.right - rect.left, rect.bottom - rect.top); ReleaseDC(hWnd, hDC);
HGDIOBJ hOld = SelectObject(hDCMem, hBmp); SendMessage(hWnd, WM_PRINT, (WPARAM) hDCMem, PRF_CHILDREN | PRF_CLIENT | PRF_ERASEBKGND | PRF_NONCLIENT | PRF_OWNED);
SelectObject(hDCMem, hOld); DeleteObject(hDCMem);
OpenClipboard(hWnd);
EmptyClipboard(); SetClipboardData(CF_BITMAP, hBmp); CloseClipboard(); }
BOOL SaveBitmap(char *name,HBITMAP bitmap) { HDC hdcScreen; // Контекст устройства экрана HWND hwndScreen; // Дескриптор окна рабочего стола int i; // Количество выбираемых линий BYTE *bits; // Указатель0020на массив битов изображения BITMAPINFOHEADER *info; // Информационная структура изображения HANDLE fp; // Дескриптор файла BITMAPFILEHEADER finfo; // Заголовок файла изображения long ctsize,imgsize,pixels;// Различные размерности для записи файла DWORD dw; // Код возврата char *ptr; // Указатель используемый для записи открытого BM
// Получаем дескриптор рабочего стола hwndScreen=GetDesktopWindow(); // Получаем контекст устройства рабочего стола hdcScreen = GetDC( hwndScreen );
// Выделяем память под структуру с информацией о изображении info = (BITMAPINFOHEADER*)GlobalAlloc(GMEM_FIXED,sizeof(BITMAPFILEHEADER)+(1024*sizeof(RGBQUAD))); info->biSize = sizeof(BITMAPINFOHEADER); info->biBitCount = 0;
// Заполняем структуру информацией о изображении i = GetDIBits( hdcScreen, // дескриптор контекста устройства bitmap, // дескриптор изображения 0, // первая строка развертки, которая должна быть выбрана 0, // число копируемых линий NULL, // адрес массива для битов изображения (BITMAPINFO*)info, // адрес структуры для данных изображения DIB_RGB_COLORS // RGB или индекс палитры ); // Определяем количество бит на пиксель. if( (info->biBitCount!=4) && (info->biBitCount!=8) && (info->biBitCount!=24) ) info->biBitCount=24; // Указываем что изображение не сжато info->biCompression=BI_RGB;
// Получаем количество пикселей pixels=info->biWidth*info->biHeight; switch(info->biBitCount) { case 4:ctsize=16;imgsize=pixels/2;break; case 8:ctsize=256;imgsize=pixels;break; case 16:ctsize=0;imgsize=pixels*2;break; case 24:ctsize=0;imgsize=pixels*3;break; case 32:ctsize=0;imgsize=pixels*4;break; default: ReleaseDC( hwndScreen,hdcScreen ); return FALSE; }
// Инициализируем массив для битов изображения bits = (unsigned char*)GlobalAlloc(GMEM_FIXED,imgsize);
//Заполняем массив битов изображения i = GetDIBits( hdcScreen, // дескриптор контекста устройства bitmap, // дескриптор изображения 0, // первая выбираемая линия для изображения назначения info->biHeight, // количество выбираемых линий bits, // адрес массива битов изображения (BITMAPINFO*)info,// адрес структуры с данными изображения DIB_RGB_COLORS // RGB или индекс палитры );
// Формируем заголовок файла ptr = (char *)&finfo.bfType; ptr[0]='B'; ptr[1]='M';
//Определяем сдвиг от начала структуры BITMAPFILEHEADER до массива бит finfo.bfOffBits=sizeof(BITMAPFILEHEADER)+ sizeof(BITMAPINFOHEADER)+ (sizeof(RGBQUAD)*ctsize); // Размер файла изображения в байтах finfo.bfSize=finfo.bfOffBits+imgsize; finfo.bfReserved1=0; finfo.bfReserved2=0;
//Создаем файл для изображения fp = CreateFile(name, // указатель с именем файла GENERIC_WRITE, // режим доступа 0, // режим использования NULL, // указатель на параметры безопасности CREATE_ALWAYS, // метод создания FILE_ATTRIBUTE_NORMAL|FILE_FLAG_SEQUENTIAL_SCAN,// атрибуты файла NULL ); // Записываем структуру заголовка файла WriteFile(fp,&finfo,sizeof(BITMAPFILEHEADER),&dw,NULL); // Записываем структуру информации изображения WriteFile(fp,info,sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD)*ctsize,&dw,NULL); // Записываем биты изображения WriteFile(fp,bits,imgsize,&dw,NULL); // Закрываем файл CloseHandle(fp); //Освобождаем память с информацией изображения GlobalFree(info); // Освобождаем память с битами изображения GlobalFree(bits); // Освобождаем контекст устройства ReleaseDC(hwndScreen,hdcScreen); return TRUE; }
|
||
Последнее изменение этой страницы: 2018-04-12; просмотров: 585. stydopedya.ru не претендует на авторское право материалов, которые вылажены, но предоставляет бесплатный доступ к ним. В случае нарушения авторского права или персональных данных напишите сюда... |