I have a method that opens a FileStream
and creates a BitmapImage
, by using the StreamSource
property.
Somehow, in a single machine, trying to open a big image (6000x4000px) results in the method returning a 1x1px image instead.
First I thought that the image was being loaded from a shared folder on the local network, but It was stored in the downloads folder of the same computer.
I saw that the image was "blocked/locked" by Windows because it was downloaded from an unverified source, so I opened Properties and unlocked it. Trying to load the image again resulted in the same problem.
The image was fully downloaded.
Background information:
The machine with the problem:
- Windows 7 SP1.
- 32 bits.
- Net Framework 4.6.2.
- 4GB of memory, with 2.5GB being used.
My machine (it works as expected):
- Windows 10, build 15063.413.
- 64 bits.
- Net Framework 4.7.
- 8GB of memory, with 6GB being used.
Code:
public static BitmapSource SourceFrom(this string fileSource, int? size = null)
{
using (var stream = new FileStream(fileSource, FileMode.Open, FileAccess.Read))
{
var bitmapImage = new BitmapImage();
bitmapImage.BeginInit();
bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
if (size.HasValue)
{
//It's not possible to get the size of image while opening, so get from another place.
var refSize = fileSource.ScaledSize(); //Gets the size of the image.
if (refSize.Height > refSize.Width)
bitmapImage.DecodePixelHeight = size.Value;
else
bitmapImage.DecodePixelWidth = size.Value;
}
bitmapImage.StreamSource = stream;
bitmapImage.EndInit();
bitmapImage.Freeze(); //Just in case you want to load the image in another thread.
return bitmapImage;
}
}
Usage:
var image = "C:\Image.jpg".SourceFrom(); //Without any other parameter.
Question:
- Is there any case that my code is not treating properly, at least that explains why I'm getting a 1x1px image instead of the full size one?
- Also, why it does not throw an
Exception
if it can't load the image?
Probable answer:
- My code does not handle if the image finished downloading or not, but the image was fully downloaded, so I'm not sure if this is the case. I've found a similar thread about the same problem.
Working code:
using (var stream = new FileStream(fileSource, FileMode.Open, FileAccess.Read))
{
using (var memory = new MemoryStream())
{
stream.CopyTo(memory);
memory.Position = 0;
//...
Just replace this part of the code and use the memory
variable instead of stream
while setting the StreamSource
object.