Just reading through that code, I see many areas for improvement.

Try changing TImageListCollection.LoadFromFile to use a TFileStream instead of a TMemoryStream. This will prevent the initial hit of allocating 19MB of memory and loading the entire file into it.
Code:
procedure TImageListCollection.LoadFromFile(const Filename: string);
var
  Stream: TFileStream;
begin
  Stream := TFileStream.Create(Filename, fmOpenRead or fmShareDenyNone;
  try
    LoadFromStream(Stream);
  finally
    Stream.Free;
  end;
end;
Not much can be done about TOmegaImageList.Init.

TImageListItem.Init could be improved in several places.

- FFilePath should have been trimmed before it was saved. Therefore there should be no need to always trim FFilePath every time you enter this method. Move the call to Trim to inside the if statement. But that's only a tiny problem.

- For every item in the list, you are creating a TMemoryStream and saving the image back to it so that D3DX can load that very same picture back in again. Very inefficient. That's where most of your time is being taken up.

If you don't want 600+ files on your harddisk, then this imagelist is not a very efficient way to avoid that. A better solution would be to use a system similar to a PAK file where multiple files are lumped together into one big file. Manually create each instance of TImageListItem and set the Filename property. Then you just create a TMemoryStream, load the file from the PAK file into the stream, pass that to D3DX, free the stream. Still not the most efficient method, but it should be more efficient than the current method.

I could possibly create a proof of concept for this, but I won't be able to do that for a couple of days.