JPEG/GIF/BMP/PNG/PCX등의 이미지를 이미지 컴포넌트를 사용하지 않고 간단히 이미지 정보를 얻을 수 있음
다음과같은 정보를 얻을 수 있습니다
- 이미지 크기(width, heigjht)
- 이미지 컬러수(Depth, 8, 24 ..)
- 이미지 유형(BMP, JPEG, GIF...)
- 파일크기
다음 유닛을 Uses 절에 추가후 사용
사용 예)
다음과같은 정보를 얻을 수 있습니다
- 이미지 크기(width, heigjht)
- 이미지 컬러수(Depth, 8, 24 ..)
- 이미지 유형(BMP, JPEG, GIF...)
- 파일크기
다음 유닛을 Uses 절에 추가후 사용
사용 예)
ImageInfo := TDCImageInfo.Create; ImageInfo.ReadFile(AFileName); if ImageInfo.Depth=8 then begin ... end; ImageInfo.free;. Unit : DCImageInfo.pas
{******************************************************************************* TDCImageInfo ?2001 David Crowell www.davidcrowell.com Description: TDCImageInfo returns image type, dimensions, and color depth from GIF, JPEG, PNG, BMP, PCX, and TIFF files. This is a port of my CImageInfo class which was created with Visual Basic. Usage: var ImageInfo: TDCImageInfo; Begin ImageInfo := TDCImageInfo.Create; ImageInfo.ReadFile('test.jpg'); Writeln(ImageInfo.Width); // etc... ImageInfo.Free; *******************************************************************************} unit DCImageInfo; interface uses SysUtils, Classes; const TIFF_WIDTH = 256; TIFF_HEIGHT = 257; TIFF_BITSPERSAMPLE = 258; TIFF_BYTE = 1; TIFF_WORD = 3; TIFF_DWORD = 4; {******************************************************************************* image type enumeration *******************************************************************************} type TImageType = (itUnknown, itGIF, itJPEG, itPNG, itBMP, itPCX, itTIFF); {******************************************************************************* class declaration *******************************************************************************} type TDCImageInfo = Class(TObject) private ImageFile: TFileStream; FWidth: integer; FHeight: integer; FDepth: integer; FImageType: TImageType; FFileSize: integer; procedure ReadPNG; procedure ReadGIF; procedure ReadBMP; procedure ReadPCX; procedure ReadLETIFF; procedure ReadBETIFF; procedure ReadJPEG; procedure ResetValues; function Swap32(Value: Integer): Integer; public property Width: integer read FWidth; property Height: integer read FHeight; property Depth: integer read FDepth; property ImageType: TImageType read FImageType; property FileSize: integer read FFileSize; procedure ReadFile(const FileName: String); end; implementation {******************************************************************************* ReadFile *******************************************************************************} procedure TDCImageInfo.ReadFile(const FileName: String); var Buffer: array[0..2] of Byte; begin // Clear any left over data... ResetValues; // Open the file Try ImageFile := TFileStream.Create(FileName, fmOpenRead); Except; Exit; End; FFileSize := ImageFile.Size; // read the first 3 bytes to determine file type Try ImageFile.ReadBuffer(Buffer, 3); Except; ImageFile.Free; Exit; End; // check for PNG if (Buffer[0] = 137) and (Buffer[1] = 80) and (Buffer[2] = 78) Then begin Try ReadPNG; Except ResetValues; End; end; // check for GIF if (Buffer[0] = 71) and (Buffer[1] = 73) and (Buffer[2] = 70) Then begin Try ReadGIF; Except ResetValues; End; end; // check for BMP if (Buffer[0] = 66) and (Buffer[1] = 77) Then begin Try ReadBMP; Except ResetValues; End; end; // check for PCX if (Buffer[0] = 10) Then begin Try ReadPCX; Except ResetValues; End; end; // check for TIFF (little endian) if (Buffer[0] = 73) and (Buffer[1] = 73) and (Buffer[2] = 42) Then begin Try ReadLETIFF; Except ResetValues; End; end; // check for TIFF (big endian) if (Buffer[0] = 77) and (Buffer[1] = 77) and (Buffer[2] = 42) Then begin Try ReadBETIFF; Except ResetValues; End; end; // if we haven't found the correct type by now, it's either invalid or // a JPEG if FImageType = itUnknown Then begin Try ReadJPEG; Except ResetValues; End; end; // clean up ImageFile.Free; end; {******************************************************************************* ReadPNG *******************************************************************************} procedure TDCImageInfo.ReadPNG; var b: Byte; c: Byte; w: Word; begin FImageType := itPNG; ImageFile.Position := 24; ImageFile.ReadBuffer(b, 1); ImageFile.ReadBuffer(c, 1); // color depth Case c Of 0: FDepth := b; // greyscale 2: FDepth := b * 3; // RGB 3: FDepth := 8; // Palette based 4: FDepth := b * 2; // greyscale with alpha 6: FDepth := b * 4; // RGB with alpha Else FImageType := itUnknown; End; If FImageType = itPNG Then begin ImageFile.Position := 18; ImageFile.ReadBuffer(w, 2); FWidth := Swap(w); ImageFile.Position := 22; ImageFile.ReadBuffer(w, 2); FHeight := Swap(w); end; end; {******************************************************************************* ReadGIF *******************************************************************************} procedure TDCImageInfo.ReadGIF; var b: Byte; w: Word; begin FImageType := itGIF; ImageFile.Position := 6; ImageFile.ReadBuffer(w, 2); FWidth := w; ImageFile.ReadBuffer(w, 2); FHeight := w; ImageFile.ReadBuffer(b, 1); FDepth := (b and 7) + 1; end; {******************************************************************************* ReadBMP *******************************************************************************} procedure TDCImageInfo.ReadBMP; var b: Byte; w: Word; begin FImageType := itBMP; ImageFile.Position := 18; ImageFile.ReadBuffer(w, 2); FWidth := w; ImageFile.Position := 22; ImageFile.ReadBuffer(w, 2); FHeight := w; ImageFile.Position := 28; ImageFile.ReadBuffer(b, 1); FDepth := b; end; {******************************************************************************* ReadPCX *******************************************************************************} procedure TDCImageInfo.ReadPCX; var b1: Byte; b2: Byte; X1: Word; X2: Word; Y1: Word; Y2: Word; begin FImageType := itPCX; ImageFile.Position := 3; ImageFile.ReadBuffer(b1, 1); ImageFile.ReadBuffer(X1, 2); ImageFile.ReadBuffer(Y1, 2); ImageFile.ReadBuffer(X2, 2); ImageFile.ReadBuffer(Y2, 2); ImageFile.Position := 65; ImageFile.ReadBuffer(b2, 1); FWidth := (X2 - X1) + 1; FHeight := (Y2 - Y1) + 1; FDepth := b1 * b2; end; {******************************************************************************* ReadLETIFF (little endian TIFF) *******************************************************************************} procedure TDCImageInfo.ReadLETIFF; var pIFD: Integer; pEntry: Integer; NumEntries: Word; i: Integer; b: Byte; w: Word; w2: Word; w3: Word; dw: Integer; begin FImageType := itTIFF; // get pointer to IFD ImageFile.Position := 4; ImageFile.ReadBuffer(pIFD, 4); // get number of entries in the IFD ImageFile.Position := pIFD; ImageFile.ReadBuffer(NumEntries, 2); // loop through each entry For i := 0 to NumEntries - 1 do begin pEntry := pIFD + 2 + (12 * i); ImageFile.Position := pEntry; ImageFile.ReadBuffer(w, 2); // width if w = TIFF_WIDTH then begin ImageFile.ReadBuffer(w2, 2); ImageFile.Position := pEntry + 8; Case w2 of TIFF_BYTE: begin ImageFile.ReadBuffer(b, 1); FWidth := b; end; TIFF_WORD: begin ImageFile.ReadBuffer(w3, 2); FWidth := w3; end; TIFF_DWORD: begin ImageFile.ReadBuffer(dw, 4); FWidth := dw; end; Else FWidth := 0; end; end; // end of TIFF_WIDTH // Height if w = TIFF_HEIGHT then begin ImageFile.ReadBuffer(w2, 2); ImageFile.Position := pEntry + 8; Case w2 of TIFF_BYTE: begin ImageFile.ReadBuffer(b, 1); FHeight := b; end; TIFF_WORD: begin ImageFile.ReadBuffer(w3, 2); FHeight := w3; end; TIFF_DWORD: begin ImageFile.ReadBuffer(dw, 4); FHeight := dw; end; Else FHeight := 0; end; end; // end of TIFF_HEIGHT // Depth if w = TIFF_BITSPERSAMPLE then begin ImageFile.ReadBuffer(w2, 2); ImageFile.Position := pEntry + 8; Case w2 of TIFF_BYTE: begin ImageFile.ReadBuffer(b, 1); FDepth := b; end; TIFF_WORD: begin ImageFile.ReadBuffer(w3, 2); FDepth := w3; end; TIFF_DWORD: begin ImageFile.ReadBuffer(dw, 4); FDepth := dw; end; Else FDepth := 0; end; end; // end of TIFF_BITSPERSAMPLE end; // end of loop if not((FWidth > 0) and (FHeight > 0) and (FDepth > 0)) then ResetValues; end; // end of procedure {******************************************************************************* ReadBETIFF (big endian TIFF) *******************************************************************************} procedure TDCImageInfo.ReadBETIFF; var pIFD: Integer; pEntry: Integer; NumEntries: Word; i: Integer; b: Byte; w: Word; w2: Word; w3: Word; dw: Integer; begin FImageType := itTIFF; // get pointer to IFD ImageFile.Position := 4; ImageFile.ReadBuffer(pIFD, 4); pIFD := Swap32(pIFD); // get number of entries in the IFD ImageFile.Position := pIFD; ImageFile.ReadBuffer(NumEntries, 2); NumEntries := Swap(NumEntries); // loop through each entry For i := 0 to NumEntries - 1 do begin pEntry := pIFD + 2 + (12 * i); ImageFile.Position := pEntry; ImageFile.ReadBuffer(w, 2); w := Swap(w); // width if w = TIFF_WIDTH then begin ImageFile.ReadBuffer(w2, 2); w2 := Swap(w2); ImageFile.Position := pEntry + 8; Case w2 of TIFF_BYTE: begin ImageFile.ReadBuffer(b, 1); FWidth := b; end; TIFF_WORD: begin ImageFile.ReadBuffer(w3, 2); FWidth := Swap(w3); end; TIFF_DWORD: begin ImageFile.ReadBuffer(dw, 4); FWidth := Swap32(dw); end; Else FWidth := 0; end; end; // end of TIFF_WIDTH // Height if w = TIFF_HEIGHT then begin ImageFile.ReadBuffer(w2, 2); w2 := Swap(w2); ImageFile.Position := pEntry + 8; Case w2 of TIFF_BYTE: begin ImageFile.ReadBuffer(b, 1); FHeight := b; end; TIFF_WORD: begin ImageFile.ReadBuffer(w3, 2); FHeight := Swap(w3); end; TIFF_DWORD: begin ImageFile.ReadBuffer(dw, 4); FHeight := Swap32(dw); end; Else FHeight := 0; end; end; // end of TIFF_HEIGHT // Depth if w = TIFF_BITSPERSAMPLE then begin ImageFile.ReadBuffer(w2, 2); w2 := Swap(w2); ImageFile.Position := pEntry + 8; Case w2 of TIFF_BYTE: begin ImageFile.ReadBuffer(b, 1); FDepth := b; end; TIFF_WORD: begin ImageFile.ReadBuffer(w3, 2); FDepth := Swap(w3); end; TIFF_DWORD: begin ImageFile.ReadBuffer(dw, 4); FDepth := Swap32(dw); end; Else FDepth := 0; end; end; // end of TIFF_BITSPERSAMPLE end; // end of loop if not((FWidth > 0) and (FHeight > 0) and (FDepth > 0)) then ResetValues; end; // end of procedure {******************************************************************************* ReadJPEG *******************************************************************************} procedure TDCImageInfo.ReadJPEG; var Pos: Integer; w: Word; b: Byte; Buffer: array[0..2] of Byte; begin Pos :=0; // find beginning of JPEG stream While True do begin ImageFile.Position := Pos; ImageFile.ReadBuffer(Buffer, 3); if (Buffer[0] = $FF) and (Buffer[1] = $D8) and (Buffer[2] = $FF) then break; Pos := Pos + 1; end; Pos := Pos +1; // loop through each marker until we find the C0 marker (or C1 or C2) which // has the image information While True do begin // find beginning of next marker While True do begin ImageFile.Position := Pos; ImageFile.ReadBuffer(Buffer, 2); if (Buffer[0] = $FF) and (Buffer[1] <> $FF) then break; Pos := Pos + 1; end; // exit the loop if we've found the correct marker b := Buffer[1]; if (b = $C0) or (b = $C1) or (b = $c2) or (b = $C3) then break; // otherwise find position of next marker ImageFile.Position := Pos + 2; ImageFile.ReadBuffer(w, 2); Pos := Pos + Swap(w); //writeln(pos); end; // if we haven't errored by this point then we're at the right // marker, and can retrieve the info FImageType := itJPEG; ImageFile.Position := Pos + 5; ImageFile.ReadBuffer(w, 2); FHeight := Swap(w); //ImageFile.Position := Pos + 6; ImageFile.ReadBuffer(w, 2); FWidth := Swap(w); //ImageFile.Position := Pos + 8; ImageFile.ReadBuffer(b, 1); FDepth := b * 8; end; {******************************************************************************* ResetValues *******************************************************************************} procedure TDCImageInfo.ResetValues; begin FImageType := itUnknown; FWidth := 0; FHeight := 0; FDepth := 0; end; {******************************************************************************* Swap32 *******************************************************************************} function TDCImageInfo.Swap32(Value: Integer): Integer; var b1: Integer; b2: Integer; b3: Integer; b4: Integer; r: Integer; begin b1 := Value and 255; b2 := (Value shr 8) and 255; b3 := (Value shr 16) and 255; b4 := (Value shr 24) and 255; b1 := b1 shl 24; b2 := b2 shl 16; b3 := b3 shl 8; r := b1 or b2 or b3 or b4; result := r; end; end.
'프로그래밍 > Delphi' 카테고리의 다른 글
Graphics32에서 TBitmap32를 Thread 내에서 사용했을때의 문제점 추정 (0) | 2011.07.24 |
---|---|
GDI객체 및 기본 윈도우 메모리 힙 할당문제 (1) | 2011.07.23 |
이미지 파일명을 가지고 이미지 사이즈(폭/높이) 알아내기 (0) | 2011.07.19 |
Twitter for Delphi(델파이를 이용한 트위터 클라이언트 제작) (3) | 2011.07.13 |
TPrinter를 이용한 이미지 인쇄 (3) | 2011.03.16 |