delphi 用户选择的图像文件未显示在TIimage组件中

2w2cym1i  于 2023-01-05  发布在  其他
关注(0)|答案(2)|浏览(237)

我有一个程序,让用户选择一个图像文件。一旦选择,它应该显示在一个TImage组件。
为什么不显示(即使文件路径显示在标签中)?

procedure TForm1.btn1_select_imgClick(Sender: TObject);
var
  OpenDialog: TOpenDialog;
begin
  OpenDialog := TOpenDialog.Create(nil);
  OpenDialog.Filter := 'All Files|*.*';
  OpenDialog.Options := [ofPathMustExist, ofFileMustExist];
  try
    if OpenDialog.Execute then
    begin
      lbl_selected_file.Caption := OpenDialog.FileName;
      img1.Picture.LoadFromFile(OpenDialog.FileName);
      OriginalImage := TBitmap.Create;
      OriginalImage.Assign(img1.Picture.Bitmap);
    end;
  finally
    OpenDialog.Free;
  end;
end;

预期结果:

完整代码:

unit image_blurrr_unit;

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
  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);
var
  OpenDialog: TOpenDialog;
begin
  OpenDialog := TOpenDialog.Create(nil);
  OpenDialog.Filter := 'All Files|*.*';
  OpenDialog.Options := [ofPathMustExist, ofFileMustExist];
  try
    if OpenDialog.Execute then
    begin
      lbl_selected_file.Caption := OpenDialog.FileName;
      img1.Picture.LoadFromFile(OpenDialog.FileName);
      OriginalImage := TBitmap.Create;
      OriginalImage.Assign(img1.Picture.Bitmap);
    end;
  finally
    OpenDialog.Free;
  end;
end;

procedure TForm1.btn2_select_output_pathClick(Sender: TObject);
var
  FileOpenDialog: TFileOpenDialog;
  OutputImage: TBitmap;
begin
  FileOpenDialog := TFileOpenDialog.Create(nil);
  try
    FileOpenDialog.Options := [fdoPickFolders];
    FileOpenDialog.Title := 'Select Output Path';
    if FileOpenDialog.Execute then
    begin
      OutputImage := TBitmap.Create;
      try
        // Create a copy of the original image
        OutputImage.Assign(OriginalImage);

        // Apply the blur effect to the output image here...

        // Save the output image to the selected folder
        OutputImage.SaveToFile(FileOpenDialog.FileName + '\output.jpg');
      finally
        OutputImage.Free;
      end;
    end;
  finally
    FileOpenDialog.Free;
  end;
end;

end.
fd3cxomn

fd3cxomn1#

答案在TPicture.Bitmap文档中:
如果在图片包含图元文件或图标图形1时引用Bitmap,则不会转换该图形(Types of Graphic Objects)。相反,图片的原始内容将被丢弃,Bitmap将返回一个新的空白位图。
1:只需将"图元文件或图标图形"替换为"任何非BMP图形"。
因此,如果用户选择非.bmp文件(很可能是这样的,因为.bmp文件现在很少使用,支持其他文件格式,如PNG),那么访问img1.Picture.Bitmap将清除已经加载到img1.Picture中的当前图像,替换为一个空的TBitmap对象(然后将其分配给OriginalImage对象)。这就是为什么在TImage中看不到任何显示的内容。
解决方案是通过TPicture.Graphic属性而不是TPicture.Bitmap属性访问原始加载的映像,例如:

OriginalImage.Assign(img1.Picture.Graphic);

话虽如此,您的代码还有另一个问题:

OutputImage.SaveToFile(FileOpenDialog.FileName + '\output.jpg');

OutputImageTBitmap,因此其SaveToFile()方法只能创建BMP编码的文件。因此,您正在创建一个扩展名为.jpg的BMP文件,这不会使其成为有效的JPG图像。为此,您需要使用TJPEGImage而不是TBitmap,例如:

uses
  ..., Vcl.Imaging.jpeg;

procedure TForm1.btn2_select_output_pathClick(Sender: TObject);
var
  FileOpenDialog: TFileOpenDialog;
  BlurredImage: TBitmap;
  OutputImage: TJPEGImage;
begin
  FileOpenDialog := TFileOpenDialog.Create(nil);
  try
    FileOpenDialog.Options := [fdoPickFolders];
    FileOpenDialog.Title := 'Select Output Path';
    if FileOpenDialog.Execute then
    begin
      BlurredImage := TBitmap.Create;
      try
        // Create a copy of the original image
        BlurredImage.Assign(OriginalImage);

        // Apply the blur effect to the output image here...

        // Save the output image to the selected folder
        OutputImage := TJPEGImage.Create;
        try
          OutputImage.Assign(BlurredImage);
          OutputImage.SaveToFile(FileOpenDialog.FileName + '\output.jpg');
        finally
          OutputImage.Free;
        end;
      finally
        BlurredImage.Free;
      end;
    end;
  finally
    FileOpenDialog.Free;
  end;
