Lipko Posted August 25, 2021 Report Share Posted August 25, 2021 (edited) Hi all! I have an picture organizer application where there is a picture list, pictures can be selected and there is a full resolution preview indicator for the selected picture. Since image sizes are quite large, the picture is loaded from the image file for the full resolution preview generation (the pictures and the indicator are too large to pre-cache). Simply loading the picture in the GUI input thread slows the GUI down significantly. For this reason, I would place the file loading in a background thread, but I can't find a way to cancel image loading (the user clicked on another picture before the file read is finished), or a workaround this problem. The best I came up yet is to have a parallel while loop with the input event loop, and load the image if the requested image path is not equal to the image path that's currently loading. I'd poll the paths for that but mixing polling with events give me mixed feelings. At worst case, this method would roughly double the preview generation time if the user clicks around quickly (the first clicked image is fully loading, but another picture should be loaded so that will be loaded AFTER the first finished). This is much better than I have now (the user quicly clicks on pictures then has to sit out the preview "slideshow"). Maybe having two parallel loops would solve the double load time issue, but I have a feeling that this direction is very very fishy (starting a flie read in a parallel thread while a file reading is still happening. Maybe it would slow both image loading times). Having a way to stop image loading would be the best, I don't know if there's a method or 3rd party library for that. I can imagine the image (jpg for example) could be loaded as raw data in chunks, but how to generate the jpg from that raw data? I'm not even sure jpg file reading is simple as that. Thanks for any hints in advance! Edited August 25, 2021 by Lipko Quote Link to comment
dadreamer Posted August 25, 2021 Report Share Posted August 25, 2021 1 hour ago, Lipko said: I can imagine the image (jpg for example) could be loaded as raw data in chunks, but how to generate the jpg from that raw data? I'm not even sure jpg file reading is simple as that. You could probably take a look at this: https://forums.ni.com/t5/Machine-Vision/Convert-JPEG-image-in-memory-to-Imaq-Image/m-p/3786705#M51129 For PNGs there are already native PNG Data to LV Image VI and LV Image to PNG Data VI. 1 Quote Link to comment
Lipko Posted August 26, 2021 Author Report Share Posted August 26, 2021 14 hours ago, dadreamer said: You could probably take a look at this: https://forums.ni.com/t5/Machine-Vision/Convert-JPEG-image-in-memory-to-Imaq-Image/m-p/3786705#M51129 For PNGs there are already native PNG Data to LV Image VI and LV Image to PNG Data VI. Thank you, that's exactly what I was looking for. I'll come back when I'll have time to implement this. If someone is into spagetti. Quote Link to comment
Lipko Posted August 27, 2021 Author Report Share Posted August 27, 2021 A related thing: I noticed that the "read JPEG file.vi" (the native one) runs in GUI thread. Is it an expected behaviour, is it the same with any file loading in Windows or am i doing something wrong? I narrowed down this GUI thread problem to "read JPEG.vi" (I replaced it with a simple 5 second wait). It is clear that the read causes the loop run in the GUI thread: with jpg read the main GUI freezes at every jpg load, with dummy wait, the main GUI is responsive without any hiccups. The read jpg is burred in subVIs, so it's not that the prioritry or preferred execution system are set up wrong for the subVIs. Quote Link to comment
Lipko Posted August 27, 2021 Author Report Share Posted August 27, 2021 16 minutes ago, Lipko said: A related thing: I noticed that the "read JPEG file.vi" (the native one) runs in GUI thread. Is it an expected behaviour, is it the same with any file loading in Windows or am i doing something wrong? I narrowed down this GUI thread problem to "read JPEG.vi" (I replaced it with a simple 5 second wait). It is clear that the read causes the loop run in the GUI thread: with jpg read the main GUI freezes at every jpg load, with dummy wait, the main GUI is responsive without any hiccups. The read jpg is burred in subVIs, so it's not that the prioritry or preferred execution system are set up wrong for the subVIs. Never mind. I've just tried the Decode Image Stream thing, and it doesn1t halt the main GUI, it runs like a charm. But seems to be slower than the native read JPG. I guess that's the prize of a responsive GUI. Thanks again! Quote Link to comment
dadreamer Posted August 27, 2021 Report Share Posted August 27, 2021 (edited) 8 hours ago, Lipko said: Is it an expected behaviour, is it the same with any file loading in Windows or am i doing something wrong? It's just that NI designed those JPEGToLVImageDataPreflight and JPEGToLVImageData functions to run in UI thread. I don't know whether it's safe to set the CLFNs to "Run in any thread" and use it, because we don't have the sources. You could test it on your own and see. But it's known that most of WinAPI functions are reentrant, thus you may freely use WIC or GDI+ from multiple threads simultaneously. So, to re-invent JPEG reading VI with WIC this thread could be a starting point (along with Decode Image Stream VI diagram as an example). For GDI+ this thread becomes useful, but this way requires writing a small DLL to use GDI classes. I don't recommend using .NET nodes in LabVIEW here, as the execution speed is that important for you. Edited August 27, 2021 by dadreamer Quote Link to comment
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.