德尔福图像维度

时间:2013-05-11 00:08:03

标签: image delphi

我创建了一个简单的Opendialog,带有显示消息的Edit1

我不知道为什么我的函数会返回:

[DCC Error] Unit1.pas(112): E2010 Incompatible types: 'string' and 'tagSIZE'

完整的代码是:

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls,Types, ExtDlgs;

type
  TForm1 = class(TForm)
    Edit1: TEdit;
    Button1: TButton;
    Label1: TLabel;
    Memo1: TMemo;
    OpenDialog1: TOpenDialog;
    procedure Button1Click(Sender: TObject);

  private
    { Private declarations }
  public
//      procedure GetGIFSize(const sGIFFile: string; var wWidth, wHeight: Word);

  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}
function GetGIFSize(const FileName: string): Windows.TSize;
type
  // GIF header record
  TGIFHeader = packed record
    Sig: array[0..5] of AnsiChar;     // signature bytes
    ScreenWidth, ScreenHeight: Word;  // logical screen width and height
    Flags: Byte;                      // various flags
    Background: Byte;                 // background colour index
    Aspect: Byte;                     // pixel aspect ratio
  end;
  // GIF image block header record
  TGIFImageBlock = packed record
    Left, Top: Word;      // image top left
    Width, Height: Word;  // image dimensions
    Flags: Byte;          // flags and local colour table size
  end;
const
  cSignature: PAnsiChar = 'GIF';  // gif image signature
  cImageSep = $2C;                // image separator byte
var
  FS: Classes.TFileStream;      // stream onto gif file
  Header: TGIFHeader;           // gif header record
  ImageBlock: TGIFImageBlock;   // gif image block record
  BytesRead: Integer;           // bytes read in a block read
  Offset: Integer;              // file offset to seek to
  B: Byte;                      // a byte read from gif file
  DimensionsFound: Boolean;     // flag true if gif dimensions have been read
begin
  Result.cx := 0;
  Result.cy := 0;
  if (FileName = '') or not SysUtils.FileExists(FileName) then
    Exit;
  FS := Classes.TFileStream.Create(
    FileName, SysUtils.fmOpenRead or SysUtils.fmShareDenyNone
  );
  try
    // Check signature
    BytesRead := FS.Read(Header, SizeOf(Header));
    if (BytesRead <> SizeOf(TGIFHeader)) or
      (SysUtils.StrLComp(cSignature, Header.Sig, 3) <> 0) then
      // Invalid file format
      Exit;
    // Skip colour map, if there is one
    if (Header.Flags and $80) > 0 then
    begin
      Offset := 3 * (1 shl ((Header.Flags and 7) + 1));
      if Offset >= FS.Size then
        Exit;
      FS.Seek(Offset, Classes.soFromBeginning);
    end;
    DimensionsFound := False;
    FillChar(ImageBlock, SizeOf(TGIFImageBlock), #0);
    // Step through blocks
    FS.Read(B, SizeOf(B));
    while (FS.Position < FS.Size) and (not DimensionsFound) do
    begin
      if B = cImageSep then
      begin
        // We have an image block: read dimensions from it
        BytesRead := FS.Read(ImageBlock, SizeOf(ImageBlock));
        if BytesRead <> SizeOf(TGIFImageBlock) then
          // Invalid image block encountered
          Exit;
        Result.cx := ImageBlock.Width;
        Result.cy := ImageBlock.Height;
        DimensionsFound := True;
      end;
      FS.Read(B, SizeOf(B));
    end;
  finally
    FS.Free;
  end;
end;


procedure TForm1.Button1Click(Sender: TObject);
var
  Size: Windows.TSize;
begin
    Size := GetGIFSize('file.gif');
    ShowMessage(Size);
  end;
end.

我简单地使用:

GetGIFSize(路径/到/文件名);

但是Filename是一个字符串,你知道为什么不工作吗?

2 个答案:

答案 0 :(得分:3)

问题发生在TForm1.ButtonClick事件中,ShowMessage来电。 ShowMessage采用字符串参数(要显示的消息),而您将Windows.TSize传递给它。

您需要将TSize记录转换为字符串才能将其与ShowMessage一起使用。 TSize有两个维度 - 宽度(由TSize.cx表示)和高度(由TSize.cy表示),因此您需要将这些维度转换为可显示的字符串表示形式:

procedure TForm1.Button1Click(Sender: TObject);
var
  Size: Windows.TSize;
const
  SizeDisplayMsg = 'Size - width (cx): %d height (cy): %d';
begin
    Size := GetGIFSize('file.gif');
    ShowMessage(Format(SizeDisplayMsg, [Size.cx, Size.cy]));
end;

当然,如果您想要使用TOpenFileDialog来获取文件名,则应该使用它:

procedure TForm1.Button1Click(Sender: TObject);
var
  Size: Windows.TSize;
const
  SizeDisplayMsg = 'Size - width (cx): %d height (cy): %d';
begin
  if OpenDialog1.Execute(Handle) then
  begin
    Size := GetGIFSize(OpenDialog1.FileName);
    ShowMessage(Format(SizeDisplayMsg, [Size.cx, Size.cy]));
  end;
end;

答案 1 :(得分:2)

ShowMessage过程将其作为唯一参数string类型值,但您尝试传递Windows.TSize条记录。这就是为什么编译器拒绝使用此类消息进行编译的原因。此外,Windows.TSize记录类型包含2个字段;来自cxcy,其中每个都是数字类型,所以除了你需要单独传递 之外,你需要在传递之前将它们的值转换为字符串他们进入ShowMessage程序。你可以通过多种方式做到这一点,例如:由:

1。使用格式化功能(首选方式)

procedure TForm1.Button1Click(Sender: TObject);
var
  Size: Windows.TSize;
begin
  Size := GetGIFSize('c:\File.gif');
  ShowMessage(Format('Width: %d; Height: %d', [Size.cx, Size.cy]));
end;

2。字符串的手动连接(可读性更差)

procedure TForm1.Button1Click(Sender: TObject);
var
  Size: Windows.TSize;
begin
  Size := GetGIFSize('c:\File.gif');
  ShowMessage('Width: ' + IntToStr(Size.cx) + '; Height: ' + IntToStr(Size.cy));
end;