1 bit czarno-biały czy 8 bit skala szarości? Zresztą tak czy tak chyba i tak nie ma innego sposobu niż pojechanie pętlą z ScanLine po całym obrazku i sprawdzenie kolorów każdego piksela dla czarno białych wszystkie składowe RGB muszą mieć wartości 0 lub 255 a dla skali szarości wszystkie składowe muszą mieć tą samą wartość R = G AND G = B naturalnie pętlę przerywamy gdy natrafiamy na pierwszy niespełniający warunków piksel.
Dziękuję za odpowiedź.. przepraszam, że z takim opóźnieniem reaguje, ale byłem "utopiony" w innym problemie :)
Finalnie do samego wykrycia jakiego rodzaju jest poszczególna bitmapa użyłem metod zaszytych w komponencie Twain,
procedure TTwainSource.ReadNative(Handle: TW_UINT32; var Cancel: Boolean; Paleta: integer);
var
DibInfo: ^TBITMAPINFO;
ColorTableSize: Integer;
lpBits: PAnsiChar;
DC: HDC;
BitmapHandle: HBitmap;
begin
DibInfo := GlobalLock(Handle);
ColorTableSize := (DibNumColors(DibInfo) * SizeOf(RGBQUAD));
Paleta := PBitmapInfoHeader(DibInfo).biBitCount;
lpBits := PAnsiChar(DibInfo);//ccc
Inc(lpBits, DibInfo.bmiHeader.biSize);
Inc(lpBits, ColorTableSize);
DC := GetDC(Owner.VirtualWindow);
BitmapHandle := CreateDIBitmap(DC, DibInfo.bmiHeader, CBM_INIT,
lpBits, DibInfo^, DIB_RGB_COLORS);
ReleaseDC(Owner.VirtualWindow, DC);
Owner.DoTwainAcquire(Owner, Index, BitmapHandle, Cancel, Paleta);
GlobalUnlock(Handle);
GlobalFree(Handle);
end;
Pojawił się natomiast inny kłopot z którym sobie nie mogę poradzić.. mianowicie zmiana formatu Bitmapy w momencie jej zapisywania do ImageList z pfDevice na odpowiadający każdej bitmapie powoduje wzrost użycia pamięci, aż do pojawienia się komunikatu o braku miejsca w magazynie.
Stąd moja prośba.. jeśli ktoś z Was będzie w stanie wyjaśnić mi pewne zachowanie będę wdzięczny.
Mam prostą procedurę:
procedure TScanForm.ScanTwainAcquire(Sender: TObject; const Index: Integer;
Image: TBitmap; var Cancel: Boolean; Paleta: integer);
begin
ImageList.Add(TBitmap.Create);
TBitmap(ImageList[ImageList.Count - 1]).Assign(Image);
if ImageList.Count > 0 then
begin
if ImageList.Count = 1 then SelectFirst
else
if cbxShowLast.Checked then SelectLast
else SelectFirst;
end;
GoForward.Enabled := ImageList.Count - 1 > CurrentImage;
inc(LiczbaSkanow);
Current.Caption := Inttostr(CurrentImage + 1)+'/'+ IntToStr(LiczbaSkanow);
Current.Repaint;
end;
za jej pomocą zapisuje do ImageList (TList) około setki obrazów ze skanera... zadziwiające jest to, że użycie pamięci nawet przy 200 obrazach kolorowych w 200dpi zajmuje w pamięci ok 20-30MB.. nie wiem jakich cudów dokonuje kompilator, ale optymalizacja działania pod tym kątem poraża...
potem mogę za pomocą kolejnej prostej procedury wyświetlać sobie zeskanowane obrazy w TImage:
procedure TScanForm.GoForwardClick(Sender: TObject);
begin
if ImageList.Count > 0 then
begin
inc(CurrentImage);
Image.Picture.Assign(TBitmap(ImageList[CurrentImage]));
end;
end;
szybkie poruszanie się po liście i wyświetlanie obrazów także nie powoduje zwiększenia użycia RAM...
Problem pozostaje jednak, że wszystkie bitmapy mają PixelFormat = pfDevice. W zmiennej Paleta: integer przekazuję sobie głębie w bitach więc dla każdej Bitmapy moge zrobić coś takiego:
case Paleta of
2: TBitmap(ImageList[ImageList.Count - 1]).PixelFormat := pf1bit;
16: TBitmap(ImageList[ImageList.Count - 1]).PixelFormat := pf4bit;
256: TBitmap(ImageList[ImageList.Count - 1]).PixelFormat := pf8bit;
else TBitmap(ImageList[ImageList.Count - 1]).PixelFormat := pf24bit;
end ;
tylko niestety, każda taka operacja powoduje, że użycie pamięci także wzrasta do granicznej wartości...
Jak to jest, że zapisanie do pamięci tak dużej ilości bitmap (rekordowo zmieściłem prawie 700 skanów kolorowych w 200dpi) bez zmiany property PixelFormat, przeglądanie ich, obracanie itd powoduje, że użycie RAM jest znikome.. a wystarczy tylko zmienić PixelFormat (bez względu na jaką wartość) zabija RAM??
próbowałem wywoływać metody Dormant, FreeImage po każdej zmianie, ale nic to nie pomaga...
Będę wdzięczny za wszelkie wskazówki..
pozdrawiam