![]() |
|
|
#1
|
||||
|
||||
|
Здравия всем!
Столкнулся с некоторой проблемкой при работе с 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)
| ||