How to get dimensions of image file in Delphi?

前端 未结 6 1826
南旧
南旧 2021-01-05 00:35

I want to know width and height of an image file before opening that file.

So, how to do that?

EDIT: This refers to jpg, bmp, png and gif types of image fil

6条回答
  •  粉色の甜心
    2021-01-05 01:21

    I don't like Rafael's solution for JPGs too much because his algorithm parses every single byte until it hits FFC0. It doesn't make use of the fact that almost all markers (except FFD8,FFD9 and FFFE) are followed by two length bytes, allowing to skip from marker to marker. So I suggest the following procedure (which I condensed even a little more by stuffing checking for a marker and retrieving a value into the same function):

    procedure GetJPGSize(const Filename: string; var ImgWidth, ImgHeight: word);
    const
      SigJPG : TBytes = [$FF, $D8];
      SigC01 : TBytes = [$FF, $C0];
      SigC02 : TBytes = [$FF, $C1];
    var
      FStream: TFileStream;
      Buf: array[0..1] of Byte;
      Offset,CheckMarker : Word;
    //--------------------------------------------------------------------------------------------------------------------------------------------------------------
      function  SameValue(Sig:TBytes):Boolean;
      begin
         Result := CompareMem(@Sig[0], @Buf[0], Length(Sig));
      end;
    //--------------------------------------------------------------------------------------------------------------------------------------------------------------
      function  CheckMarkerOrVal(var Value:Word):Boolean;
      begin
        FStream.ReadData(Buf, Length(Buf));
        Value := Swap(PWord(@Buf[0])^);
        Result := (Buf[0] = $FF);
      end;
    //--------------------------------------------------------------------------------------------------------------------------------------------------------------
    begin
      FStream := TFileStream.Create(Filename, fmOpenRead);
      Try
        // First two bytes in a JPG file MUST be $FFD8, followed by the next marker
        If not (CheckMarkerOrVal(CheckMarker) and SameValue(SigJPG))
          then exit;
        Repeat
          If not CheckMarkerOrVal(CheckMarker)
            then exit;
          If SameValue(SigC01) or SameValue(SigC02) then begin
            FStream.Position := FStream.Position + 3;
            CheckMarkerOrVal(ImgHeight);
            CheckMarkerOrVal(ImgWidth);
            exit;
          end;
          CheckMarkerOrVal(Offset);
          FStream.Position := FStream.Position + Offset - 2;
        until FStream.Position > FStream.Size div 2;
      Finally
        FStream.Free;
      end;
    end;
    

提交回复
热议问题