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

Вниз

GetDIBBits - нот а гуд!!!   Найти похожие ветки 

 
WondeRu ©   (2004-04-29 10:13) [0]

Здравствуйте!

При вызове GetDIBBits, если изображение больше 64 кб (не точно), происходит отшибка и массив битов, не инициализируется!

Как решить данную проблему? Если ли альтернатива данной функции для больших картинок?

Спасибо!


 
MBo ©   (2004-04-29 11:03) [1]

Код?


 
WondeRu ©   (2004-04-29 11:27) [2]

Сам напросился)))


function TAPlan.PrepareImage(BitMapTemp: TBitmap): Boolean;
 function FindNearest(Value: Integer): Integer;
 var
   i : Integer;
   x1, x2, x3 : Integer;
 begin
   Result := 1024;
   for i := 2 to 11 do
     begin
       x1 := Round(Power(2,i - 1)) - Value;
       x2 := Round(Power(2,i    )) - Value;
       x3 := Round(Power(2,i + 1)) - Value;
       if (x1 <= 0) and (x3 >= 0) and (x2>=0)
         then
           begin
             Result := Round(Power(2, i));
             Break;
           end;
     end;
 end;

var
 Data         : array of Byte;
 P            : Pointer;
 Bitmap       : TBitmap;
 LittleBMP    : TBitmap;
 i, tmpCount  : Integer;
 BMInfo       : TBitmapInfo;
 MemDC        : HDC;
 Size         : DWORD;
 tmp, j       : Integer;
 tmpColor     : TColor;
begin
 Result := True;
 try
   Bitmap := TBitmap.Create;
   Bitmap.PixelFormat := pf32bit;

   Bitmap.Width  := FindNearest(BitmapTemp.Width);
   Bitmap.Height := FindNearest(BitmapTemp.Height);
   GetLastError;
   SetStretchBltMode(dc,HALFTONE);
 
   if not StretchBlt(Bitmap.Canvas.Handle,     // handle to destination DC
                     0,                        // x-coord of destination upper-left corner
                     0,                        // y-coord of destination upper-left corner
                     Bitmap.Width,             // width of destination rectangle
                     Bitmap.Height,            // height of destination rectangle
                     BitmapTemp.Canvas.Handle, // handle to source DC
                     0,                        // x-coord of source upper-left corner
                     0,                        // x-coord of source upper-left corner
                     BitmapTemp.Width,         // width of source rectangle
                     BitmapTemp.Height,        // height of source rectangle
                     SRCCOPY)                  // raster operation code
     then  ShowError(True,"StretchBlt");

   BitMapTemp.Canvas.Pixels[0,0];

   fxmin := 0;
   fxmax := BitmapTemp.Width;
   fymin := 0;
   fymax := BitmapTemp.Height;

   MemDC := CreateCompatibleDC(0);
   GetLastError;

   try
     try
       SetLength(Data, Bitmap.Width * Bitmap.Height * 3);
       GetLastError;
     except
       on e: Exception do
         begin
           OutputDebugString(PChar("TAPlan.PrepareImage1 in uPlanClass with message: " + e.Message));
           GrEvents.OnError("Ошибка выделения памяти для текстуры");
           Exit;
         end;
     end;

     tmpCount := Bitmap.Height div 16;
     for i := 0 to tmpCount - 1 do
       begin
         LittleBMP := TBitmap.Create;
         try
           LittleBMP.Width  := Bitmap.Width;
           LittleBMP.Height := 16;

           BitBlt(LittleBMP.Canvas.Handle,        // handle to destination DC
                  0,                              // x-coord of destination upper-left corner
                  0,                              // y-coord of destination upper-left corner
                  LittleBMP.Width,                // width of destination rectangle
                  LittleBMP.Height,               // height of destination rectangle
                  Bitmap.Canvas.Handle,           // handle to source DC
                  0,                              // x-coordinate of source upper-left corner
                  LittleBMP.Height * i,           // y-coordinate of source upper-left corner
                  SRCCOPY);                       // raster operation code

           FillChar (BMInfo, SizeOf(BMInfo), 0);
           with BMinfo.bmiHeader do
             begin
               biSize        := sizeof(TBitmapInfoHeader);
               biBitCount    := 24;
               biWidth       := LittleBMP.Width;
               biHeight      := LittleBMP.Height;
               biPlanes      := 1;
               biCompression := BI_RGB;

               tmp := (Bitmap.Width * Bitmap.Height - LittleBMP.Height * LittleBMP.Width * (i +1)) * 3;

               if  GetDIBits (MemDC,
                              LittleBMP.Handle,
                              0,
                              biHeight,
                              @Data[tmp],
                              BMInfo,
                              DIB_RGB_COLORS) = 0
                 then
                   try
                     //если GetDIBits завершилась ошибкой, то применяем более медленную модель
                     for j := 0 to  LittleBMP.Height * LittleBMP.Width - 1 do
                       begin
                         tmpColor := LittleBMP.Canvas.Pixels[j mod LittleBMP.Height, j div LittleBMP.Height];
                         try
                         Data[tmp + j * 3    ] := GetBValue(tmpColor);
                         Data[tmp + j * 3 + 1] := GetGValue(tmpColor);
                         Data[tmp + j * 3 + 2] := GetRValue(tmpColor);
                         except
                          // asm
                          //   nop
                          // end;
                         end;
                       end;
                   except
                     on e: Exception do
                       OutputDebugString(PChar(IntTostr(tmp + j * 3) + " TAPlan.PrepareImage.GetDIBits in uPlanClass with message: " + e.Message));
                   end;
             end;
         finally
           LittleBMP.Free;
         end;
       end;
       GetLastError;

       DeleteDC (MemDC);

   finally
     SetLength(Data,0);
     Data := nil;
     Bitmap.Free;
   end;
 except
   on e: Exception do
     OutputDebugString(PChar("TAPlan.PrepareImage3 in uPlanClass with message: " + e.Message));
 end;
