I’m writing a desktop application which displays images in a listbox.
Since my images are very large, I’m trying to cache them in a sqlite database.
The cachingprocess was very slow, so I wanted to put the caching process inside of workers.
For the resizing of the images, I created a method which I put into a Module named WorkerHelper.
I put the name of the module into the “Project Items To Include” field of the worker.
When I’m trying to run the worker, it does absolutely nothing.
Since there was no hint at all what went wrong, I included an Exception at the end of the “JobRun” Event handler.
Now I knew, that the event handler tried to acces a Nil object.
After some more digging I found out, that the method I’m using to resize the images, was not running at all.
Now my question:
Is there a limitation within a worker to run methods of the module I included in the “Project Items To Include”?
Do I have to put all my code inside of the event handler “jobRun” or am I able to use methods?
Your code does not have to be self-contained in JobRun.
The two example projects demonstrate calling code in classes from the JobRun event of the Worker.
I don’t often visit here anymore, but I saw your post yesterday and decided that I’d like to try to help. Especially as you remind myself of me when I was trying to do similar things in Xojo.
First of all, Xojo is not a great tool for this kind of job, lemme explain why.
-
Xojo does not natively support OS functions for reading image thumbnails/previews. I have written code for the Mac that will utilize the OS support, but because of limitations in Xojo’s framework (that they don’t want to address) it can’t be as efficient as other tools.
-
Xojo’s listbox does not support lazy loading, you can fashion a sort of thing, but that comes with redraw penalties. With lazy loading, you app would only load the previews that it actually needs, when it needs it.
-
Xojo’s listbox is from the 1990s and each update redraws everything you see, the more you draw the slower it gets. Modern tools use clever caching tricks directly on the GPU, making this super slick and smooth.
-
Xojo’s concurrency is terrible for this sort of thing. Workers are separate processes, which means without performance degrading serialization you can’t get a worker to load the preview and pass it back to the main thread. Not only that, I also found that the controller for Xojo’s workers has a performance leak and on top of that, can’t shunt tasks like these to the efficiency cores of modern computers.
As part of my AppKit (which wasn’t worth the conversion to API 2.0), there is the code for utilizing the built-in functions on the macOS to load thumbnails. This will help improve the performance of trying to do this with Xojo, reach out to me on Twitter https://twitter.com/Sam_Ohanaware if you’re interested in me stripping this code out and sharing it with you.
No I managed it to get the worker to do what I want.
The example project was not helpful at all.
Unfortunetely my method “createThumbnails” is not able to create thumbnails of .arw files when it’s running in worker mode.
With jpg files is working fine, when using this method within a thread it’s also working fine for .arw files.
I tried the PictureResizer-Sample on Windows and it worked perfectly. With 4 workers the resizing of pictures was done about 4 times faster, pretty impressive and straighforward example, i think.
Did you resize .arw files?
No, i used JPG-files. You .arw only then? These are Sony RAW files, right? Xojo does not support RAW-files natively, i think.
That’s the thing, my method is working fine on .arw when it’s running inside the desktop app.
I guess the worker has no access to the raw converter.
I wouldn’t need the worker for the thumbnails if I would only work with jpegs.
My files are about 75 mb each.
The Graphics class in Console apps is different from that of Desktop apps. Helpers are just some pre-written wrappers around Console apps. At one point that was documented somewhere.
2 Likes
What if I write me a helper app and call it from a thread?
Is there a replacement for folderitem.launch?
Can I run an external application with a parameter?
You would have to write a Desktop application to use the Desktop version of the Graphics class. This is doable, and on macOS you can hide the application from the dock like this:
NSApplicationMBS.activationPolicy = NSApplicationMBS.NSApplicationActivationPolicyAccessory
I do not have the declare handy. I seem to recall that Apple does not want developers using the LSUIElement Info.plist property but I can’t find documentation to that effect.
Call the helper app using Shell.
Yes, if you use Shell you can pass arguments. You can use System.CommandLine to gather the passed arguments.
1 Like
Here is my IDE script to hide a helper app:
dim dbg as String
if debugBuild then dbg = ".debug"
dim appNameForShell as string
appNameForShell = PropertyValue("App.MacOSXAppName") + dbg +".app" + "/Contents/Info.plist"
appNameForShell = replaceall(appNameForShell, " ", "\ ")
dim theResult as string
theResult = DoShellCommand("/usr/libexec/PlistBuddy -c ""Add :NSUIElement string \""true\"""" " + CurrentBuildLocation + "/" + appNameForShell )
if theResult <> "" then print theResult
I think I tried to replace the script with MBS functionality. But I don’t remember why it didn’t work. Did the Dock icon flash? Something like that.
1 Like
You could also try using dcraw
via shell and extract the thumbnail of .arw-files directly, should work much faster, no scaling needed.
In the terminal (may brew needs to be installed)
brew install dcraw
Extracting embedded jpg-thumbnail in Terminal:
dcraw -e <path to arw file>
wow that’s a lot of help, here.
Thanks a lot for that.