![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Серый Битмап
DevilDevil © (2006-10-19 16:58:00)Создаю 24-х или 32-х битные битмапы (средствами API) без особых проблем. Пытаюсь создать 8-битный палитровый, каждый цвет которого - оттенок серого... Битмап не создаётся, результат равен нулю. Что я делаю не правильно?
function CreateGrayBitmap(width, height : word) : HBitmap;
var
BI : PBitmapInfo;
Bits : Pointer;
BIsize, i : integer;
begin
BiSize := sizeof(TBitmapInfoHeader) + 1024; //PaletteSize;
BI := nil;
Bits := nil;
try
GetMem(BI, BiSize);
ZeroMemory(BI, sizeof(TBitmapInfoHeader));
BI.bmiHeader.biSize := BiSize ;
BI.bmiHeader.biWidth := width ;
BI.bmiHeader.biHeight := height ;
BI.bmiHeader.biPlanes := 1;
BI.bmiHeader.biBitCount := 8;
BI.bmiHeader.biSizeImage:= ((width+3) shr 2)*4*Height;
// заполняю палитру
for i := 0 to 255 do
DWORD(BI.bmiColors[i]) := RGB(i, i, i);
Result := CreateDIBSection(0, BI^, 0,Bits,0,0);
finally
if BI <> nil then FreeMem(BI);
end;
end;
Rouse_ (2006-10-19 23:17:00) [1]
> Далековато от API реализации... Ты скажи, у меня то что
> неправильно?
Да собственно, тогда след элемент, думаю теперь будет понятно что забыл...:
// создадим битмап из
// растра цветов и растра маски иконки
DC := GetDC(0);
if DC = 0 then OutOfResources;
try
pColorBuffer := nil;
// Создаем DIB секцию для растра цветов
hDIBColor := GDICheck(CreateDIBSection(DC, PBitmapInfo(@BI)^,
DIB_RGB_COLORS, pColorBuffer, 0, 0));
try
// Создаем контекст устройства памяти
hdcColor := GDICheck(CreateCompatibleDC(DC));
try
// Назначаем контексту объект (DIB секцию)
hdcTempColor := SelectObject(hdcColor, hDIBColor);
try
SetBkColor(hdcColor, RGB(1, 1, 1));
// Копируем растр цвета
SetDIBitsToDevice(hdcColor, 0, 0, BI.biWidth, BI.biHeight, 0,
0, 0, BI.biHeight, pDIBColor, PBitmapInfo(@BI)^, DIB_RGB_COLORS);
// Модифицируем BitmapInfoHeader для работы с растром маски
with BI do
begin
biBitCount := 1;
biSizeImage := BytesPerScanline(biWidth, biBitCount, 32) * biHeight;
biClrUsed := 2;
biClrImportant := 2;
end;
Colors := Pointer(DWORD(@BI) + SizeOf(BI));
Colors^[0] := 0;
Colors^[1] := $FFFFFF;
// Создаем DIB секцию для растра маски
pMaskBuffer := nil;
hDIBMask := GDICheck(CreateDIBSection(0, PBitmapInfo(@BI)^,
DIB_RGB_COLORS, pMaskBuffer, 0, 0));
try
// Создаем контекст устройства памяти
hdcMask := GDICheck(CreateCompatibleDC(0));
try
// Назначаем контексту объект (DIB секцию маски)
hdcTempMask := SelectObject(hdcMask, hDIBMask);
try
// Копируем растр маски
SetDIBitsToDevice (hdcMask, 0, 0, BI.biWidth, BI.biHeight, 0,
0, 0, BI.biHeight, pDIBMask, PBitmapInfo(@BI)^, DIB_RGB_COLORS);
// Выводим маску на переданный канвас
BitBlt(ACanvas.Handle, P.X, P.Y, BI.biWidth, BI.biHeight,
hdcMask, 0, 0, SRCAND);
finally
SelectObject(hdcMask, hdcTempMask);
end;
finally
DeleteObject(hdcMask);
end;
finally
DeleteObject(hDIBMask);
end;
// Инвертируем поверх маски цветовой растр
BitBlt(ACanvas.Handle, P.X, P.Y, BI.biWidth, BI.biHeight,
hdcColor, 0, 0, SRCINVERT);
finally
SelectObject(hdcColor, hdcTempColor);
end;
finally
DeleteObject(hdcColor);
end;
finally
DeleteObject(hDIBColor);
end;
finally
ReleaseDC(0, DC);
end;
finally
BI.biHeight := BI.biHeight shl 1;
end;
DevilDevil (2006-10-19 19:10:00) [2]так почему в отдельном приложении
Pbytearr[i] := b;работает, а в моём раюочем вызывает ошибку выхода за предел доступной памяти? И то и это свободно компилируются в одинаковой версии Delphi
Sapersky (2006-10-19 18:54:00) [3]Pbytearr[i] := b;
Скобки (также как ".") сами выполняют ^
DevilDevil (2006-10-19 18:33:00) [4]ошибку нашёл, так надо:
BI.bmiHeader.biSize := sizeof(TBitmapInfoHeader);
и ещё одно мето нашёл...
кто нить знает, почему обращениеBI.bmiColors[i]может компилироваться неправильно? Это уже не первый раз, именно в этом проекте [рабочем проекте] обращениеPbytearr[i]^ := b; вызывает ошибку, в то время, как обращениеpbyte(integer(Pbytearr) + i)^ := b;работает корректно.
Eraser (2006-10-19 18:29:00) [5]> где флаг DIB_PAL_COLORS?
пардон. замечание лишнее.
Eraser (2006-10-19 18:26:00) [6]> [6] DevilDevil © (19.10.06 18:13)
> что я сделал неправильно?
> Пытаюсь создать 8-битный
> Result := CreateDIBSection(0, BI^, 0,Bits,0,0);
где флаг DIB_PAL_COLORS?
Sapersky (2006-10-19 18:19:00) [7]> Помоему VCL удобнее API...
именно.
Вот как раз работу с палитрой в TBitmap приходится делать теми же API-функциями.
Да и VCL товарища, чувствую, не устраивает по религиозным соображениям.
См. TFastDIB:
http://sourceforge.net/project/showfiles.php?group_id=173551
Хотя... примеры этот типа "админ проекта" так и не выложил... ну примерно так:
fd := TFastDIB.Create;
fd.SetSize(Width, Height, 8);
fd.FillColors(0, 255, [tfBlack, tfWhite]);
<...>
fd.Free;
DevilDevil (2006-10-19 18:13:00) [8]плохой пример, лишнего много.
Вопрос: что я сделал неправильно? Задача элементарная для профи должна быть.
Eraser (2006-10-19 18:13:00) [9]> [6] DevilDevil © (19.10.06 18:13)
эт тебе так кажется, что лишнее :)
Eraser (2006-10-19 18:09:00) [10]> [4] DevilDevil © (19.10.06 18:07)
> Помоему VCL удобнее API...
именно.
кстати если уж так хочется писать на API, VCL - хороший пример, как это делать.
DevilDevil (2006-10-19 18:07:00) [11]> Eraser © (19.10.06 17:42) [1]
Помоему VCL удобнее API...
> Rouse_ © (19.10.06 17:55) [2]
Далековато от API реализации... Ты скажи, у меня то что неправильно?
Rouse_ (2006-10-19 17:56:00) [12]BytesPerScanline из Graphics.pas
Rouse_ (2006-10-19 17:55:00) [13]вот тебе кусочек из рабочего класса:
with BI do
begin
biHeight := biHeight shr 1; // Высота включает высоту маски
biSizeImage := BytesPerScanline(biWidth, biBitCount, 32) * biHeight;
case biBitCount of
1, 4, 8, 16: nNumColors := 1 shl biBitCount;
else
nNumColors := 0;
end;
end;
try
// Рассчитываем размеры таблицы цветов, растра цветов и растра маски
nColorTableSize := nNumColors * SizeOf(TRGBQuad);
nDIBColorSize := (((BI.biWidth * BI.biBitCount + 31) shr 5) * BI.biHeight) shl 2;
nDIBMaskSize := (((BI.biWidth + 31) shr 5)* BI.biHeight) shl 2;
// Получаем указатели на таблицу цветов, растр цветов и растр маски
pColorTable := Pointer(DWORD(@BI) + SizeOf(BI));
pDIBColor := Pointer(DWORD(pColorTable) + nColorTableSize);
pDIBMask := Pointer(DWORD(pDIBColor) + nDIBColorSize);
Eraser (2006-10-19 17:42:00) [14]> [0] DevilDevil © (19.10.06 16:58)
по-моему проще использовать класс TBitmap.