如何将数据 uri 方案显示到 C# WebBrowser 控制器中

发布于 2024-09-03 06:49:08 字数 402 浏览 9 评论 0原文

如何在 C# 中显示使用 WebBrowser 控件编码的图像 base64?

我使用了以下代码:

<img src="data:image/gif;base64,/9j/4AAQSkZJRgABAgAAZABkAA7AAR
R894ADkFkb2JlAGTAAAAAAfbAIQABAMDAwMDBAMDBAYEAwQGBwUEBAUHCAYGBw
...
uhWkvoJfQO2z/rf4VpL6CX0Dts/63+FaS+gl9A7bP+tthWkvoJfQODCde4qfcg
RiNWK3UyUeX9CXpHU43diOK915X5fG/reux5hUAUBftZ" />

但没有显示图像。一种解决方案是将图像保存在本地并使用绝对路径,但这是不可取的。

有什么想法吗?

How can I show an image base64 encoded using WebBrowser control in C#?

I used the following code:

<img src="data:image/gif;base64,/9j/4AAQSkZJRgABAgAAZABkAA7AAR
R894ADkFkb2JlAGTAAAAAAfbAIQABAMDAwMDBAMDBAYEAwQGBwUEBAUHCAYGBw
...
uhWkvoJfQO2z/rf4VpL6CX0Dts/63+FaS+gl9A7bP+tthWkvoJfQODCde4qfcg
RiNWK3UyUeX9CXpHU43diOK915X5fG/reux5hUAUBftZ" />

but no image is displayed. One solution would be to save images locally and using absolute path, but this is not desirable.

Any idea?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

南风几经秋 2024-09-10 06:49:08

我尝试在一个项目中这样做,但 IE(WebBrowser 控件最终将使用它)成为限制因素 - 它只能容纳 32Kb 大小的图像。我最终不得不创建一个 HTTP 处理程序 (.ashx),它根据数据库密钥返回图像。

编辑:示例 - 请注意数据库处理例程是专有的,您必须放入自己的例程。处理程序的其余部分将展示如何重新缩放图像(如果需要)并作为响应发送回浏览器:

public class GenerateImage : IHttpHandler
{
    /// <summary>
    /// Shortcut to the database controller.  Instantiated immediately
    /// since the ProcessRequest method uses it.
    /// </summary>
    private static readonly IDataModelDatabaseController controller =
        DataModelDatabaseControllerFactory.Controller;

    /// <summary>
    /// Enables processing of HTTP Web requests by a custom HttpHandler
    /// that implements the <see cref="T:System.Web.IHttpHandler"/>
    /// interface.
    /// </summary>
    /// <param name="context">An <see cref="T:System.Web.HttpContext"/>
    /// object that provides references to the intrinsic server objects
    /// (for example, Request, Response, Session, and Server) used to
    /// service HTTP requests.</param>
    public void ProcessRequest(HttpContext context)
    {
        if (controller == null)
        {
            return;
        }

        IDataModelDescriptor desc = controller.GetDataModelDescriptor(
            new Guid(context.Request.QueryString["dataModel"]));
        IDataModelField imageField =
            desc.Fields[context.Request.QueryString["imageField"]];
        IDatabaseSelectQuery query = controller.CreateQuery();
        string[] keys = context.Request.QueryString["key"].Split(',');
        string showThumb = context.Request.QueryString["showThumbnail"];
        bool showThumbnail = showThumb != null;

        query.AssignBaseTable(desc);
        query.AddColumn(imageField, false);
        for (int i = 0; i < desc.KeyFields.Count; i++)
        {
            query.AddCompareValue(
                desc.KeyFields[i],
                keys[i],
                DatabaseOperator.Equal);
        }

        context.Response.CacheControl = "no-cache";
        context.Response.ContentType = "image/jpeg";
        context.Response.Expires = -1;

        byte[] originalImage = (byte[])controller.ExecuteScalar(query);

        if (showThumbnail)
        {
            int scalePixels;

            if (!int.TryParse(showThumb, out scalePixels))
            {
                scalePixels = 100;
            }

            using (Stream stream = new MemoryStream(originalImage))
            using (Image img = Image.FromStream(stream))
            {
                double multiplier;

                if ((img.Width <= scalePixels)
                    && (img.Height <= scalePixels))
                {
                    context.Response.BinaryWrite(originalImage);
                    return;
                }
                else if (img.Height < img.Width)
                {
                    multiplier = (double)img.Width / (double)scalePixels;
                }
                else
                {
                    multiplier = (double)img.Height / (double)scalePixels;
                }

                using (Bitmap finalImg = new Bitmap(
                    img,
                    (int)(img.Width / multiplier),
                    (int)(img.Height / multiplier)))
                using (Graphics g = Graphics.FromImage(finalImg))
                {
                    g.InterpolationMode =
                        InterpolationMode.HighQualityBicubic;
                    finalImg.Save(
                        context.Response.OutputStream,
                        ImageFormat.Jpeg);
                }
            }
        }
        else
        {
            context.Response.BinaryWrite(originalImage);
        }
    }

