为什么 WPF 的 BitmapImage 对象在 ASP.Net Web Forms 中不能从 Uri Source 下载图像?

3
我正在ASP.Net中尝试实现以下功能:
  1. 创建一个WPF Canvas控件
  2. 启动一个WPF Image控件和BitmapImage对象
  3. 将BitmapImage源设置为图像的Uri
  4. 将图像添加到画布中
  5. 当图像下载完成后,将画布渲染到新的位图上
我的代码在WPF本身中可以正常工作,但在ASP.Net页面中运行时,图片无法下载。
对于其他WPF UI元素,这完全没有问题。 对于Image,使用BitmapImage.StreamSource属性设置源是有效的。 当我使用 BitmapImage.UriSource 属性时,BitmapImage.DownloadCompleted事件没有被触发,这表明该图片根本没有开始下载。
需要注意的是,对于大多数控件(椭圆、矩形、墨迹演示文稿以及Image控件),只要我使用流源而不是uri源,就可以正常工作。
所以,我错过了什么?为什么BitmapImage类在Web应用程序中行为不同?
我知道我会被问到这个目的,因为我编写了一个Silverlight客户端来创建存储在Web服务器上的图形内容。 我希望Web服务器将内容呈现为位图文件。
提前感谢您的任何建议。
这是我ASP.Net页面的代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Windows.Controls;
using System.Windows.Media.Imaging;
using System.Threading;
using System.Windows;
using System.Net;
using System.IO;
using System.Windows.Media;

public partial class _Default : System.Web.UI.Page 
{
    private static Canvas c;
    protected void Page_Load(object sender, EventArgs e)
    {
        Thread t = new Thread(new ThreadStart(
            delegate { DownloadAndSave(); }));
        t.SetApartmentState(ApartmentState.STA);
        t.Start();
        t.Join();
    }

    [STAThread]
    void DownloadAndSave()
    {
        c = new Canvas();
        BitmapImage bitmap = new BitmapImage();
        System.Windows.Controls.Image image = new System.Windows.Controls.Image();

        bitmap.DownloadCompleted += new EventHandler(bitmap_DownloadCompleted);
        bitmap.BeginInit();
        bitmap.UriSource = new Uri("http://andrew.myhre.tanash.net/customassets/andrewmyhre/image/face.jpg");
        bitmap.EndInit();

        image.Source = bitmap;

        c.Children.Add(image);

        c.UpdateLayout();
        c.Measure(new Size(400, 300));
        c.Arrange(new Rect(new Size(400, 300)));
    }

    void bitmap_DownloadCompleted(object sender, EventArgs e)
    {
        // this never fires!!
        SaveImage(c);
    }

    void SaveImage(UIElement element)
    {
        RenderTargetBitmap bmp = new RenderTargetBitmap(400, 300, 96, 96, PixelFormats.Pbgra32);
        bmp.Render(element);
        BitmapEncoder encoder = new JpegBitmapEncoder();
        encoder.Frames.Add(BitmapFrame.Create(bmp));
        using (Stream stm = File.Create(Server.MapPath("~/file.jpg")))
            encoder.Save(stm);
    }
}
2个回答

2
我认为DownloadCompleted事件从未被触发是因为当您使用UriSource属性时,BitmapImage会异步加载,这允许后台线程(DownloadAndSave方法)在图像加载之前完成。
最近在一个几乎相同的情况下对我有效的方法是同步下载位图资源,并使用BitmapImage.StreamSource属性设置它。请注意,当使用该技术时,直到渲染RenderTargetBitmap之后才能关闭/处理流。

1

你验证过将STAThread属性添加到DownloadAndSave方法是否确实使其在STA线程中运行吗?

根据STAThreadAttribute的文档(http://msdn.microsoft.com/en-us/library/system.stathreadattribute.aspx),它对于WinForms应用程序中的其他方法,如Main入口方法,没有任何影响。

我猜你应该朝那个方向看 - 我曾经遇到过需要STA的WPF图像函数类似的问题。


你是对的,STAThread属性对该方法没有影响。我之前不知道为什么.. - Andrew Myhre

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接