4

I see a weird behavior of an image.

I have two methods wich calculate a heatmap image. one method works in the GUI thread, and the other one in a background thread. Both methods should be the same and the output as an png seems to be good. The GUI thread created image is able to loaded in, but the created one from the background thread not.

I save the calculated image as file on my hard drive and load it in again. When I load it and assign it to the image source it is not null. But when the programm leaves the allocating method the image.source is null. I don't understand why.

This is the code:

private void LoadImageClicked(object sender, RoutedEventArgs e)
{
    this.ImageHeatMap.BeginInit();
    this.ImageHeatMap.Source = new BitmapImage(new Uri(@"HeatMapImage.png", UriKind.Relative));
    this.ImageHeatMap.EndInit();
}

and this his how I save the image as png:

public void SaveFile(BitmapSource source, string filePath)
{
    using (var fileStream = new FileStream(filePath, FileMode.Create))
    {
        BitmapEncoder encoder = new PngBitmapEncoder();
        encoder.Frames.Add(BitmapFrame.Create(source));
        encoder.Save(fileStream);
    }
}

Interesting is that I can not view the Image.Source.Height property in debug mode. but with the working file I am able to read this property. Debug looks like this:

Debug of Image.Source assignment

Error message in english (free translated): "this.Image:heatMap.Source.Height" has thrown an exception of type "System.IO.IOException"

Is somebody able to help me understanding where is the problem? Because I don't understand why I can't load the image. I am able to open it via the Windows picture viewer.

I think the problem is the metadata but I don't know - at the moment - how to fix it.

Mogsdad
  • 44,709
  • 21
  • 151
  • 275
Jens
  • 2,592
  • 2
  • 21
  • 41
  • GUI thread and Background thread both use the same Save-Method? – DJmRek Jun 17 '15 at 09:22
  • Yes. But the one with the GUI thread works but the background one not. I fixed it with a little hack / workaround but it would be nice to know why there is a difference – Jens Jun 17 '15 at 09:26
  • So i tried a few scenarios and only can reproduce your errors for Height, Width, Metadata, if the file called by the Uri don't exist at the programs folder. Have you tried an absolute Uri? Und es wär schön wenn man wüsste was dein `ImageHeatMap` Object bei `BeginInit` und `EndInit` macht ;) – DJmRek Jun 17 '15 at 12:30
  • Begin and EndInit makes no difference. You can also leave it out. I only have tried with Relative Source – Jens Jun 17 '15 at 12:40
  • Could you try an absolute path? But anyway Source as propertie shouldn't turn to null after leaving the method. In my testscenario it isn't null even with IOExceptions in Height etc. Is it already null if you jump to the closing braket in debug? or later when you call it? – DJmRek Jun 17 '15 at 13:06
  • 1
    You can't modify GUI elements from other threads than the UI thread. You'll have to use `Invoke` for any such manipulation from another thread. – Luaan Jun 17 '15 at 13:47
  • @Luaan thats right. but i do not need that in my case. – Jens Jun 17 '15 at 13:54
  • @Luaan when I want to access image.Height I get of course a "thread is not the owner exception" – Jens Jun 18 '15 at 09:56
  • Down voted for lack of interaction on the answers. I don't believe Jens Horstmann is exploring the answers/comments earnestly. – Jason Geiger Aug 10 '15 at 14:05
  • possible duplicate of [Why does Image.FromFile keep a file handle open sometimes?](http://stackoverflow.com/questions/788335/why-does-image-fromfile-keep-a-file-handle-open-sometimes) – Mogsdad Aug 26 '15 at 04:09

1 Answers1

-2

When it comes to images objects in .Net I have found the need to force it to disposed. Using the .Dispose() method of any class that manipulates the image was enough to release it's hold on the file. You would think that closing the Stream would force this release but it does not.

Here is a related post that explains what I was saying further.

Why does Image.FromFile keep a file handle open sometimes?

miken32
  • 42,008
  • 16
  • 111
  • 154
Jason Geiger
  • 1,912
  • 18
  • 32
  • Uhm, what? i do not want to dispose my image. – Jens Aug 05 '15 at 16:13
  • I don't think you understand what dispose does. After Encoder.Save(...) you would call Encoder.Dispose() so the resources are returned to the system and that it doesn't lock the file. – Jason Geiger Aug 05 '15 at 20:35
  • you don't understand my question / problem. i know what dispose does and i also know how to use it -- so whyever should you call dispose? it is much better coding to use the using block. So why should your solution help me? My image is null after assignment. why should a Dispose help me? if i dispose it, it is null anyway. Where is the sense? – Jens Aug 10 '15 at 14:57
  • My problem also exists when i won't open it over an file. when i ceep the image the whole time in memory the problem also exists. this can't be a problem with file handle and / or dispose. your answer has no value to my question... – Jens Aug 10 '15 at 15:02
  • Just try this... After you save the image with this... "encoder.Save(fileStream);" add another line of code "encoder.Dispose();" The file will not be deleted, the "encoder" object will be removed from memory. Normally you don't have do this kind of thing because of .Net's garbage collection. However you do have to do this when you work with Images and such. – Jason Geiger Aug 10 '15 at 18:37