You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Delphi FireMonkey下ScaledLayout多余线条及ImageList问题如何修复

Delphi FMX ImageList 缩放多余线条修复方案

问题说明

该bug在Delphi 10.3、10.4版本均可复现,表现为ScaledLayout缩放后,关联ImageList的菜单/控件边缘出现异常多余线条,更换更大尺寸的图标无法解决,属于ImageList原生实现问题。
原始尺寸界面:
原始尺寸界面
全屏界面:
全屏界面

最小复现代码

unit Unit1;

interface

uses
  System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
  FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs,
  System.ImageList, FMX.ImgList, FMX.Menus, FMX.Objects, FMX.Layouts;

type
  TForm1 = class(TForm)
    Image1: TImage;
    PopupMenu1: TPopupMenu;
    MenuItem1: TMenuItem;
    ImageList1: TImageList;
    MenuItem2: TMenuItem;
    MenuItem3: TMenuItem;
    MenuItem4: TMenuItem;
    ScaledLayout1: TScaledLayout;
    procedure Image1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.fmx}

procedure TForm1.Image1Click(Sender: TObject);
begin
  PopupMenu1.Popup(Image1.Position.X,Image1.Position.Y);
end;

end.

修复方案

  • 方案1:图标预处理(无代码改动)
    给所有导入ImageList的图标边缘预留1px的透明边,同时将ImageList的Width、Height属性设置为比实际使用的图标尺寸大2px,绘制时会自动裁剪掉边缘溢出的采样像素,可快速解决问题。
  • 方案2:运行时动态刷新缓存
    在PopupMenu的OnPopup事件中加入以下代码,强制刷新ImageList的图标缓存,避免缩放后的缓存异常:
procedure TForm1.PopupMenu1Popup(Sender: TObject);
begin
  ImageList1.Clear;
  // 此处替换为自身业务的图标加载逻辑,重新加载所有图标
  LoadIconsToImageList(ImageList1);
end;
  • 方案3:源码级根修复
    找到Delphi安装目录下的FMX.ImgList.pas文件,复制到你的项目目录下,找到TImageList.Draw方法中绘制纹理的代码段,将绘制坐标整体偏移0.5像素,避免亚像素采样导致的边界溢出,修改完成后重新编译项目即可,该方案可以彻底解决同类型的ImageList缩放线条问题。
  • 方案4:控件替换
    使用Delphi 10.3及以上版本自带的TImageCollection替代原生TImageList存储图标,该控件对多DPI、缩放场景的适配做了优化,不会出现该边界线条问题,原有业务代码只需做少量调整即可适配。

内容的提问来源于stack exchange,提问作者Wellington Telles Cunha

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 01:36:07