简体   繁体   English

如何捕获此WPF位图加载异常?

[英]How do I catch this WPF Bitmap loading exception?

I'm developing an application that loads bitmaps off of the web using .NET 3.5 sp1 and C#. 我正在开发一个应用程序,它使用.NET 3.5 sp1和C#从Web加载位图。

The loading code looks like: 加载代码如下:

        try {
            CurrentImage = pics[unChosenPics[index]];
            bi = new BitmapImage(CurrentImage.URI);
            // BitmapImage.UriSource must be in a BeginInit/EndInit block.
            bi.DownloadCompleted += new EventHandler(bi_DownloadCompleted);
            AssessmentImage.Source = bi;
        }
        catch {
            System.Console.WriteLine("Something broke during the read!");
        }

and the code to load on bi_DownloadCompleted is: 并且在bi_DownloadCompleted上加载的代码是:

    void bi_DownloadCompleted(object sender, EventArgs e) {
        try {
            double dpi = 96;
            int width = bi.PixelWidth;
            int height = bi.PixelHeight;

            int stride = width * 4; // 4 bytes per pixel
            byte[] pixelData = new byte[stride * height];
            bi.CopyPixels(pixelData, stride, 0);

            BitmapSource bmpSource = BitmapSource.Create(width, height, dpi, dpi, PixelFormats.Bgra32, null, pixelData, stride);

            AssessmentImage.Source = bmpSource;
            Loading.Visibility = Visibility.Hidden;
            AssessmentImage.Visibility = Visibility.Visible;
        }
        catch {
            System.Console.WriteLine("Exception when viewing bitmap.");
        }
    }

Every so often, an image comes along that breaks the reader. 每隔一段时间,就会出现一个图像,打破了读者。 I guess that's to be expected. 我猜这是可以预料的。 However, rather than being caught by either of those try/catch blocks, the exception is apparently getting thrown outside of where I can handle it. 但是,除了被这些try / catch块中的任何一个捕获之外,异常显然会被抛到我可以处理的地方之外。 I could handle it using global WPF exceptions, like this SO question . 我可以使用全局WPF异常来处理它,比如这个问题 However, that will seriously mess up the control flow of my program, and I'd like to avoid that if at all possible. 但是,这会严重扰乱我程序的控制流程,如果可能的话,我想避免这种情况。

I have to do the double source assignment because it appears that many images are lacking in width/height parameters in the places where the microsoft bitmap loader expects them to be. 我必须进行双源分配,因为在微软位图加载器期望的地方,许多图像似乎缺少宽度/高度参数。 So, the first assignment appears to force the download, and the second assignment gets the dpi/image dimensions happen properly. 因此,第一个分配似乎强制下载,第二个分配使dpi /图像维度正确发生。

What can I do to catch and handle this exception? 我该怎么做才能捕获并处理这个异常?

If you'd like to replicate, try loading this image as the uri: 如果您想要复制,请尝试将此图像加载为uri:

http://i.pbase.com/o2/26/519326/1/123513540.Yub8hciV.Longford12.jpg

The exception itself is: 例外本身是:

System.ArgumentException in PresentationCore
Value does not fall within the expected range.

The inner exception is: 内在的例外是:

An invalid character was found in text context.

Stack trace: 堆栈跟踪:

   at MS.Internal.HRESULT.Check(Int32 hr)
   at System.Windows.Media.Imaging.BitmapFrameDecode.get_ColorContexts()
   at System.Windows.Media.Imaging.BitmapImage.FinalizeCreation()
   at System.Windows.Media.Imaging.BitmapImage.OnDownloadCompleted(Object sender, EventArgs e)
   at System.Windows.Media.UniqueEventHelper.InvokeEvents(Object sender, EventArgs args)
   at System.Windows.Media.Imaging.LateBoundBitmapDecoder.DownloadCallback(Object arg)
   at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Boolean isSingleParameter)
   at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Boolean isSingleParameter, Delegate catchHandler)
   at System.Windows.Threading.DispatcherOperation.InvokeImpl()
   at System.Threading.ExecutionContext.runTryCode(Object userData)
   at System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode code, CleanupCode backoutCode, Object userData)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Windows.Threading.DispatcherOperation.Invoke()
   at System.Windows.Threading.Dispatcher.ProcessQueue()
   at System.Windows.Threading.Dispatcher.WndProcHook(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
   at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
   at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o)
   at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Boolean isSingleParameter)
   at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Boolean isSingleParameter, Delegate catchHandler)
   at System.Windows.Threading.Dispatcher.InvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Boolean isSingleParameter)
   at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam)
   at MS.Win32.UnsafeNativeMethods.DispatchMessage(MSG& msg)
   at System.Windows.Threading.Dispatcher.TranslateAndDispatchMessage(MSG& msg)
   at System.Windows.Threading.Dispatcher.PushFrameImpl(DispatcherFrame frame)
   at System.Windows.Application.RunInternal(Window window)
   at LensComparison.App.Main() in C:\Users\Mark64\Documents\Visual Studio 2008\Projects\LensComparison\LensComparison\obj\Release\App.g.cs:line 48
   at System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args)
   at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Threading.ThreadHelper.ThreadStart()

This exception is the result of 'broken' color profile information contained in the image. 此异常是图像中包含的“损坏”颜色配置文件信息的结果。 If you don't care about this information (or would like to try parsing again after exception), use the BitmapCreateOptions.IgnoreColorProfile flag. 如果您不关心此信息(或者想要在异常后再次尝试解析),请使用BitmapCreateOptions.IgnoreColorProfile标志。

Example: 例:

BitmapImage i = new BitmapImage();
i.BeginInit();
i.CreateOptions |= BitmapCreateOptions.IgnoreColorProfile;
i.UriSource = new Uri(@"http://www.bing.com/fd/hpk2/KiteFestival_EN-US2111991920.jpg");
i.EndInit();

If you're looking for more information, check out Scott Hanselman's post . 如果您正在寻找更多信息,请查看Scott Hanselman的帖子 (We were all in communication about this issue today, via email.) (我们今天通过电子邮件就此问题进行了沟通。)

This seems to work: 这似乎有效:

try
{
    frame = BitmapFrame.Create(new Uri("http://i.pbase.com/o2/26/519326/1/123513540.Yub8hciV.Longford12.jpg"));
}
catch
{
    return;
}

BitmapFrame has a DecodeFailed event, but I'm not able to hook it because the BitmapFrame is frozen after it's created. BitmapFrame有一个DecodeFailed事件,但我无法挂钩它,因为BitmapFrame在创建后被冻结。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM