【问题标题】:How to add images to TImageCollection programmatically如何以编程方式将图像添加到 TImageCollection
【发布时间】:2021-01-22 16:59:06
【问题描述】:

我正在尝试加载我想要填充和保存的 TImageCollection,以便它可以作为数据模块(.dfm 文件)中的资源使用。 此代码将图像从选定的 .png 文件添加到图像集合中,我可以看到计数增加,所以它正在填充​​p>

 ImageCollectionMS.Images.Add(ChangeFileExt(ShortName,''), Path+Shortname);`

但我需要将其保存为资源。可以吗?

【问题讨论】:

  • 查看TStream.WriteComponent()TStream.WriteComponentRes() 以将TComponent 派生的对象保存到DFM 格式的流中。
  • 你在写源代码生成器吗?一种编译器?或者也许是 IDE 扩展?如果您解释一下您想要达到的目标,也许我们可以给出更好的答案?
  • 我想自动构建大型 ImageCollection,使用特定的编程标准选择 .png 文件,而不是煞费苦心地逐个添加它们,试图遵循规则但并不总是成功。 (多年来,我不得不编写程序来组织我的数据。)如果 Image Collection Editor 可以以编程方式完成,我想我可以尝试。
  • @Mike-Scott 不确定您的具体情况,但是如果您想要真正需要通过一些规则填充的“大型 ImageCollections” - 为什么不在运行时组织它,将图像存储在文件系统中,在某种文件(xml、ini、json 等)中定义您的规则。我不明白为什么您需要在 DFM 中收集复杂而庞大的图像。

标签: image delphi collections dfm delphi-10.4-sydney


【解决方案1】:

我就是这样做的:

  1. 按PNG添加到ImageCollection、PNG文件(使用首选标准):

    ImageCollectionX.Add(ChangeFileExt(ShortName,''), FullFilename);

然后构建虚拟 .DFM 和 .PAS 文件:

function PosInStr(const substr, str: String): integer;
var start, p : integer;
begin
  start := 1;
  Result := 0;
  repeat
    p := PosEx(Substr,Str,start);
    if p>0 then begin
      start := p+1;
      inc(Result);
    end;
  until P=0;
end;

procedure TForm1.WriteDFM(aStream: TStream; const ImgCollName, Suffix, Filename: string);
const DFMStart : array[0..14] of string =
  ('object Form%s: TForm%s',
  'Left = 0',
  'Top = 0',
  'Caption = ''Form%s''',
  'ClientHeight = 299',
  'ClientWidth = 635',
  'Color = clBtnFace',
  'Font.Charset = DEFAULT_CHARSET',
  'Font.Color = clWindowText',
  'Font.Height = -11',
  'Font.Name = ''Tahoma''',
  'Font.Style = []',
  'OldCreateOrder = False',
  'PixelsPerInch = 96',
  'TextHeight = 13');
var
  i, n : integer;
  outpfrm, outpImg : TStringlist;
  ConvStream: TStream;
begin
  aStream.Position := 0;
  outpFrm := TStringlist.Create;
  outpImg := TStringlist.Create;
  ConvStream := TMemoryStream.Create;
  try
    ObjectBinaryToText (aStream, ConvStream);
    ConvStream.Position := 0;
    outpImg.LoadFromStream(ConvStream);
    for i := Low(DFMStart) to High(DFMStart) do begin
      n := PosInStr('%s', DFMStart[i]);
      case n of 0:  outpFRM.Add(DFMStart[i]);
        1 : outpFRM.Add(Format(DFMStart[i],[suffix]));
        2 : outpFRM.Add(Format(DFMStart[i],[suffix, suffix]));
      end;
    end;
    outpFrm.AddStrings(outpImg);
    outpFrm.Add('end');
    outpFrm.SaveToFile(ChangeFileExt(Filename,'.dfm'));
    writePasForDFM(ImgCollName, Suffix, Filename);
  finally
    outpFrm.Free;
    outpImg.Free;
    ConvStream.Free
  end;
end;

procedure TForm1.WritePasForDFM(const ImgCollName, Suffix, Filename: string);
const
  PasStart : array[0..15] of string =
  ('unit %s;',
  'interface',
  'uses',
  'Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,',
  'Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.BaseImageCollection, Vcl.ImageCollection;',
  '',
  'type',
  'TForm%s = class(TForm)',
  '@: TImageCollection;',
  'end;',
  '',
  'var',
  'Form%s: TForm%s;',
  'implementation',
  '{$R *.dfm}',
  'end.');
var
  i, n: integer;
  outp : TStringlist;
begin
  outp := TStringlist.Create;
  try
    for i := Low(PASStart) to High(PASStart) do begin
      n := PosInStr('%s', PASStart[i]);
      case n of 0:
      if POs('@', PASStart[i])>0 then
        outp.Add(ImgCollName+ Copy(PASStart[i],2,maxint))
        else outp.Add(PASStart[i]);
        1 : outp.Add(Format(PasStart[i],[suffix]));
        2 : outp.Add(Format(PasStart[i],[suffix, suffix]));
      end;
    end;
    outp.SaveToFile(ChangeFileExt(Filename,'.pas'));
  finally
    outp.Free;
  end;
end;


【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-08-12
    • 1970-01-01
    • 1970-01-01
    • 2020-07-16
    • 2014-03-20
    • 2013-03-07
    • 2010-12-02
    • 1970-01-01
    相关资源
    最近更新 更多