end;



 
MBo ©   (2004-04-29 12:09) [3]

;) Да уж, удружил

LittleBMP - какого типа - DIB или DDB?
Какой Pixelformat?
Уверен, что в Data хватает места?

Если нет уверенности, что правмльно заполняешь BMinfo.bmiHeader, стоит вызвать GetDiBits сначала с nil вместо буфера - она сама инициализирует BMinfo.


 
MBo ©   (2004-04-29 12:20) [4]

кроме того - GetDIBits (MemDC...
А LittleBMP не выбраны в нем. Видимо, формат совпадает с экранным, однако стоит LittleBMP.Canvas.Handle использовать для надежности


 
WondeRu ©   (2004-04-29 12:21) [5]

2MBo ©   (29.04.04 12:09) [3]

Как ты понял, если просмотрел все, есть большая картинка, я ее разбиваю на куски по 64к и пытаюсь выдрать биты (когда всю картинку берешь 50% что GetDibits не сработает), но все равно иногда происходят ошибки!

LittleBMP DDB (делфовсий TBitmap);

Data хватает;

PixelFormat:
 Bitmap.PixelFormat := pf32bit;


 
MBo ©   (2004-04-29 12:27) [6]

LittleBMP делай DIB явным указанием PixelFormat

У меня не было проблем с Get/SetDiBits для картинок порядка 1280*1024


 
WondeRu ©   (2004-04-29 12:27) [7]

>А LittleBMP не выбраны в нем. Видимо, формат совпадает с экранным, однако стоит LittleBMP.Canvas.Handle использовать для надежности

Это при инициализации MemDC?

Еще не совсем протестировал, но вставив код после  LittleBMP := TBitmap.Create :

LittleBMP.PixelFormat := pf32bit;

ВРОДЕ заработало корректно, возможно!


 
WondeRu ©   (2004-04-29 12:33) [8]

>LittleBMP делай DIB явным указанием PixelFormat

каким образом? КАк в [7]?

Спасибо!


 
MBo ©   (2004-04-29 12:36) [9]

>каким образом? КАк в [7]?
Да. (можно еще HandleType:=bmDib, но тогда PixelFormat будет зависеть от установленного режима экрана, что с точки зрения переносимости нехорошо)



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

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

Наверх




Память: 0.51 MB
Время: 0.065 c
9-1071510959
Yaroslav
2003-12-15 20:55
2004.05.16
С чего начать??? Нужно сделать игрушку.


14-1082639764
Ditrix
2004-04-22 17:16
2004.05.16
Требуется квалифицированный программер


7-1080710574
random
2004-03-31 09:22
2004.05.16
autorun cd-rom


4-1080297332
frost
2004-03-26 13:35
2004.05.16
Стиль окна как в Outlook.


3-1082573072
Vit
2004-04-21 22:44
2004.05.16
подскажите как переменной присвоить номер текущей записи