Page 1 of 1
How to find all images fast?
Posted: Mon Sep 15, 2025 11:48 pm
by whisper1980
I have a need to be able to find all images in a set of rtf streams so that I can show the user what images in the database are not yet being used. They are not embedded images, just linked images that I use importPicture event when I need to load them. There can be on average 30 RTF streams I have to search through. Doing it this way is quite slow, especially if each RTF stream is fairly large:
var vTLE := vRVE.TopLevelEditor;
for var i := 0 to vTLE.ItemCount-1 do
begin
var vSomeItem := vTLE.GetItem(i);
if (not vSomeItem.GetExtraStrProperty(rvespImageFileName, vValue)) or (vValue = '') then continue;
...
Where vValue is contains the filename info.
Is there a better and faster way other than perhaps string searching the raw RTF.
TrichViewFMX v23.2
Delphi 12.3 (soon v13)
Thanks,
Eric
Re: How to find all images fast?
Posted: Tue Sep 16, 2025 3:13 pm
by Sergey Tkachenko
This enumeration code must be very fast.
The slow operations are:
1) loading RTF
2) formatting.
If you just need to enumerate images without displaying document, just use TRichView to load document from database stream and search in it.
Do not use TDBRichView or TDBRichViewEdit for this task, because they format themselves after loading from DB.
Use vRVE.LoadRTFFromStream if you are sure that documents are RTF and the field is not wide-memo. If you are not sure, use vRVE.LoadFromStream.
But your code enumerates not all images, but only images in TopLevelEditor.
The simplest way to enumerate all items is calling vRVE.RVData.EnumItems. This method will call your procedure for each item in the document.
Example:
Code: Select all
uses
RVItem, CRVData;
procedure TForm1.MyEnumItemsProc(RVData: TCustomRVData;
ItemNo: Integer; var UserData1: Integer; const UserData2: TRVUnicodeString;
var ContinueEnum: Boolean);
begin
if RVData.GetItem(ItemNo) is TRVGraphicItemInfo then
begin
RVData.GetItem(ItemNo).GetExtraStrProperty(rvespImageFileName, ...);
...
end;
ContinueEnum := True;
end;
How to call:
Code: Select all
var
v: Integer;
begin
v := 0;
vRVE.RVData.EnumItems(MyEnumItemsProc, v, '');
end;
Re: How to find all images fast?
Posted: Wed Sep 17, 2025 6:30 pm
by whisper1980
Yeah, I noticed it wasn't finding all the images as I tested.
But I cannot seem to be able to use a TRichView component in my Android app. The LoadFromStream, or LoadRTFFromStream immediately halts the app without being able to trap the error. I have to use a TRichViewEdit. However, the MyEnumItemsProc gets called but does not find any TRVGraphicItemInfo items.
Using the TRichViewEdit's event OnImportPicture, I can enumerate the used images without actually loading the graphic (I just use it to get the name it wants to load). Is that just as good?
Re: How to find all images fast?
Posted: Wed Sep 17, 2025 7:09 pm
by whisper1980
FWIW, I added a post in the private forum with a stack trace where the app halts when using a TRichView as mentioned.
viewtopic.php?t=15165