Delphi :JPG到位图:不相容的类型:'TPersistent'和'TFileName'

vqlkdk9b  于 2022-12-12  发布在  其他
关注(0)|答案(1)|浏览(146)

我正在写一个程序:
1.-要求用户选择一个文件,任何类型的图像(JPG、PNG等)
2.-让我们的用户像素化的图像,并显示新的像素化的图像。
由于我的测试图像是JPG,我得到错误:Incompatible types: 'TPersistent' and 'TFileName'

在尝试将JPG转换为位图之前,我得到了:
Bitmap image is not valid

代码:

unit demo_2;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ExtCtrls, Vcl.Imaging.Jpeg;

var
  OpenDialog: TOpenDialog;
  OpenFolder: TFileOpenDialog;
  OriginalImage: TBitmap;
  PixellatedImage: TBitmap;

type
  TForm1 = class(TForm)
    btn1_select_img: TButton;
    btn2_select_output_path: TButton;
    lbl_selected_file: TLabel;
    lbl_output_path: TLabel;
    img1: TImage;
    pnl_img: TPanel;
    pnl_btns: TPanel;
    procedure btn1_select_imgClick(Sender: TObject);
    procedure btn2_select_output_pathClick(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.btn1_select_imgClick(Sender: TObject);
begin
  OpenDialog := TOpenDialog.Create(nil);
  OpenDialog.Filter := 'All Files|*.*';
  OpenDialog.Options := [ofPathMustExist, ofFileMustExist];
  try
    if OpenDialog.Execute then
    begin
      // Print the selected file's path to the console
      //WriteLn(OpenDialog.FileName);
      lbl_selected_file.Caption := OpenDialog.FileName;
      img1.Picture.LoadFromFile(OpenDialog.FileName);
    end;
  finally
    //OpenDialog.Free;
  end;
end;

procedure TForm1.btn2_select_output_pathClick(Sender: TObject);
begin
  //OpenFolder := TFileOpenDialog.Create(nil);  for folder selection
  //OpenFolder.Options := [fdoPickFolders];  for folder selection
  try
    //if OpenFolder.Execute then
    begin
      PixellatedImage := TBitmap.Create;
      //PixellatedImage.LoadFromFile(OpenDialog.FileName);
      PixellatedImage.Assign(OpenDialog.FileName);

      // Pixellate the image by setting the Width and Height to a small value
      PixellatedImage.Width := 10;
      PixellatedImage.Height := 10;

      img1.Picture.Bitmap := PixellatedImage;

      //lbl_output_path.Caption := OpenFolder.FileName;   for folder selection
    end;
  finally
    //OpenFolder.Free;
    //OpenDialog.Free;
    PixellatedImage.Free;
  end;

end;

end.
8gsdolmq

8gsdolmq1#

由于我的测试图像是JPG,我得到错误:不相容的类型:'TPersistent'和'TFileName'
实际上,这是错误的,因为错误与图像是JPG无关。因此,虽然“我的测试图像是JPG”和“我得到了错误...”都是正确的,但含义(“因为”)是错误的。
中使用的TPersistent.Assign方法

PixellatedImage.Assign(OpenDialog.FileName);

需要一个TPersistent对象。在这种情况下,当您处理图形时,通常需要一个TGraphic示例。因此,您不能传递字符串,即使该字符串恰好是图像文件的文件名。
因此,如果要在图形对象上使用Assign方法,则需要向其传递另一个图形对象--您可能已经使用其自己的LoadFromFile从文件中加载了该对象:

procedure TForm1.FormCreate(Sender: TObject);
begin

  var JpegImage := TJPEGImage.Create;
  try

    var OpenDlg := TFileOpenDialog.Create(Self);
    try
      with OpenDlg.FileTypes.Add do
      begin
        DisplayName := 'JPEG images';
        FileMask := '*.jpg';
      end;
      if OpenDlg.Execute then
        JpegImage.LoadFromFile(OpenDlg.FileName)
      else
        Exit;
    finally
      OpenDlg.Free;
    end;

    var BmpImage := TBitmap.Create;
    try
      BmpImage.Assign(JpegImage);
      // For example: BmpImage.SaveToFile('K:\bitmap.bmp');
    finally
      BmpImage.Free;
    end;

  finally
    JpegImage.Free;
  end;

end;

另外,请注意你一定要用成语

LFrog := TFrog.Create;
try
  // use LFrog
finally
  LFrog.Free;
end

而且永远不会

try
  LFrog := TFrog.Create;
  // use LFrog
finally                   // WRONG!
  LFrog.Free;
end

假设LFrog是一个局部变量。如果LFrog不是一个局部变量,那么它可能应该是一个局部变量!否则,对它执行FreeAndNil而不仅仅是Free非常重要。
更新。Q被改变了,所以它不再是关于JPG -〉BMP,而是“任何”图像文件到BMP。那么也许最好的方法是使用Windows图像组件:

procedure TForm1.FormCreate(Sender: TObject);
begin

  var WicImage := TWICImage.Create;
  try

    var OpenDlg := TFileOpenDialog.Create(Self);
    try
      with OpenDlg.FileTypes.Add do
      begin
        DisplayName := 'All image files';
        FileMask := '*.jpg;*.tiff;*.tif;*.png;*.gif;*.bmp';
      end;
      with OpenDlg.FileTypes.Add do
      begin
        DisplayName := 'JPEG images';
        FileMask := '*.jpg';
      end;
      with OpenDlg.FileTypes.Add do
      begin
        DisplayName := 'TIFF images';
        FileMask := '*.tiff;*.tif';
      end;
      with OpenDlg.FileTypes.Add do
      begin
        DisplayName := 'PNG images';
        FileMask := '*.png';
      end;
      with OpenDlg.FileTypes.Add do
      begin
        DisplayName := 'GIF images';
        FileMask := '*.gif';
      end;
      with OpenDlg.FileTypes.Add do
      begin
        DisplayName := 'Bitmap images';
        FileMask := '*.bmp';
      end;
      // etc.
      if OpenDlg.Execute then
        WicImage.LoadFromFile(OpenDlg.FileName);
    finally
      OpenDlg.Free;
    end;

    var BmpImage := TBitmap.Create;
    try
      BmpImage.Assign(WicImage);
      // For example: BmpImage.SaveToFile('K:\bitmap.bmp');
    finally
      BmpImage.Free;
    end;

  finally
    WicImage.Free;
  end;

end;

最后,我注意到你写

// Pixellate the image by setting the Width and Height to a small value
PixellatedImage.Width := 10;
PixellatedImage.Height := 10;

虽然与您的主要问题TGraphic.Assign无关,但我应该注意到,设置TBitmapWidthHeight太多,并不能像通常意义上的那样对图像进行像素化(从算法上讲,像素化应该像Pixelate过程中那样完成)。

相关问题