# Saving images fast enough

**URL:** <https://forum.commonvisionblox.com/t/saving-images-fast-enough/836>\
**Category:** Programming Questions\
**Tags:** acquisition, net\
**Created:** [July 22, 2019, 12:42pm UTC](https://forum.commonvisionblox.com/t/saving-images-fast-enough/836 "2019-07-22T12:42:39Z")\
**Posts on this page:** 15\
**Page:** 1

<div class="post-metadata">

**Author:** ![CvK](https://yyz1.discourse-cdn.com/flex027/user_avatar/forum.commonvisionblox.com/cvk/32/112_2.png) [@CvK](https://forum.commonvisionblox.com/u/CvK)\
**Post date:** [July 22, 2019, 12:42pm UTC](https://forum.commonvisionblox.com/t/saving-images-fast-enough/836/1 "2019-07-22T12:42:39Z")

</div>

I’m starting out with tasks and the .net bindings, so not sure if this is my own code being messy or something else alltogether.

The code below works just fine with .jpg extention, but with png it gets very weird. With the jpg extention there timestamps are spot on, and I get a nice file with 100 images. With .png extention, not so much. I don’t fully understand why that should be the case to be honest. I aquire the images at 5 herz, and they are 5mp rgb images.

Saving an png itself takes about 2-3 seconds, seems like a lot, but turning them into threads should resolve that (meaning there would be about 3\*5 images max being saved at any given time).

```auto
namespace ConsoleApplication2
{
  class Program
  {
    static void Main(string[] args)
    {
      Device firstDevice = DeviceFactory.Open("Genicam.vin");
      firstDevice.Stream.Start();

      try
      {
        for (int i = 0; i < 100; i++)
        {
          using (StreamImage image = firstDevice.Stream.Wait()) 
          {
            var cloneIMG = image.Clone();
            Task t = Task.Run(() => asyncSaveImage(cloneIMG));
          }
        }
      }
      catch (Exception)
      {
        throw;
      }
    }

    private static void asyncSaveImage(Image image)
    {
      var location = string.Format(@"C:\LOG\{0:yyyy/MM/dd HH-mm-ss-fff}.png", DateTime.Now);
      image.Save(location);
    }
  }
}
```

---

<div class="post-metadata">

**Author:** ![illusive](https://yyz1.discourse-cdn.com/flex027/user_avatar/forum.commonvisionblox.com/illusive/32/61_2.png) [@illusive](https://forum.commonvisionblox.com/u/illusive)\
**Post date:** [July 22, 2019, 4:02pm UTC](https://forum.commonvisionblox.com/t/saving-images-fast-enough/836/2 "2019-07-22T16:02:30Z")

</div>

Hi @CvK!

You might be interested in this post:  
[https://forum.commonvisionblox.com/t/different-performance-when-saving-different-formats/252](https://forum.commonvisionblox.com/t/different-performance-when-saving-different-formats/252)

---

<div class="post-metadata">

**Author:** ![CvK](https://yyz1.discourse-cdn.com/flex027/user_avatar/forum.commonvisionblox.com/cvk/32/112_2.png) [@CvK](https://forum.commonvisionblox.com/u/CvK)\
**Post date:** [July 23, 2019, 7:45am UTC](https://forum.commonvisionblox.com/t/saving-images-fast-enough/836/3 "2019-07-23T07:45:23Z")

</div>

Hi @illusive,

Had allready found that, but it doesnt completely answer my question though. If I hand over the save task to threads, it shouldn’t matter all that much in overall speed how quickly I am able to save right? It will only result in perhaps a lot of tasks being active at any given moment.

Instead, I see little to no gain by handing it over to tasks. Which is unexpected for me.

---

<div class="post-metadata">

**Author:** ![Chris](https://yyz1.discourse-cdn.com/flex027/user_avatar/forum.commonvisionblox.com/chris/32/1154_2.png) [@Chris](https://forum.commonvisionblox.com/u/Chris)\
**Post date:** [July 23, 2019, 12:28pm UTC](https://forum.commonvisionblox.com/t/saving-images-fast-enough/836/4 "2019-07-23T12:28:03Z")

</div>

Offtopic:

just a little hint:

```cs
DateTime.Now.ToString("yyyy_MM_dd_HHmmss")

```

Cheers  
Chris

---

<div class="post-metadata">

**Author:** ![Chris](https://yyz1.discourse-cdn.com/flex027/user_avatar/forum.commonvisionblox.com/chris/32/1154_2.png) [@Chris](https://forum.commonvisionblox.com/u/Chris)\
**Post date:** [July 23, 2019, 12:36pm UTC](https://forum.commonvisionblox.com/t/saving-images-fast-enough/836/5 "2019-07-23T12:36:51Z")

</div>

Hi @CvK,

handing over the process of saving the images to tasks will increase the speed of your application as you will not be “stuck” for 2-3 seconds everytime you try to save an image.  
Instead you simply have x Tasks that are writing images to the disk while already sending off new tasks.  
I dont see why this should increase the speed of one save process… you simply are able to acquire new images faster.

(If I dont miss anything right now).

Cheers  
Chris

---

<div class="post-metadata">

**Author:** ![CvK](https://yyz1.discourse-cdn.com/flex027/user_avatar/forum.commonvisionblox.com/cvk/32/112_2.png) [@CvK](https://forum.commonvisionblox.com/u/CvK)\
**Post date:** [July 23, 2019, 12:48pm UTC](https://forum.commonvisionblox.com/t/saving-images-fast-enough/836/6 "2019-07-23T12:48:56Z")

</div>

Hmm, well, thats the weird thing! When writing png, only 16 images of my 100 images are actually sucesfully stored @ 5 herz acquisition.

edit: it was 8-9 images saved, the result of 16 was from 2 runs.

---

<div class="post-metadata">

**Author:** ![Chris](https://yyz1.discourse-cdn.com/flex027/user_avatar/forum.commonvisionblox.com/chris/32/1154_2.png) [@Chris](https://forum.commonvisionblox.com/u/Chris)\
**Post date:** [July 23, 2019, 1:02pm UTC](https://forum.commonvisionblox.com/t/saving-images-fast-enough/836/7 "2019-07-23T13:02:45Z")

</div>

Just out of curiosity… have you tried increasing the NumBuffers?  
I am not sure if this changes anything but it would be interesting.  
Just go for 100 Buffers.

---

<div class="post-metadata">

**Author:** ![TStadler](https://yyz1.discourse-cdn.com/flex027/user_avatar/forum.commonvisionblox.com/tstadler/32/308_2.png) [@TStadler](https://forum.commonvisionblox.com/u/TStadler)\
**Post date:** [July 24, 2019, 6:34am UTC](https://forum.commonvisionblox.com/t/saving-images-fast-enough/836/8 "2019-07-24T06:34:08Z")

</div>

You could also record the 100 images with RingBuffer LockMode = On (You need minimum 100 buffers for that) and then safe after the images are recorded, which, I would say, is the correct way of handling situations where youre recording faster than youre writing images

---

<div class="post-metadata">

**Author:** ![CvK](https://yyz1.discourse-cdn.com/flex027/user_avatar/forum.commonvisionblox.com/cvk/32/112_2.png) [@CvK](https://forum.commonvisionblox.com/u/CvK)\
**Post date:** [July 24, 2019, 6:59am UTC](https://forum.commonvisionblox.com/t/saving-images-fast-enough/836/9 "2019-07-24T06:59:24Z")

</div>

I clone the image, and then save it and hand it over to a task. This should not be influenced by the number of ringbuffers right?

I’ve gotten this to work using the tobitmap example in the past in the c-style API so I know this isn’t a doomed approach.

Edit:  
Just tried it with 100 buffers, no effect whatsoever ☹ exact same results as before. Not locked, though, but the weird behavior of the saving still exists… Why isn’t the saving improbed by handing it over to tasks as I expect?

---

<div class="post-metadata">

**Author:** ![Chris](https://yyz1.discourse-cdn.com/flex027/user_avatar/forum.commonvisionblox.com/chris/32/1154_2.png) [@Chris](https://forum.commonvisionblox.com/u/Chris)\
**Post date:** [July 24, 2019, 8:06am UTC](https://forum.commonvisionblox.com/t/saving-images-fast-enough/836/10 "2019-07-24T08:06:13Z")

</div>

One last approach:

I am not sure, what happens to the fired tasks if you hit the end of your main. I would assume they will very likely just be lost.

You could make your Save() method async (as the name already implies), create a list of tasks and wait for each element of that list to have finished bevore leaving the programm.

> <https://stackoverflow.com/questions/19849847/use-task-waitall-to-handle-awaited-tasks>

Also interesting:

> <https://stackoverflow.com/questions/17119075/do-you-have-to-put-task-run-in-a-method-to-make-it-async>

---

<div class="post-metadata">

**Author:** ![CvK](https://yyz1.discourse-cdn.com/flex027/user_avatar/forum.commonvisionblox.com/cvk/32/112_2.png) [@CvK](https://forum.commonvisionblox.com/u/CvK)\
**Post date:** [July 24, 2019, 8:07am UTC](https://forum.commonvisionblox.com/t/saving-images-fast-enough/836/11 "2019-07-24T08:07:48Z")

</div>

Hmm, right! that makes sense. I shall attempt it 🙂

---

<div class="post-metadata">

**Author:** ![illusive](https://yyz1.discourse-cdn.com/flex027/user_avatar/forum.commonvisionblox.com/illusive/32/61_2.png) [@illusive](https://forum.commonvisionblox.com/u/illusive)\
**Post date:** [July 24, 2019, 8:45am UTC](https://forum.commonvisionblox.com/t/saving-images-fast-enough/836/12 "2019-07-24T08:45:51Z")

</div>

There is one general warning, that I would like to post here: There is no guarantee that multi threaded saving of images will generally work for all formats. With \*.bmp and \*.mio I am fairly confident (and if you find that it fails this would qualify as a bug in my opinion), but all the other formats are handled through the open source libraries mentioned [here](https://help.commonvisionblox.com/NextGen/OpenSourceLicenses.pdf) (namely [jasper](https://www.ece.uvic.ca/~frodo/jasper/), [libjpg](http://www.ijg.org/), [libpng](http://www.libpng.org/pub/png/libpng.html), [libtiff](http://www.simplesystems.org/libtiff/), [openjpeg](http://www.openjpeg.org/)) and as far as I know not all of them make thread-safety guarantees…

With \*.png files you’re lucky 🍀 insofar as the libpng documentation says “_Libpng is thread safe, provided the threads are using different instances of the structures._”. The latter condition is satisfied in :cvb: so you should be fine. But I assume using your approach with e.g. \*.jpg files would cause issues.

---

<div class="post-metadata">

**Author:** ![CvK](https://yyz1.discourse-cdn.com/flex027/user_avatar/forum.commonvisionblox.com/cvk/32/112_2.png) [@CvK](https://forum.commonvisionblox.com/u/CvK)\
**Post date:** [July 24, 2019, 8:57am UTC](https://forum.commonvisionblox.com/t/saving-images-fast-enough/836/13 "2019-07-24T08:57:16Z")

</div>

The .png is the one causing issues actually. But, that might be caused by the fact that the .jpg saving is actually faster and doesn’t really need the parallelization.

I’ll try some of the suggestions here and post my findings back here. I’m probably not going to be the last one trying to save images after all 😉

---

<div class="post-metadata">

**Author:** ![illusive](https://yyz1.discourse-cdn.com/flex027/user_avatar/forum.commonvisionblox.com/illusive/32/61_2.png) [@illusive](https://forum.commonvisionblox.com/u/illusive)\
**Post date:** [July 24, 2019, 8:58am UTC](https://forum.commonvisionblox.com/t/saving-images-fast-enough/836/14 "2019-07-24T08:58:53Z")

</div>

👍  
(with issues I meant symptoms far worse than what you describe like `SEHException`s and its siblings…)

---

<div class="post-metadata">

**Author:** ![CvK](https://yyz1.discourse-cdn.com/flex027/user_avatar/forum.commonvisionblox.com/cvk/32/112_2.png) [@CvK](https://forum.commonvisionblox.com/u/CvK)\
**Post date:** [July 24, 2019, 9:00am UTC](https://forum.commonvisionblox.com/t/saving-images-fast-enough/836/15 "2019-07-24T09:00:00Z")

</div>

Right, none of that so far, lets hope they don’t suddenly pop up! 🤞
