|
#1
|
||||
|
||||
4 bit HBitmap
Здравия всем!
Столкнулся с некоторой проблемкой при работе с HBitmap; Использую WinAPI. Суть - Не могу сделать SelectObject на 4 битный битмап. Использую именно 4 битный, т.к. графические данные подготовлены в 16 цветной индексированной палитре, поэтому переводить в 32 бит - затратно для производительности приложения. Вот пример использования: Код:
Const data2: array[0..63] of byte = ( $00, $00, $00, $00, $01, $00, $01, $00, $41, $00, $71, $00, $55, $00, $7C, $00, $00, $00, $00, $00, $01, $00, $01, $00, $41, $00, $71, $00, $55, $00, $7C, $00, $00, $00, $00, $00, $01, $00, $01, $00, $41, $00, $71, $00, $55, $00, $7C, $00, $00, $00, $00, $00, $01, $00, $01, $00, $41, $00, $71, $00, $55, $00, $7C, $00 ); ... procedure TForm1.Button1Click(Sender: TObject); var HDC:THandle; BufferImages:HBitmap; BDC:THandle; Select:LongWord; begin Image1.Picture.Bitmap.Width:=8; Image1.Picture.Bitmap.Height:=8; HDC:=Image1.Picture.Bitmap.Canvas.Handle; BufferImages:=CreateBitmap(8,8,1,4,@data2); //??? BDC:=CreateCompatibleDC(HDC); Select:= SelectObject(BDC,BufferImages); if Select =0 then ShowMessage('Selected error'); BitBlt(HDC,0,0,8,8,BDC,0,0,SRCCOPY); ReleaseDC(BDC,BufferImages); DeleteDC(BDC); DeleteObject(BufferImages); end; CreateBitmap(8,8,1,1,@data2) - то нормально, а если: CreateBitmap(8,8,1,4,@data2) - то SelectObject = 0 и соответственно на контексте ничего. Аналогичная ошибка при 8, 16 битах, а 32 понятно норм. При этом сам CreateBitmap возвращает идентификатор в любом случае. а установка Код:
Image1.Picture.Bitmap.PixelFormat:=pf4bit; Пробовал использовать CreateDIBSelection, SetDIBits, StretchDiBits - не помогает. SetDIBits и StretchDiBits что-то пытаются, но слишком геморно. Собственно вопрос как отрисовать 4 битный битмап (на 32 битном контексте)? Програмистами не рождаются, ими становятся! |
#2
|
|||
|
|||
Цитата:
Ничего не подсказывает? Т.е. для начала надо смотреть в сторону CreateCompatibleBitmap. Последний раз редактировалось lmikle, 07.03.2017 в 19:41. |
#3
|
||||
|
||||
Нет, CreateCompatibleBitmap создает на основе контекста, а контекст 32 битый, а значит что битмап на выходе будет 32 битный, а мне нужен 4 битный. В этом и прикол. В итоге мне удалось реализовать задуманное через CreateDIBSelection.
Если вдруг кому понадобится: Что нам надо, 1. Переменную структуры BITMAPINFO, в которой опишем нужный нам формат битмапа. 2. Переменную Pointer, что бы знать куда писать данные. 3. Массив с палитрой типа RGBQUAD. 4. Собственно данные. Код:
var ImgBitInfo:BITMAPINFO; //Описание битмапа hDC:LongWord; //Контекст BufferedImage:LongWord; // Битмап PImgArrayPix: Array [0..7] of Integer; //Массив данных //можно брать 4 byte на строчку из 8 px, но это равносильно 1 integer i,color:Integer; //Переменки PbyteArray:Pointer; //Указатель на память Palletes:array [0..3] of RGBQUAD; //Палитра begin //Заполняем структуру with ImgBitInfo.bmiHeader do begin biSize:=sizeof(ImgBitInfo.bmiHeader); biWidth:=8; //размер картинки 8 px biHeight:=8;//размер картинки 8 px biPlanes:=1; //Всегда 1 biBitCount:=4; //4 бита на пиксель, палитра 16 цветов, индексированные цвета biCompression:=0; //без компрессии biClrUsed:=4; //используем только 4 цвета end; //Создаем Битмап, точнее область в памяти // с DIB данными с заданными параметрами BufferedImage :=CreateDIBSection(DC,ImgBitInfo,0,PbyteArray,0,0); //теперь PbyteArray - это указатель на адрес памяти где лежат данные DIB //Создаем контекст hdc :=CreateCompatibleDC(DC); //Выбираем это хозяйство SelectObject(hdc, BufferedImage); //Заполняем палитру нужными цветами for i := 0 to 3 do begin color:=NesColor[palettes[Palette,0,i]]; //Каким угодно образом Palletes[i].rgbRed := GetRValue(color);//заполняем палитру Palletes[i].rgbGreen:= GetGValue(color);// Palletes[i].rgbBlue := GetBValue(color);// end; SetDIBColorTable(hDC,0,4,Palletes); //Применяем палитру к контексту // 0 - первый индекс цвета, 4 - количество цветов //Заполняем массив данных, читаем его или подготавливаем заранее for i := 0 to 7 do PImgArrayPix[7-i]:=bit2Int(maps_Tables[Mapper,code,0, i],maps_Tables[Mapper,code,1,i]); //Заполняется снизу вверх //Копируем все данные массива, в адрес полученный ранее CopyMemory(PbyteArray, @PImgArrayPix, 32); //Выводим полученное изображение куда надо, TransparentBlt(dc,x,y,8,8,hdc,0,0,8,8,NesColor[palettes[Palette,0,0]]);//с прозрачностью //BitBLT(DC,x,y,x+8,y+8,hdc,0,0,SRCCOPY); //или без //Удаляем переменные. ReleaseDC(hDC,BufferedImage); DeleteDC(hDC); DeleteObject(BufferedImage); end; Програмистами не рождаются, ими становятся! Последний раз редактировалось SCrat.ORS, 08.03.2017 в 10:55. |
Этот пользователь сказал Спасибо SCrat.ORS за это полезное сообщение: | ||
IvoX (22.05.2019)
|