Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2004.05.16;
Скачать: [xml.tar.bz2];

Вниз

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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.5 MB
Время: 0.033 c
3-1082189318
Koba
2004-04-17 12:08
2004.05.16
База данных


3-1082600463
Марат
2004-04-22 06:21
2004.05.16
Запрос


1-1083363899
Zeon
2004-05-01 02:24
2004.05.16
FindFirst / FindNext


4-1080823908
Midaw
2004-04-01 16:51
2004.05.16
Перевод хэндла процесса в хэндл его окна


7-1081003358
CAHEK
2004-04-03 18:42
2004.05.16
Как из Винды в проге открыть файл???





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский