Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2007.03.04;
Скачать: CL | DM;

Вниз

Серый Битмап   Найти похожие ветки 

 
DevilDevil ©   (2006-10-19 16:58) [0]

Создаю 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;


 
Eraser ©   (2006-10-19 17:42) [1]

> [0] DevilDevil ©   (19.10.06 16:58)

по-моему проще использовать класс TBitmap.


 
Rouse_ ©   (2006-10-19 17:55) [2]

вот тебе кусочек из рабочего класса:

 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);


 
Rouse_ ©   (2006-10-19 17:56) [3]

BytesPerScanline из Graphics.pas


 
DevilDevil ©   (2006-10-19 18:07) [4]

> Eraser ©   (19.10.06 17:42) [1]

Помоему VCL удобнее API...

> Rouse_ ©   (19.10.06 17:55) [2]

Далековато от API реализации... Ты скажи, у меня то что неправильно?


 
Eraser ©   (2006-10-19 18:09) [5]

> [4] DevilDevil ©   (19.10.06 18:07)


> Помоему VCL удобнее API...

именно.

кстати если уж так хочется писать на API, VCL - хороший пример, как это делать.


 
DevilDevil ©   (2006-10-19 18:13) [6]

плохой пример, лишнего много.

Вопрос: что я сделал неправильно? Задача элементарная для профи должна быть.


 
Eraser ©   (2006-10-19 18:13) [7]

> [6] DevilDevil ©   (19.10.06 18:13)

эт тебе так кажется, что лишнее :)


 
Sapersky   (2006-10-19 18:19) [8]

> Помоему 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;


 
Eraser ©   (2006-10-19 18:26) [9]

> [6] DevilDevil ©   (19.10.06 18:13)


> что я сделал неправильно?


> Пытаюсь создать 8-битный          


> Result := CreateDIBSection(0, BI^, 0,Bits,0,0);

где флаг DIB_PAL_COLORS?


 
Eraser ©   (2006-10-19 18:29) [10]

> где флаг DIB_PAL_COLORS?

пардон. замечание лишнее.


 
DevilDevil ©   (2006-10-19 18:33) [11]

ошибку нашёл, так надо:
BI.bmiHeader.biSize     := sizeof(TBitmapInfoHeader);

и ещё одно мето нашёл...
кто нить знает, почему обращение BI.bmiColors[i] может компилироваться неправильно? Это уже не первый раз, именно в этом проекте [рабочем проекте] обращение Pbytearr[i]^ := b; вызывает ошибку, в то время, как обращение pbyte(integer(Pbytearr) + i)^ := b; работает корректно.


 
Sapersky   (2006-10-19 18:54) [12]

Pbytearr[i] := b;
Скобки (также как ".") сами выполняют ^


 
DevilDevil ©   (2006-10-19 19:10) [13]

так почему в отдельном приложении Pbytearr[i] := b; работает, а в моём раюочем вызывает ошибку выхода за предел доступной памяти? И то и это свободно компилируются в одинаковой версии Delphi


 
Rouse_ ©   (2006-10-19 23:17) [14]


> Далековато от 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;



Страницы: 1 вся ветка

Текущий архив: 2007.03.04;
Скачать: CL | DM;

Наверх




Память: 0.52 MB
Время: 0.07 c
15-1170831074
vasIZmax
2007-02-07 09:51
2007.03.04
Не спам!!


15-1171134036
Narik
2007-02-10 22:00
2007.03.04
Помогите… работа с ListBox...


2-1171016494
НиколайКо
2007-02-09 13:21
2007.03.04
Как получить клик мышкой


2-1170831337
Ламерок
2007-02-07 09:55
2007.03.04
Почему не вставляется русскоязычный текст в таблицу базы данных?


2-1171621980
Tolibas
2007-02-16 13:33
2007.03.04
fsMDIForm - > fsMDIChild -> fsNormal