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

标签 c# wpf exception download bitmap

我正在开发一个使用 .NET 3.5 sp1 和 C# 从 Web 加载位图的应用程序。

加载代码如下:

        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!");
        }

加载 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.");
        }
    }

每隔一段时间,就会出现一张让读者崩溃的图片。我想这是可以预料的。但是,异常并没有被这些 try/catch block 中的任何一个捕获,而是被抛出了我可以处理的范围之外。我可以使用全局 WPF 异常来处理它,比如 this SO question .但是,这会严重扰乱我的程序的控制流,我希望尽可能避免这种情况。

我必须进行双源分配,因为在 Microsoft 位图加载程序期望的位置,许多图像似乎缺少宽度/高度参数。因此,第一个任务似乎强制下载,而第二个任务使 dpi/图像尺寸正确发生。

我该怎么做才能捕获并处理这个异常?

如果您想复制,请尝试将此图像作为 uri 加载:

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

异常本身是:

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

内部异常是:

An invalid character was found in text context.

堆栈跟踪:

   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()

最佳答案

此异常是图像中包含的“损坏”颜色配置文件信息的结果。如果您不关心此信息(或想在异常后再次尝试解析),请使用 BitmapCreateOptions.IgnoreColorProfile 标志。

例子:

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();

如果您正在寻找更多信息,请查看 Scott Hanselman's post . (我们今天都通过电子邮件就此问题进行了沟通。)

关于c# - 如何捕获此 WPF 位图加载异常?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2732140/

相关文章:

c# - 我应该如何在编译时不知道类型的情况下调用泛型函数?

c# - 同时进行两个异步调用后的 WCF 问题

c# - 如何在 C# 中捕获包含匿名方法的 Action 的异常?

c# - 导出到 excel 抛出 System.OutOfMemoryException

c# - 让 gtk# 应用程序在 Windows 上运行的最简单方法

c# - 如何使用 XSLT 将 Richtext 图像从标准 WPF RichTextBox 转换为 HTML?

WPF MVVM - 异步使用 Web 服务的正确方法

c# - 使用 WindowsXamlHost Overlay 托管 CaptureElement

c# - ExecuteNonQuery() 异常未被 try-catch 捕获

c++ - 处理来自 DLL 的异常