Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Delphi XE7 FMX损坏的PNG缩略图_Delphi_Png_Firemonkey_Delphi Xe7 - Fatal编程技术网

Delphi XE7 FMX损坏的PNG缩略图

Delphi XE7 FMX损坏的PNG缩略图,delphi,png,firemonkey,delphi-xe7,Delphi,Png,Firemonkey,Delphi Xe7,在XE7-Update1 FMX Windows7-64位中创建缩略图时遇到问题。XE5中不存在此问题 我有三个TImage组件,一个按钮和FMX HD表单上的TopEndDialog组件 使用TOpenDialog,我选择了一个已经在Photoshop/Corel中测试过的、看起来不错的现有PNG。图像在图像1中正确显示 在运行时,我使用Image1.Bitmap.create缩略图创建两个缩略图,并将结果分配给Image2和Image3。在XE7上,Image2和Image3的背景已损坏,表

在XE7-Update1 FMX Windows7-64位中创建缩略图时遇到问题。XE5中不存在此问题

我有三个TImage组件,一个按钮和FMX HD表单上的TopEndDialog组件

使用TOpenDialog,我选择了一个已经在Photoshop/Corel中测试过的、看起来不错的现有PNG。图像在图像1中正确显示

在运行时,我使用
Image1.Bitmap.create缩略图创建两个缩略图,并将结果分配给Image2和Image3。在XE7上,Image2和Image3的背景已损坏,表单的随机部分已损坏。使用XE5,一切都很好

当我重复这个过程(在Image1中加载PNG…创建缩略图并显示)时,损坏会增加

保存到文件时存在损坏的背景

代码如下:

procedure TForm1.Button1Click(Sender: TObject);
begin
  FormShow(nil);
end;

procedure TForm1.FormShow(Sender: TObject);
var
  thumbX, thumbY : Integer;
  SaveParams: TBitmapCodecSaveParams;
  thumb1, thumb2 : TBitmap;
begin
  if OpenDialog1.Execute then
  begin
    Image1.Bitmap.LoadFromFile(OpenDialog1.FileName);
    try        
      thumbX := Round(Image1.Width / 4);
      thumbY := Round(Image1.Height / 4);
      thumb1 := Image1.Bitmap.CreateThumbnail(thumbX, thumbY);
      Image2.Bitmap.SetSize(thumbX, thumbY); //this has no impact
      Image2.Bitmap.Assign(thumb1);
    finally
      thumb1.free;
    end;

    try
      thumbX := Round(Image1.Width / 2);
      thumbY := Round(Image1.Height /2);
      thumb2 := Image1.Bitmap.CreateThumbnail(thumbX, thumbY);
      Image3.Bitmap.SetSize(thumbX, thumbY); //this has no impact
      Image3.Bitmap.Assign(thumb2);
    finally
      thumb2.Free;   
    end;

    SaveParams.Quality := 100;
    Image2.Bitmap.SaveToFile('c:\blackdot\image_quarter.png', @SaveParams);
    Image3.Bitmap.SaveToFile('c:\blackdot\image_half.png', @SaveParams);
  end;
end;
任何关于如何解决这个问题的想法都将非常有用

我们尝试:

  • 使无效
  • 在指定缩略图之前,设置image2、image3的大小
  • 在指定缩略图之前清除image2、image3

  • 查看了FMX.Graphics中的
    CreateThumbnail
    代码,但是我们看到的没有什么可以改变的来修补这个问题。

    这肯定是一个大错误。我使用了示例代码,并亲自进行了尝试。
    结果:
    1) 图像2的缩放效果不好,并且始终与图像3的大小相同
    2) 3次尝试后,图像2由两个重叠图像组成:前面是第三次尝试的图像,后面是第一次尝试的图像


    该过程是可重复的,图像的选择也不相关,因为这似乎是XE7的一个缺陷,我采用了另一种方法,似乎在测试代码中也能起作用。我没有使用TBitmap.CreateThumbnail创建拇指,而是使用传递所需拇指宽度和高度的TBitmap.LoadThumbnailFromFile创建拇指。我想在真正的应用程序中,我们可以直接在可视化组件中加载thumb,而不必在运行时创建TBitmaps

    尽管这种方法反复从磁盘加载文件,但它允许我们继续应用程序开发。使用测试代码,我可以反复加载图像,这些图像既直观又正确地保存到文件中

    var
       thumbX, thumbY : Integer;
       SaveParams: TBitmapCodecSaveParams;
       thumb1, thumb2 : TBitmap;
    begin
         if OpenDialog1.Execute then
         begin
           Image1.Bitmap.LoadFromFile(OpenDialog1.FileName);
    
             thumbX := Round(Image1.Width / 4);
             thumbY := Round(Image1.Height / 4);
             //thumb1 := Image1.Bitmap.CreateThumbnail(thumbX, thumbY);
             thumb1 := TBitmap.Create;
           try
             thumb1.LoadThumbnailFromFile(OpenDialog1.FileName, thumbX, thumbY);
             thumb1.SaveToFile('c:\blackdot\thumb1.png');  //just to compare with our visual components
             Image2.Bitmap.SetSize(thumbX, thumbY);
             Image2.Bitmap.Assign(thumb1);
           finally
             thumb1.Free;
           end;
    
    
             thumbX := Round(Image1.Width / 2);
             thumbY := Round(Image1.Height /2);
             //thumb2 := Image1.Bitmap.CreateThumbnail(thumbX, thumbY);
             thumb2 := TBitmap.Create;
           try
             thumb2.LoadThumbnailFromFile(OpenDialog1.FileName, thumbX, thumbY);
             thumb2.SaveToFile('c:\blackdot\thumb2.png');  //just to compare with our visual components
             Image3.Bitmap.SetSize(thumbX, thumbY);
             Image3.Bitmap.Assign(thumb2);
           finally
             thumb2.Free;
           end;
    
           SaveParams.Quality := 100;
           Image2.Bitmap.SaveToFile('c:\blackdot\image_quarter.png', @SaveParams);
           Image3.Bitmap.SaveToFile('c:\blackdot\image_half.png', @SaveParams);
    
         end;
    end;
    

    TBitmap.create缩略图()
    返回一个新的
    TBitmap
    对象
    TBitmap.Assign()
    创建图像数据的副本,但不获取原始数据的所有权。所以你正在泄漏那些
    TBitmap
    对象。@RemyLebeau是的,非常正确。测试代码已更改,但结果相同。
    try
    应该紧跟在
    CreateThumbnail()
    之后,而不是在
    Round()
    之前。谢谢,你说得对。如果没有创建拇指,代码不应该尝试释放拇指,理论上,在我们创建拇指之前,Round操作可能会失败。知道了。但这只是说明实际问题的测试代码。为什么拇指被损坏了。你是说这是因为尝试不在正确的地方,还是我泄露了TBitmaps(都是真的)?如果是这样的话,我想更详细地了解这一点。我认为XE7中存在一个问题,特别是因为即使是泄漏的TBitmap版本也可以在XE5中工作。我们在一个大得多的应用程序中发现了这个问题,并编写了这个“坏”代码,以确定问题是否与我们的应用程序或XE7中的其他内容有关。也许有更好的方法来创造拇指?也许我的方法不正确?