【问题标题】:Picture Database, TDBImages, TImageList, Delphi图片数据库、TDBImages、TImageList、Delphi
【发布时间】:2014-09-25 15:21:33
【问题描述】:

我正在编写一个显示图片(地图)的程序。当您点击图片的一部分时,它必须放大。总共有26张图片(包括主图)。我想将这些图片加载到 Delphi 中,并将 Image1(Whole_map.jpg) 替换为 Amusement_park.jpg。

我想使用高质量的 jpg 而不是位图 :( *是否可以将这 26 个图像加载到 TImageList 并仍然使用其质量的图像 要么 *我可以将图像保存在某种数据库中并将其加载到 Delphi 中

Loading images and converting to bitmap 没有帮助,因为我不想使用位图。 我也不想使用任何第三方组件,因为这个程序必须在默认的 Delphi 2010 上运行。

【问题讨论】:

  • 我不确定在这种情况下您是否应该使用TImageList 来存储(高分辨率?)图像(而不是图标)。改为创建并使用通用 TObjectList<TImage>
  • 你为什么不简单地创建一个 TJpegImage 数组并在每个 TJpegImage 中存储单独的图像。
  • @SilverWarior 我已经创建了一个数组arrPics : array[1..26] of TJPEGImage; 如何将图像添加到其中?我尝试将位置名称(字符串)加载到数组中,但它不起作用。
  • 如果不提供一些代码说明你是如何做到的,很难说它为什么不起作用。

标签: image delphi jpeg delphi-2010 timagelist


【解决方案1】:

正如我在评论中提到的,您可以创建一个 TJPEGImage 对象数组来存储图像。

你这样做:

//Global array for storing images
var Images: Array [1..26] of TJPEGImage;

implemenetation

...

procedure TForm1.FormCreate(Sender: TObject);
var I: Integer;
begin
  for I := 1 to 26 do
  begin
    //Since TJPEGIMage is a class we first need to create each one as array only
    //stores pointer to TJPEGImage object and not the object itself
    Images[I] := TJPEGImage.Create;
    //Then we load Image data from file into each TJPEGImage object
    //If file names are not numerically ordered you would probably load images
    //later and not inside this loop. This depends on your design
    Images[I].LoadFromFile('D:\Image'+IntToStr(I)+'.jpg');
  end;
end;

正如您在源评论中看到的,该数组仅存储指向 TJPEGImage 对象的指针,而不存储 TJPEGImage 对象本身。所以不要忘记在尝试将任何图像数据加载到它们之前创建它们。否则将导致访问冲突。

另外,因为您自己创建了这些 TJPEGImage 对象,您还需要自己释放它们以避免可能的内存泄漏

procedure TForm1.FormDestroy(Sender: TObject);
var I: Integer;
begin
  for I := 1 to 26 do
  begin
    Images[I].Free;
  end;
end;

为了在您的 TImage 组件中显示这些存储的图像,请使用此

//N is array index number telling us which array item stores the desired image
Image1.Picture.Assign(Images[N]); 

您可以使用的第二种方法

现在,由于 TJPEGImage 是分类对象,您还可以使用 TObjectList 来存储指向它们的指针。 在这种情况下,创建代码将如下所示

procedure TForm1.FormCreate(Sender: TObject);
var I: Integer;
    Image: TJPEGImage;
for I := 1 to NumberOfImages do
  begin
    //Create TObject list with AOwnsObjects set to True means that destroying
    //the object list will also destroy all of the objects it contains
    //NOTE: On ARC compiler destroying TObjectList will only remove the reference
    //to the objects and they will be destroyed only if thir reference count
    //drops to 0
    Images := TObjectList.Create(True);
    //Create a new TJPEGImage object
    Image := TJPEGImage.Create;
    //Load image data into it from file
    Image.LoadFromFile('Image'+IntToStr(I)+'.jpg');
    //Add image object to our TObject list to store reference to it for further use
    Images.Add(Image);
  end;
end;

您现在可以像这样显示这些图像

//Note becouse first item in TObject list has index of 0 you need to substract 1
//from your ImageNumber
Image1.Picture.Assign(TJPEGImage(Images[ImageNumber-1]));

由于我们将 TObjectList 设置为拥有 TJPEGImage 对象,因此我们可以像这样快速销毁所有对象

//NOTE: On ARC compiler destroying TObjectList will only remove the reference
//to the objects and they will be destroyed only if thir reference count
//drops to 0
Images.Free;

【讨论】:

  • 非常感谢兄弟!我使用了第一种方法,效果很好。有点话题...你说我需要释放它procedure TForm1.FormDestroy(Sender: TObject); var I: Integer; begin for I := 1 to 26 do begin Images[I].Free; end; end;我不明白我有什么效果?
  • 由于其大小限制,使用评论/s 来解释这一点并不容易,但我会尝试。首先需要了解组件和常规类之间的区别(组件是特殊类)。创建组件时,您会在创建过程中为其分配所有者。因此,现在当所有者被销毁时,它会通知它拥有的所有组件,因此它们也会销毁自己(释放自己的内存)。因此,对于组件,您无需特别注意,除非您在创建时将所有者设置为 lill(无所有者)。它继续......
  • 但是当您在您的情况下创建其他类(如 TJPEGImage)时,您无法为它们指定所有者,这意味着当他们需要销毁它们时不会通知他们,除非您通过调用这样做他们每个人都是免费的。这意味着他们永远不会释放他们正在使用的内存。这种情况被称为“内存泄漏”。现在确实,在您的特定情况下,不释放 TJPEGImage 对象不会造成太大问题,因为它们的内存将在应用程序终止时释放。它再次继续......
  • 但是如果这些是其他一些以不同方式处理其内存的类,则可能导致即使在应用程序终止时也不会释放一些内存。这很糟糕,因为它可能导致您的操作系统内存不足,因为操作系统仍然认为这部分内存是保留的。现在,如果这些类正在初始化硬盘驱动器上的某些文件的句柄,则可能会出现更严重的问题,因为即使在您的应用程序终止后,操作系统仍可能将此类文件视为仍在打开的文件。它再次继续......
  • 或者,如果这些类提供了一些其他应用程序使用的扩展功能,则终止您的应用程序可能会导致挂起另一个。为什么?因为这些类不会被销毁,它们将没有机会通知其他应用程序它们将无法再工作的事实。因此,其他应用程序可能只是无限期地等待某些结果并因此挂起。无论如何,这里有很多案例要写下来。它再次继续......
猜你喜欢
  • 2012-05-31
  • 2011-05-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-24
相关资源
最近更新 更多