I'm running into a strange problem when loading BitmapImages from a URI, passing them through a CroppedBitmap and encoding / saving to an image in memory via a MemoryStream.
Code below:
System.Windows.Media.Imaging.BitmapImage bi = new System.Windows.Media.Imaging.BitmapImage(); bi.BeginInit(); // The BitmapCacheOption seems to be the source of the problem - // Setting it to OnLoad removes the issue but performance is 3-4x slower bi.CacheOption = System.Windows.Media.Imaging.BitmapCacheOption.None; bi.UriSource = new Uri(inputFile); bi.DecodePixelWidth = (int)imageViewBox[10]; bi.DecodePixelHeight = (int)imageViewBox[11]; bi.EndInit(); System.Windows.Media.Imaging.CroppedBitmap cbi = new System.Windows.Media.Imaging.CroppedBitmap(bi, new System.Windows.Int32Rect( (int)(imageViewBox[2] * imageViewBox[10]), (int)(imageViewBox[3] * imageViewBox[11]), (int)((imageViewBox[4] - imageViewBox[2]) * imageViewBox[10]), (int)((imageViewBox[5] - imageViewBox[3]) * imageViewBox[11]))); newImageSize = new Size(cbi.PixelWidth, cbi.PixelHeight); using (MemoryStream msOut = new MemoryStream()) { System.Windows.Media.Imaging.BmpBitmapEncoder enc = new System.Windows.Media.Imaging.BmpBitmapEncoder(); enc.Frames.Add(System.Windows.Media.Imaging.BitmapFrame.Create(cbi)); // Throws access violation exception intermittently when zoomed on some images enc.Save(msOut);
As commented in the code, the enc.Save line throws an AccessViolation exception intermittently (usually on larger images at 2 x zoom) when the BitmapCacheOption is set to None. Setting it to OnLoad resolves the issue. However, this is a performance critical part of the application, and OnLoad seems to hit performance by 3-400% which is not workable.
Even stranger, sometimes an exception is not thrown, and the image returned has regular vertical fault lines in it, as if it was missing a vertical line of pixels every n rows. Those missing pixels then get moved to the right hand of the image in a "compressed" mini-image!
Can anyone shed light on what might be happening here? I've tried using an OnDownload event handler, but it never seems to fire, and have tried testing for IsDownloading before proceeding with the rest of the method but it always returns false which seems to suggest that fully loading the image is not the issue here.