    /// <summary>
    /// Gets a value indicating whether another request can use the
    /// <see cref="T:System.Web.IHttpHandler"/> instance.
    /// </summary>
    /// <value></value>
    /// <returns>true if the <see cref="T:System.Web.IHttpHandler"/>
    /// instance is reusable; otherwise, false.
    /// </returns>
    public bool IsReusable
    {
        get
        {
            return false;
        }
    }
}

I tried doing this for a project and IE (which the WebBrowser control will eventually use) became the limiting factor - it can only hold 32Kb-sized images. I wound up having to create an HTTP handler (.ashx) that returned the image based on a database key.

edit: example - note the database handling routines are proprietary and you'd have to put in your own. The rest of the handler will show how to rescale images (if desired) and send back as a response to the browser:

public class GenerateImage : IHttpHandler
{
    /// <summary>
    /// Shortcut to the database controller.  Instantiated immediately
    /// since the ProcessRequest method uses it.
    /// </summary>
    private static readonly IDataModelDatabaseController controller =
        DataModelDatabaseControllerFactory.Controller;

    /// <summary>
    /// Enables processing of HTTP Web requests by a custom HttpHandler
    /// that implements the <see cref="T:System.Web.IHttpHandler"/>
    /// interface.
    /// </summary>
    /// <param name="context">An <see cref="T:System.Web.HttpContext"/>
    /// object that provides references to the intrinsic server objects
    /// (for example, Request, Response, Session, and Server) used to
    /// service HTTP requests.</param>
    public void ProcessRequest(HttpContext context)
    {
        if (controller == null)
        {
            return;
        }

        IDataModelDescriptor desc = controller.GetDataModelDescriptor(
            new Guid(context.Request.QueryString["dataModel"]));
        IDataModelField imageField =
            desc.Fields[context.Request.QueryString["imageField"]];
        IDatabaseSelectQuery query = controller.CreateQuery();
        string[] keys = context.Request.QueryString["key"].Split(',');
        string showThumb = context.Request.QueryString["showThumbnail"];
        bool showThumbnail = showThumb != null;

        query.AssignBaseTable(desc);
        query.AddColumn(imageField, false);
        for (int i = 0; i < desc.KeyFields.Count; i++)
        {
            query.AddCompareValue(
                desc.KeyFields[i],
                keys[i],
                DatabaseOperator.Equal);
        }

        context.Response.CacheControl = "no-cache";
        context.Response.ContentType = "image/jpeg";
        context.Response.Expires = -1;

        byte[] originalImage = (byte[])controller.ExecuteScalar(query);

        if (showThumbnail)
        {
            int scalePixels;

            if (!int.TryParse(showThumb, out scalePixels))
            {
                scalePixels = 100;
            }

            using (Stream stream = new MemoryStream(originalImage))
            using (Image img = Image.FromStream(stream))
            {
                double multiplier;

                if ((img.Width <= scalePixels)
                    && (img.Height <= scalePixels))
                {
                    context.Response.BinaryWrite(originalImage);
                    return;
                }
                else if (img.Height < img.Width)
                {
                    multiplier = (double)img.Width / (double)scalePixels;
                }
                else
                {
                    multiplier = (double)img.Height / (double)scalePixels;
                }

                using (Bitmap finalImg = new Bitmap(
                    img,
                    (int)(img.Width / multiplier),
                    (int)(img.Height / multiplier)))
                using (Graphics g = Graphics.FromImage(finalImg))
                {
                    g.InterpolationMode =
                        InterpolationMode.HighQualityBicubic;
                    finalImg.Save(
                        context.Response.OutputStream,
                        ImageFormat.Jpeg);
                }
            }
        }
        else
        {
            context.Response.BinaryWrite(originalImage);
        }
    }

    /// <summary>
    /// Gets a value indicating whether another request can use the
    /// <see cref="T:System.Web.IHttpHandler"/> instance.
    /// </summary>
    /// <value></value>
    /// <returns>true if the <see cref="T:System.Web.IHttpHandler"/>
    /// instance is reusable; otherwise, false.
    /// </returns>
    public bool IsReusable
    {
        get
        {
            return false;
        }
    }
}
红尘作伴 2024-09-10 06:49:08

数据uri字符串长度是多少,根据数据协议IE8 数据 URI 不能大于 32,768 个字符。

编辑:资源数据必须正确编码;否则会出错,资源不会加载。必须对“#”和“%”字符以及控制字符、非 US ASCII 字符和多字节字符进行编码。

What is data uri string length, according to data Protocol in IE8 Data URIs cannot be larger than 32,768 characters.

Edit: The resource data must be properly encoded; otherwise, an error occurs and the resource is not loaded. The "#" and "%" characters must be encoded, as well as control characters, non-US ASCII characters, and multibyte characters.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文