Is there any way to import only the thumbnail of an image instead of the full image? I frequently work with lots of images and it would be nice if the contents of a directory could be quickly displayed as small images, without loading the full image. On my machine (2 x 2.4Ghz, 2GB ram, Win7, Mathematica 8), loading 12 images (PNG, 1200x900, 45KB each) takes ~1.4 sec, which is a bit too much for delay.
2 Answers
In Mathematica 8, few image files are supported natively--meaning, without calling external MathLink executables, which results in much faster speed (order of magnitude) and great efficiency in memory usage. Currently only TIFF and JPEG work that way. PNG was close but it was cut-off. What I am saying is that you will see much speed up in the future for PNG reading/writing.
Now, I hate to say this, but with M8, there is not much thing to do to improve the speed of PNG (unless you are willing to venture and call libpng directly using
LibraryLink
. Probably out of bound for most users...).Again, current
Import
does not support thumbnail read from image files (maybe we should). I am not sure PNG has its own embedded thumbnail (I think it has... sure for JPEG). So it is no go either...The Windows system uses Thumbs.db to store "pregenerated" thumbnails. But again, M- can't utilize these files except in system dialog boxes (like
SystemDialogInput["FileOpen"]
). It is in fact quite tricky to handle this DB so I don't think that the support will happen at all.If you expect your code to access folders frequently, it won't be bad idea to maintain its own thumbnail database using
Thumbnail
function (which is quite fast). Possibly some hidden folder with miniaturized images for future use, or some specialized DB file (a notebook orDumpSave
). But, yes, it is quite involving... I have to say.
Sorry, no good answer.
Here's a humble quick shot from a beginner in .NET
. Hope you use Windows, and I'd appreciate comments. Perhaps it isn't even faster. Here goes
Needs["NETLink`"];
LoadNETType["System.Drawing.Image"];
LoadNETType["System.Drawing.Imaging.ImageFormat"];
LoadNETType["System.IntPtr"];
LoadNETType["System.Windows.Forms.Form"];
LoadNETType["System.Windows.Forms.FormBorderStyle"];
LoadNETType["System.Windows.Forms.ImageLayout"];
Module[{tmpDirName = "myThumbnails", tmpDir, del},
tmpDir = FileNameJoin[{$TemporaryDirectory, tmpDirName}];
Quiet@CreateDirectory[tmpDir];
del = NETNewDelegate["System.Drawing.Image+GetThumbnailImageAbort",
Null &];
createThumbnail[filename_String, {width_, height_}] :=
NETBlock[(Image`FromFile[filename])@
GetThumbnailImage[width, height, del, IntPtr`Zero]];
previewThumbnail[netobject_] := Module[{frm},
frm = NETNew["System.Windows.Forms.Form"];
frm@Height = netobject@Height + 40; frm@Width = netobject@Width;
frm@FormBorderStyle = FormBorderStyle`FixedDialog;
frm@BackgroundImageLayout = ImageLayout`Center;
frm@BackgroundImage = netobject;
ShowNETWindow[frm]];
getThumbnail[netobject_] :=
With[{fn = FileNameJoin[{tmpDir, "tmp.bmp"}]},
netobject@Save[fn, ImageFormat`Bmp];
Import[fn]
]
];
Usage:
thumb = createThumbnail[
imagePath, \
{100, 80}];
Now, previewThumbnail[thumb]
shows a little window with the thumbnail and getThumbnail[thumb]
loads it into Mathematica
-
$\begingroup$ Oh, good, I never used .NET to hook up with Windows before! This works nicely, will report back on how it behaves with lots of imagefiles required to be preloaded. $\endgroup$ Commented Mar 27, 2012 at 11:03