few questions about gflLoadThumbnail
Moderators: XnTriq, helmut, xnview
few questions about gflLoadThumbnail
Hello and good evening!
i tried around with gfl-sdk about gflLoadThumbnail (using Delphi) and encountered 3 questions i would appreciate very much to have an answer on.
1) Building thumbnails i use gflLoadThumbnail following the Delphi sample in the sdk.
For to remove "unwanted black markers" i use gflAutoCrop.
Is that approach ok so far?
The resulting gfl_bmp in that case may be smaller and needs to be recentered again.
So, then i need to manipulate heavily the subsequent transfer-scanline loop
using some calculated delta offsets for to have the correct center mode.
Method works, but is it ok or not straight-forward in your concept?
If not: recentering should be done by what?
2) Afterwards i store the resulting bitmap in a stringlist and paint the stringlist'ed bitmaps to a listview usingCanvas.StretchDraw (in CustomDrawItem) // painting flickers somehow
Is that good or do you think of to use a better approach to transfer the bitmaps to a listview?
3) -- this is what i was very irritated about --:
I noticed that my loop to retrieve thumbnails was slow. So i tested on a directory containing 450 images:
- using a loop only calling gflLoadThumbnail on the images (nothing else)
the result was: 38 seconds
against
- xnview without cache (thumbnail cache disabled)
the result was: 11 seconds
So, does xnview not use gflLoadThumbnail for to retrieve thumbnails or what might influence this drastic loss of speed?
Many thanks for answer in advance!
klaus2
i tried around with gfl-sdk about gflLoadThumbnail (using Delphi) and encountered 3 questions i would appreciate very much to have an answer on.
1) Building thumbnails i use gflLoadThumbnail following the Delphi sample in the sdk.
For to remove "unwanted black markers" i use gflAutoCrop.
Is that approach ok so far?
The resulting gfl_bmp in that case may be smaller and needs to be recentered again.
So, then i need to manipulate heavily the subsequent transfer-scanline loop
using some calculated delta offsets for to have the correct center mode.
Method works, but is it ok or not straight-forward in your concept?
If not: recentering should be done by what?
2) Afterwards i store the resulting bitmap in a stringlist and paint the stringlist'ed bitmaps to a listview usingCanvas.StretchDraw (in CustomDrawItem) // painting flickers somehow
Is that good or do you think of to use a better approach to transfer the bitmaps to a listview?
3) -- this is what i was very irritated about --:
I noticed that my loop to retrieve thumbnails was slow. So i tested on a directory containing 450 images:
- using a loop only calling gflLoadThumbnail on the images (nothing else)
the result was: 38 seconds
against
- xnview without cache (thumbnail cache disabled)
the result was: 11 seconds
So, does xnview not use gflLoadThumbnail for to retrieve thumbnails or what might influence this drastic loss of speed?
Many thanks for answer in advance!
klaus2
-
- Author of XnView
- Posts: 44920
- Joined: Mon Oct 13, 2003 7:31 am
- Location: France
Re: few questions about gflLoadThumbnail
Could you post the picture used before and after autocrop?klaus2 wrote: 1) Building thumbnails i use gflLoadThumbnail following the Delphi sample in the sdk.
For to remove "unwanted black markers" i use gflAutoCrop.
Is that approach ok so far?
The resulting gfl_bmp in that case may be smaller and needs to be recentered again.
So, then i need to manipulate heavily the subsequent transfer-scanline loop
using some calculated delta offsets for to have the correct center mode.
Method works, but is it ok or not straight-forward in your concept?
If not: recentering should be done by what?
No it's good2) Afterwards i store the resulting bitmap in a stringlist and paint the stringlist'ed bitmaps to a listview usingCanvas.StretchDraw (in CustomDrawItem) // painting flickers somehow
Is that good or do you think of to use a better approach to transfer the bitmaps to a listview?
XnView can use embedded thumbnail3) -- this is what i was very irritated about --:
I noticed that my loop to retrieve thumbnails was slow. So i tested on a directory containing 450 images:
- using a loop only calling gflLoadThumbnail on the images (nothing else)
the result was: 38 seconds
against
- xnview without cache (thumbnail cache disabled)
the result was: 11 seconds
So, does xnview not use gflLoadThumbnail for to retrieve thumbnails or what might influence this drastic loss of speed?
Pierre.
Hello Pierre,
info/remark below.
Many thanks for answer!
klaus2
about 1) (gflLoadThumbnail / autocrop)
> Could you post the picture used before and after autocrop?
a) == gflLoadThumbnail without autocrop
http://img339.imageshack.us/img339/8206 ... rop6pi.jpg
Please note:the darkgray area is only the background of the control which owns the image!
The black area is part of the image.
b) == gflLoadThumbnail with autocrop
http://img460.imageshack.us/img460/4676 ... rop6rc.jpg
Please note: the darkgray area is only the background of the control which owns the image.
The lightgray area is part of the image.
--> The image now is top/left-centered but i want it re-centered again ..
AutoCrop code (exception handling skipped for shortness):
pgflbackcolor := @(gflbackcolor);
e := gflGetColorAt(gfl_bmp, 0, 0, pgflbackcolor);
e := gflAutoCrop(gfl_bmp, nil, pgflbackcolor, 32);
c) == Attempt to re-center the image after autocrop:
http://img103.imageshack.us/img103/2770 ... ted9lf.jpg
- Original scanline-copy code (from Delphi sample):
for y := 0 to gfl_bmp.Height - 1 do begin
lineSrc := Pointer(Integer(gfl_bmp.data) + (y * gfl_bmp.BytesPerLine));
lineDest := bmp.Scanline[y];
move(lineSrc^, lineDest^, gfl_bmp.BytesPerLine);
end;
- Manipulated scanline-copy code for to get the middle-centering back:
deltax := (width_original - gfl_bmp.Width) div 2;
deltay := (height_original - gfl_bmp.Height) div 2;
if (deltax > 0) then begin
for y := 0 to gfl_bmp.Height - 1 do begin
lineSrc := Pointer(Integer(gfl_bmp.data) + (y * gfl_bmp.BytesPerLine));
lineDest := bmp.Scanline[y + deltay];
pBytearr := PByteArray(lineDest);
Move(lineSrc^, pBytearr[deltax * 3], gfl_bmp.BytesPerLine);
end
end
else begin
for y := 0 to gfl_bmp.Height - 1 do begin
lineSrc := Pointer(Integer(gfl_bmp.data) + (y * gfl_bmp.BytesPerLine));
lineDest := bmp.Scanline[y + deltay];
move(lineSrc^, lineDest^, gfl_bmp.BytesPerLine);
end
end;
>>> Do i need to do that by design or did i miss something?
about 3) > XnView can use embedded thumbnail
My test was Xnview without cache and with Options|Thumbnail|Use embedded thumbnail = off
and however a simple gflLoadThumbnail call (not more) on each file of a certain directory
was nearly three times slower than xnview building its listview thumbnails on the same directory.
What might be the reason? Can it be speedup'ed?
Besides: Sorry for my lack of knowledge: may gfl-sdk detect and process embedded thumbnails?
info/remark below.
Many thanks for answer!
klaus2
about 1) (gflLoadThumbnail / autocrop)
> Could you post the picture used before and after autocrop?
a) == gflLoadThumbnail without autocrop
http://img339.imageshack.us/img339/8206 ... rop6pi.jpg
Please note:the darkgray area is only the background of the control which owns the image!
The black area is part of the image.
b) == gflLoadThumbnail with autocrop
http://img460.imageshack.us/img460/4676 ... rop6rc.jpg
Please note: the darkgray area is only the background of the control which owns the image.
The lightgray area is part of the image.
--> The image now is top/left-centered but i want it re-centered again ..
AutoCrop code (exception handling skipped for shortness):
pgflbackcolor := @(gflbackcolor);
e := gflGetColorAt(gfl_bmp, 0, 0, pgflbackcolor);
e := gflAutoCrop(gfl_bmp, nil, pgflbackcolor, 32);
c) == Attempt to re-center the image after autocrop:
http://img103.imageshack.us/img103/2770 ... ted9lf.jpg
- Original scanline-copy code (from Delphi sample):
for y := 0 to gfl_bmp.Height - 1 do begin
lineSrc := Pointer(Integer(gfl_bmp.data) + (y * gfl_bmp.BytesPerLine));
lineDest := bmp.Scanline[y];
move(lineSrc^, lineDest^, gfl_bmp.BytesPerLine);
end;
- Manipulated scanline-copy code for to get the middle-centering back:
deltax := (width_original - gfl_bmp.Width) div 2;
deltay := (height_original - gfl_bmp.Height) div 2;
if (deltax > 0) then begin
for y := 0 to gfl_bmp.Height - 1 do begin
lineSrc := Pointer(Integer(gfl_bmp.data) + (y * gfl_bmp.BytesPerLine));
lineDest := bmp.Scanline[y + deltay];
pBytearr := PByteArray(lineDest);
Move(lineSrc^, pBytearr[deltax * 3], gfl_bmp.BytesPerLine);
end
end
else begin
for y := 0 to gfl_bmp.Height - 1 do begin
lineSrc := Pointer(Integer(gfl_bmp.data) + (y * gfl_bmp.BytesPerLine));
lineDest := bmp.Scanline[y + deltay];
move(lineSrc^, lineDest^, gfl_bmp.BytesPerLine);
end
end;
>>> Do i need to do that by design or did i miss something?
about 3) > XnView can use embedded thumbnail
My test was Xnview without cache and with Options|Thumbnail|Use embedded thumbnail = off
and however a simple gflLoadThumbnail call (not more) on each file of a certain directory
was nearly three times slower than xnview building its listview thumbnails on the same directory.
What might be the reason? Can it be speedup'ed?
Besides: Sorry for my lack of knowledge: may gfl-sdk detect and process embedded thumbnails?
-
- Author of XnView
- Posts: 44920
- Joined: Mon Oct 13, 2003 7:31 am
- Location: France
Not normal, could you send me the original picture?klaus2 wrote:about 1) (gflLoadThumbnail / autocrop)
> Could you post the picture used before and after autocrop?
a) == gflLoadThumbnail without autocrop
http://img339.imageshack.us/img339/8206 ... rop6pi.jpg
Please note:the darkgray area is only the background of the control which owns the image!
The black area is part of the image.
b) == gflLoadThumbnail with autocrop
http://img460.imageshack.us/img460/4676 ... rop6rc.jpg
Please note: the darkgray area is only the background of the control which owns the image.
The lightgray area is part of the image.
--> The image now is top/left-centered but i want it re-centered again ..
Could you post parameters used for gflLoadThumbnail?My test was Xnview without cache and with Options|Thumbnail|Use embedded thumbnail = off
and however a simple gflLoadThumbnail call (not more) on each file of a certain directory
was nearly three times slower than xnview building its listview thumbnails on the same directory.
What might be the reason? Can it be speedup'ed?
Besides: Sorry for my lack of knowledge: may gfl-sdk detect and process embedded thumbnails?
Pierre.
-
- Author of XnView
- Posts: 44920
- Joined: Mon Oct 13, 2003 7:31 am
- Location: France
Update about the "crop"-issue:
i fear i did run into the issue only because the receiving bitmap's transparent attribute had not been set So, my fault, in fact i did not need the crop operation in that case.
However, i found that thumbnails for bitmaps with numberOfPlanes = 4 (eg. some bitmaps used for toolbar buttons) are not painted well with the "original code", whereas they look ok with the "modified code". - So, are there any special recommendations for thumbnails for bitmaps with 4 planes?
The "speed issue" (gflLoadThumbnail very slow compared to xnview) is still vaild.
i fear i did run into the issue only because the receiving bitmap's transparent attribute had not been set So, my fault, in fact i did not need the crop operation in that case.
However, i found that thumbnails for bitmaps with numberOfPlanes = 4 (eg. some bitmaps used for toolbar buttons) are not painted well with the "original code", whereas they look ok with the "modified code". - So, are there any special recommendations for thumbnails for bitmaps with 4 planes?
The "speed issue" (gflLoadThumbnail very slow compared to xnview) is still vaild.
-
- Author of XnView
- Posts: 44920
- Joined: Mon Oct 13, 2003 7:31 am
- Location: France
4 planes = 32bits?klaus2 wrote:Update about the "crop"-issue:
i fear i did run into the issue only because the receiving bitmap's transparent attribute had not been set So, my fault, in fact i did not need the crop operation in that case.
However, i found that thumbnails for bitmaps with numberOfPlanes = 4 (eg. some bitmaps used for toolbar buttons) are not painted well with the "original code", whereas they look ok with the "modified code". - So, are there any special recommendations for thumbnails for bitmaps with 4 planes?
The "speed issue" (gflLoadThumbnail very slow compared to xnview) is still vaild.
Pierre.
No, in that case bmp.Pixelformat is pf24bit.
.
In the windows explorer the bitmap looks so:
http://img338.imageshack.us/img338/9266/exp7if.jpg
With Xnview as well as with the "modified code" using the crop stuff (as sent by mail) it looks correctly:
http://img387.imageshack.us/img387/2127 ... nnt5hq.jpg
.
With the "original code" as picked up from the Delphi sample it looks bad as:
http://img387.imageshack.us/img387/5908 ... ted3gg.jpg
.
In the windows explorer the bitmap looks so:
http://img338.imageshack.us/img338/9266/exp7if.jpg
With Xnview as well as with the "modified code" using the crop stuff (as sent by mail) it looks correctly:
http://img387.imageshack.us/img387/2127 ... nnt5hq.jpg
.
With the "original code" as picked up from the Delphi sample it looks bad as:
http://img387.imageshack.us/img387/5908 ... ted3gg.jpg
-
- Author of XnView
- Posts: 44920
- Joined: Mon Oct 13, 2003 7:31 am
- Location: France
But what the original file?klaus2 wrote:No, in that case bmp.Pixelformat is pf24bit.
.
In the windows explorer the bitmap looks so:
http://img338.imageshack.us/img338/9266/exp7if.jpg
With Xnview as well as with the "modified code" using the crop stuff (as sent by mail) it looks correctly:
http://img387.imageshack.us/img387/2127 ... nnt5hq.jpg
.
With the "original code" as picked up from the Delphi sample it looks bad as:
http://img387.imageshack.us/img387/5908 ... ted3gg.jpg
Pierre.
Maybe i'm somehow wrong here .. following the information:
-
the xnview property page says:
width 16
height 16
Pixels per inch: ???x ???
Bits per plane: 32
# of planes: 1
color model: RGB
Bits per pixel: 32
Compression: none
# of pages/frames: 1
-
But, the code i use is (shortened):
e := gflLoadThumbnail(PChar(filename), wid, heigh, gfl_bmp, lp, finfo);
//no_planes := finfo.NumberOfPlanes; // that cannot be compiled; so:
no_planes := finfo.ComponentsPerPixel; // returns "4" for the sample bitmap
if (gfl_bmp.Btype = GFL_BINARY) then begin
bpp := 1;
end else begin
bpp := gfl_bmp.BytesPerPixel * 8;
end;
...
bmp.PixelFormat := IntToPixelFormat(bpp); // gives pf24Bit for the sample bitmap
....
case bmp.PixelFormat of
pf24Bit, pf32Bit:
begin
if no_planes < 4 then begin
// ----- original coding from the delphi sample
// ----- does not work well with the sample bitmap
for y := 0 to gfl_bmp.Height - 1 do begin
lineSrc := Pointer(Integer(gfl_bmp.data) + (y * gfl_bmp.BytesPerLine));
lineDest := bmp.Scanline[y];
move(lineSrc^, lineDest^, gfl_bmp.BytesPerLine);
end;
end else begin
// ------- NumberOfPlanes = 4
// ------- used for test; works well with the sample bitmap
pgflbackcolor := @(gflbackcolor);
e := gflGetColorAt(gfl_bmp, 0, 0, pgflbackcolor);
e := gflAutoCrop(gfl_bmp, nil, pgflbackcolor, 32);
if (e <> gfl_no_error) then begin
MessageDlg('Thumbnail gflAutoCrop: ' + string(gflGetErrorString(e)), mtError, [mbOK], 0);
exit;
end;
deltax := (widold - gfl_bmp.Width) div 2;
deltay := (heighold - gfl_bmp.Height) div 2;
if (deltax > 0) then begin
for y := 0 to gfl_bmp.Height - 1 do begin
lineSrc := Pointer(Integer(gfl_bmp.data) + (y * gfl_bmp.BytesPerLine));
lineDest := bmp.Scanline[y + deltay];
pBytearr := PByteArray(lineDest);
Move(lineSrc^, pBytearr[deltax * 3], gfl_bmp.BytesPerLine);
end
end
else begin
for y := 0 to gfl_bmp.Height - 1 do begin
lineSrc := Pointer(Integer(gfl_bmp.data) + (y * gfl_bmp.BytesPerLine));
lineDest := bmp.Scanline[y + deltay];
move(lineSrc^, lineDest^, gfl_bmp.BytesPerLine);
end
end;
end;
end;
end; {case pixelformat}
-
the xnview property page says:
width 16
height 16
Pixels per inch: ???x ???
Bits per plane: 32
# of planes: 1
color model: RGB
Bits per pixel: 32
Compression: none
# of pages/frames: 1
-
But, the code i use is (shortened):
e := gflLoadThumbnail(PChar(filename), wid, heigh, gfl_bmp, lp, finfo);
//no_planes := finfo.NumberOfPlanes; // that cannot be compiled; so:
no_planes := finfo.ComponentsPerPixel; // returns "4" for the sample bitmap
if (gfl_bmp.Btype = GFL_BINARY) then begin
bpp := 1;
end else begin
bpp := gfl_bmp.BytesPerPixel * 8;
end;
...
bmp.PixelFormat := IntToPixelFormat(bpp); // gives pf24Bit for the sample bitmap
....
case bmp.PixelFormat of
pf24Bit, pf32Bit:
begin
if no_planes < 4 then begin
// ----- original coding from the delphi sample
// ----- does not work well with the sample bitmap
for y := 0 to gfl_bmp.Height - 1 do begin
lineSrc := Pointer(Integer(gfl_bmp.data) + (y * gfl_bmp.BytesPerLine));
lineDest := bmp.Scanline[y];
move(lineSrc^, lineDest^, gfl_bmp.BytesPerLine);
end;
end else begin
// ------- NumberOfPlanes = 4
// ------- used for test; works well with the sample bitmap
pgflbackcolor := @(gflbackcolor);
e := gflGetColorAt(gfl_bmp, 0, 0, pgflbackcolor);
e := gflAutoCrop(gfl_bmp, nil, pgflbackcolor, 32);
if (e <> gfl_no_error) then begin
MessageDlg('Thumbnail gflAutoCrop: ' + string(gflGetErrorString(e)), mtError, [mbOK], 0);
exit;
end;
deltax := (widold - gfl_bmp.Width) div 2;
deltay := (heighold - gfl_bmp.Height) div 2;
if (deltax > 0) then begin
for y := 0 to gfl_bmp.Height - 1 do begin
lineSrc := Pointer(Integer(gfl_bmp.data) + (y * gfl_bmp.BytesPerLine));
lineDest := bmp.Scanline[y + deltay];
pBytearr := PByteArray(lineDest);
Move(lineSrc^, pBytearr[deltax * 3], gfl_bmp.BytesPerLine);
end
end
else begin
for y := 0 to gfl_bmp.Height - 1 do begin
lineSrc := Pointer(Integer(gfl_bmp.data) + (y * gfl_bmp.BytesPerLine));
lineDest := bmp.Scanline[y + deltay];
move(lineSrc^, lineDest^, gfl_bmp.BytesPerLine);
end
end;
end;
end;
end; {case pixelformat}
-
- Author of XnView
- Posts: 44920
- Joined: Mon Oct 13, 2003 7:31 am
- Location: France
Do you have tried with GFL_LOAD_PREVIEW_NO_CANVAS_RESIZE flag?klaus2 wrote:Update about the "crop"-issue:
i fear i did run into the issue only because the receiving bitmap's transparent attribute had not been set So, my fault, in fact i did not need the crop operation in that case.
However, i found that thumbnails for bitmaps with numberOfPlanes = 4 (eg. some bitmaps used for toolbar buttons) are not painted well with the "original code", whereas they look ok with the "modified code". - So, are there any special recommendations for thumbnails for bitmaps with 4 planes?
The "speed issue" (gflLoadThumbnail very slow compared to xnview) is still vaild.
Pierre.
I fear not .. for me it is not significantly dependend on parameters, also not on the coding that (as of the delphi sample) is following the call of gflLoadThumbnail.
For me it is simply this call that is so slow, at least compared with xnview itself processing the same files.
Maybe a static lib instead of a dll would give a speedup ..
I opened a separate thread on the issue (http://newsgroup.xnview.com/viewtopic.php?t=4359)
giving a simplified test case but until now unfortunately there is no feedback.
I'm still hoping i could say that i simply did a mistake
For me it is simply this call that is so slow, at least compared with xnview itself processing the same files.
Maybe a static lib instead of a dll would give a speedup ..
I opened a separate thread on the issue (http://newsgroup.xnview.com/viewtopic.php?t=4359)
giving a simplified test case but until now unfortunately there is no feedback.
I'm still hoping i could say that i simply did a mistake