end;
    • 更新日期:**

也就是说,如果您希望输出文件与输入文件格式相同,那么您可以这样做:

var
  OriginalImage: TGraphic;
  OriginalExt: String;

...

procedure TForm1.btn1_select_imgClick(Sender: TObject);
var
  OpenDialog: TOpenDialog;
begin
  OpenDialog := TOpenDialog.Create(nil);
  OpenDialog.Filter := 'All Files|*.*';
  OpenDialog.Options := [ofPathMustExist, ofFileMustExist];
  try
    if OpenDialog.Execute then
    begin
      lbl_selected_file.Caption := OpenDialog.FileName;
      img1.Picture.LoadFromFile(OpenDialog.FileName);
      OriginalImage := TGraphicClass(img1.Picture.Graphic.ClassType).Create;
      OriginalImage.Assign(img1.Picture.Graphic);
      OriginalExt := ExtractFileExt(OpenDialog.FileName);
    end;
  finally
    OpenDialog.Free;
  end;
end;

procedure TForm1.btn2_select_output_pathClick(Sender: TObject);
var
  FileOpenDialog: TFileOpenDialog;
  BlurredImage: TBitmap;
  OutputImage: TGraphic;
begin
  FileOpenDialog := TFileOpenDialog.Create(nil);
  try
    FileOpenDialog.Options := [fdoPickFolders];
    FileOpenDialog.Title := 'Select Output Path';
    if FileOpenDialog.Execute then
    begin
      BlurredImage := TBitmap.Create;
      try
        // Create a copy of the original image
        BlurredImage.Assign(OriginalImage);

        // Apply the blur effect to the output image here...

        // Save the output image to the selected folder
        OutputImage := TGraphicClass(OriginalImage.ClassType).Create;
        try
          OutputImage.Assign(BlurredImage);
          OutputImage.SaveToFile(FileOpenDialog.FileName + '\output' + OriginalExt);
          // alternatively:
          // OutputImage.SaveToFile(FileOpenDialog.FileName + '\output.' + GraphicExtension(TGraphicClass(OutputImage.ClassType)));
        finally
          OutputImage.Free;
        end;
      finally
        BlurredImage.Free;
      end;
    end;
  finally
    FileOpenDialog.Free;
  end;
end;
cunj1qz1

cunj1qz12#

你知道你可以在VCL应用程序中使用FMX.TBitmap类吗?
为什么会有人考虑在VCL应用程序中使用FMX.TBitmap
对于一个FMX.TBitmap.LoadFromFile类支持加载和保存许多图像类型轻松。
另一件事是,你可以很容易地应用任何数字FMX.Filter.Effects到所说的FMX位图
唯一的问题是没有简单的方法将FMX位图加载到VCL组件或从VCL组件加载FMX位图。
下面是一个简单的代码示例,用于为选定的文件添加Pixelate效果,然后将其保存到另一个文件中

uses FMX.Graphics, FMX.Filter.Effects;

procedure TForm1.BtnOpenImageClick(Sender: TObject);
begin
  if OpenDialog1.Execute then
  begin
    Image1.Picture.LoadFromFile(OPenDialog1.FileName);
    OriginalFileName := OpenDialog1.FileName;
  end;
end;

procedure TForm1.BtnSaveProcessedImageClick(Sender: TObject);
var FMXOriginalBitmap: FMX.Graphics.TBitmap;
    FMXProcessedBitmap: FMX.Graphics.TBitmap;
    FMXPixelateFilter: FMX.Filter.Effects.TFilterPixelate;
begin
  FMXOriginalBitmap := FMX.Graphics.TBitmap.Create;
  FMXOriginalBitmap.LoadFromFile(OriginalFileName);

  FMXPixelateFilter := FMX.Filter.Effects.TFilterPixelate.Create(nil);
  FMXPixelateFilter.Input := FMXOriginalBitmap;
  FMXPixelateFilter.BlockCount := 100;
  FMXProcessedBitmap := FMXPixelateFilter.Output;
  FMXProcessedBitmap.SaveToFile('D:\Proba.jpg');

  Image2.Picture.LoadFromFile('D:\Proba.jpg');
end;

相关问题