使用 WebClient 获取远程图像会产生颗粒状 GIF 并且无法处理 PNG+BMP

2023-12-02

问候!

我正在创建一个 Web 表单原型 (ImageLaoder.aspx),它将返回一个图像,以便可以像这个简单的示例一样使用其他 Web 表单/网页:

<img src="http://www.mydomain.com/ImageLoader.aspx?i=http://images.mydomain.com/img/a.jpg" />

到目前为止,它加载 JPEG 没有任何问题,但与原始文件相比,GIF 看起来“有颗粒感”,BMP 和 PNG 会导致以下异常:

System.Runtime.InteropServices.ExternalException:GDI+ 中发生一般错误

到目前为止我的代码如下所示:

protected void Page_Load(object sender, EventArgs e)
{
    string l_filePath = Request.QueryString["i"];

    System.Drawing.Image l_image = GetImage(l_filePath);
    if (l_image != null)
    {
        System.Drawing.Imaging.ImageFormat l_imageFormat = DetermineImageFormat(l_filePath);
        WriteImageAsReponse(l_image, l_imageFormat);
    }
}

private System.Drawing.Image GetImage(string filePath)
{
    WebClient l_WebClient = new WebClient();
    byte[] l_imageBytes = l_WebClient.DownloadData(filePath);

    System.Drawing.Image l_image = null;
    using (MemoryStream l_MemStream = new MemoryStream(l_imageBytes, 0, l_imageBytes.Length))
    {
        l_MemStream.Write(l_imageBytes, 0, l_imageBytes.Length);
        l_image = System.Drawing.Image.FromStream(l_MemStream, true);
        l_MemStream.Close();
    }

    return l_image;
}

private System.Drawing.Imaging.ImageFormat DetermineImageFormat(string filePath)
{
    if (filePath.EndsWith(".jpg", StringComparison.OrdinalIgnoreCase))
        return System.Drawing.Imaging.ImageFormat.Jpeg;
    else if (filePath.EndsWith(".gif", StringComparison.OrdinalIgnoreCase))
        return System.Drawing.Imaging.ImageFormat.Gif;
    else if (filePath.EndsWith(".png", StringComparison.OrdinalIgnoreCase))
        return System.Drawing.Imaging.ImageFormat.Png;
    else
        return System.Drawing.Imaging.ImageFormat.Bmp;
}

private void WriteImageAsReponse(System.Drawing.Image image, System.Drawing.Imaging.ImageFormat imageFormat)
{
    if (image == null)
        return;

    System.Drawing.Bitmap l_outputBitMap = new Bitmap(image);

    if (imageFormat == System.Drawing.Imaging.ImageFormat.Jpeg)
        Response.ContentType = "image/jpg";
    else if (imageFormat == System.Drawing.Imaging.ImageFormat.Gif)
        Response.ContentType = "image/gif";
    else if (imageFormat == System.Drawing.Imaging.ImageFormat.Png)
        Response.ContentType = "image/png";
    else
        Response.ContentType = "image/bmp";

    l_outputBitMap.Save(Response.OutputStream, imageFormat);
}

知道为什么 GIF 呈颗粒状而 PNG 和 BMP 会导致异常吗?


关于 GetImage 方法的几点:

  • 当您使用 Image.FromStream 时,您不应该关闭(或处置)流
  • 如果您在流上调用 Dispose(使用 using 语句),则无需调用 Close
  • 您正在写入流,但不是“倒带”,因此据我所知, l_image 实际上没有获取任何数据(除非 Image.FromStream 重置位置本身)。 (可能是 gif/jpg 解码器倒带流,但 bmp/png 不倒带,因此出现错误。)
  • 为什么不直接使用采用字节数组的 MemoryStream 构造函数?

简而言之,我相信您的 GetImage 方法可以替换为:

private Image GetImage(string filePath)
{
    WebClient l_WebClient = new WebClient();
    byte[] l_imageBytes = l_WebClient.DownloadData(filePath);
    MemoryStream l_stream = new MemoryStream(l_imageBytes);
    return Image.FromStream(l_stream);
}

现在,更重要的是 - 为什么要加载图像?为什么不只将文件本身作为响应,按照您已经在做的那样设置内容类型 - 或者可能只是基于扩展名?换句话说,你的所有代码都将变成:

protected void Page_Load(object sender, EventArgs e)
{
    string filePath = Request.QueryString["i"];
    string extension = l_filePath.Substring(l_filePath.LastIndexOf('.') + 1);
    Response.ContentType = "image/" + extension;
    byte[] data = new WebClient.DownloadData(filePath);
    Response.OutputStream.Write(data, 0, data.Length);
    Response.End();
}

多一点错误处理(包括“这是一个合理的扩展吗?”)会很好,但除此之外我认为还可以。自己实际加载图像的唯一好处是您可以验证它是否真的is图像而不是病毒或类似的东西。

编辑:只是出于兴趣,你有充分的理由吗want图像请求要通过您的服务器吗?为什么网页作者会这样写:

<img src="http://www.mydomain.com/ImageLoader.aspx?i=http://images.mydomain.com/img/a.jpg" />

代替

<img src="http://images.mydomain.com/img/a.jpg" />

There are出于某些原因它可能有用,但在许多情况下它只是一种浪费。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 WebClient 获取远程图像会产生颗粒状 GIF 并且无法处理 PNG+BMP 的相关文章

  • 如何在C++中实现模板类协变?

    是否可以以这样一种方式实现类模板 如果模板参数相关 一个对象可以转换为另一个对象 这是一个展示这个想法的例子 当然它不会编译 struct Base struct Derived Base template
  • 如何在没有 Control.Invoke() 的情况下从后台线程修改控件属性

    最近 我们遇到了一些旧版 WinForms 应用程序 我们需要更新一些新功能 在专家测试该应用程序时 发现一些旧功能被破坏 无效的跨线程操作 现在 在您认为我是新手之前 我确实有一些 Windows 窗体应用程序的经验 我不是专家 但我认为
  • 嵌入式系统中的malloc [重复]

    这个问题在这里已经有答案了 我正在使用嵌入式系统 该应用程序在 AT91SAMxxxx 和 cortex m3 lpc17xxx 上运行 我正在研究动态内存分配 因为它会极大地改变应用程序的外观 并给我更多的力量 我认为我唯一真正的路线是为
  • FFMPEG Seeking 带来音频伪影

    我正在使用 ffmpeg 实现音频解码器 在读取音频甚至搜索已经可以工作时 我无法找到一种在搜索后清除缓冲区的方法 因此当应用程序在搜索后立即开始读取音频时 我没有任何工件 avcodec flush buffers似乎对内部缓冲区没有任何
  • 带有服务总线的 SignalR Azure 云服务

    我使用 SignalR 构建了一个简单的聊天应用程序那里有教程 http www asp net signalr overview getting started tutorial getting started with signalr
  • 为什么 POSIX 允许在只读模式下超出现有文件结尾 (fseek) 进行搜索

    为什么寻找文件结尾很有用 为什么 POSIX 让我们像示例中那样在以只读方式打开的文件中进行查找 c http en cppreference com w c io fseek http en cppreference com w c io
  • 跨多个控件共享事件处理程序

    在我用 C 编写的 Windows 窗体应用程序中 我有一堆按钮 当用户的鼠标悬停在按钮上时 我希望按钮的边框发生变化 目前我有以下多个实例 每个按钮一个副本 private void btnStopServer MouseEnter ob
  • 使用 Google Analytics API 在 C# 中显示信息

    我一整天都在寻找一个好的解决方案 但谷歌发展得太快了 我找不到有效的解决方案 我想做的是 我有一个 Web 应用程序 它有一个管理部分 用户需要登录才能查看信息 在本节中 我想显示来自 GA 的一些数据 例如某些特定网址的综合浏览量 因为我
  • c 中的错误:声明隐藏了全局范围内的变量

    当我尝试编译以下代码时 我收到此错误消息 错误 声明隐藏了全局范围内的变量 无效迭代器 节点 根 我不明白我到底在哪里隐藏或隐藏了之前声明的全局变量 我怎样才能解决这个问题 typedef node typedef struct node
  • 当 Cortex-M3 出现硬故障时如何保留堆栈跟踪?

    使用以下设置 基于 Cortex M3 的 C gcc arm 交叉工具链 https launchpad net gcc arm embedded 使用 C 和 C FreeRtos 7 5 3 日食月神 Segger Jlink 与 J
  • 基于范围的 for 循环中的未命名循环变量?

    有没有什么方法可以不在基于范围的 for 循环中 使用 循环变量 同时也避免编译器发出有关未使用它的警告 对于上下文 我正在尝试执行以下操作 我启用了 将警告视为错误 并且我不想进行像通过在某处毫无意义地提及变量来强制 使用 变量这样的黑客
  • 在 ASP.Net Core 2.0 中导出到 Excel

    我曾经使用下面的代码在 ASP NET MVC 中将数据导出到 Excel Response AppendHeader content disposition attachment filename ExportedHtml xls Res
  • Windows 窗体不会在调试模式下显示

    我最近升级到 VS 2012 我有一组在 VS 2010 中编码的 UI 测试 我试图在 VS 2012 中启动它们 我有一个 Windows 窗体 在开始时显示使用 AssemblyInitialize 属性运行测试 我使用此表单允许用户
  • 使用 LINQ 查找列表中特定类型的第一个元素

    使用 LINQ 和 C 在元素列表中查找特定类型的第一个项目的最短表示法是什么 var first yourCollection OfType
  • 更改窗口的内容 (WPF)

    我创建了一个简单的 WPF 应用程序 它有两个 Windows 用户在第一个窗口中填写一些信息 然后单击 确定 这会将他们带到第二个窗口 这工作正常 但我试图将两个窗口合并到一个窗口中 这样只是内容发生了变化 我设法找到了这个更改窗口内容时
  • EPPlus Excel 更改单元格颜色

    我正在尝试将给定单元格的颜色设置为另一个单元格的颜色 该单元格已在模板中着色 但worksheet Cells row col Style Fill BackgroundColor似乎没有get财产 是否可以做到这一点 或者我是否必须在互联
  • 如何构建印度尼西亚电话号码正则表达式

    这些是一些印度尼西亚的电话号码 08xxxxxxxxx 至少包含 11 个字符长度 08xxxxxxxxxxx 始终以 08 开头 我发现这个很有用 Regex regex new Regex 08 0 9 0 9 0 9 0 9 0 9
  • 在Linux中使用C/C++获取机器序列号和CPU ID

    在Linux系统中如何获取机器序列号和CPU ID 示例代码受到高度赞赏 Here http lxr linux no linux v2 6 39 arch x86 include asm processor h L173Linux 内核似
  • 方法参数内的变量赋值

    我刚刚发现 通过发现错误 你可以这样做 string s 3 int i int TryParse s hello out i returns false 使用赋值的返回值是否合法 Obviously i is but is this th
  • 如何在 C# 中播放在线资源中的 .mp3 文件?

    我的问题与此非常相似question https stackoverflow com questions 7556672 mp3 play from stream on c sharp 我有音乐网址 网址如http site com aud

随机推荐

  • 延迟加载和组件

    我正在将我的应用程序移至延迟加载 并且发现了两种加载组件的方法 一种是拥有 X 个组件和只有一个全局的 elements module 例如https www 9lessons info 2017 12 ionic angular lazy
  • Delphi loadlibrary() 中的错误

    我给了我的软件用户一个从 openfile 对话框中选择 dll 的机会 这样我的用户就可以从我的网站下载 dll 并将其与主项目一起使用 一切工作正常 它甚至可以发现 dll 是由我提供的或选择了无效的 dll 但是如果用户选择重命名的文
  • 使用纬度和经度计算多边形面积

    我正在使用我在这篇文章中找到的解决方案 使用从笛卡尔空间和世界文件生成的纬度和经度计算多边形面积 有问题 因为我得到的值不是真实的 例如 我们知道一个足球场应该有大约 5 300 00 平方米 对吧 但计算结果为 5 759 154 21
  • Quick Union Java 实现

    我一直在研究快速联合算法 下面的代码是实现的示例 有人可以向我解释一下里面发生了什么吗根法 please public class quickUnion private int id public void QuickUnionUF int
  • NSPredicate 表达式中 SUBQUERY 的快速解释

    关于 Apple 的 SUBQUERY 关键字的文档似乎为零 我在 SO 或 Google 上找不到关于它的简单解释 这是一个阴谋 Please 内部圈子里的人可以快速解释一下它的语法 以便我可以使用它吗 SUBQUERY Bs x x I
  • C++ 错误:字段的类型“int []”不完整

    我正在用 C 创建虚拟机 但遇到了这个错误 error field has incomplete type int int instrarr 我完全不知道 int 数组有什么问题 有人可以看一下并让我知道我做错了什么吗 我已经看了一个多小时
  • 为什么 order 在 /v2/shares 端点上不起作用

    在 hootsuite com 我们正在使用v2 shares在很长一段时间内为多个社交档案创建报告 该端点的文档指定here即 共享按创建时间排序 此刻 当我去 我会明白的 activity urn li activity 6537431
  • 要求在不同的行上设置 /p 变量

    我在批处理代码中看到 您可以在单独的行上要求用户输入 或者在询问时继续输入或执行其他操作 例如 它看起来像这样 enter your name name input would be here enter name above 代码可能看起
  • 为什么在这种带有泛型参数的情况下不考虑隐式转换?

    考虑以下代码 源自元斯卡拉项目 object Units case class Quantity M lt MInt T Numeric value T type This Quantity M T def M2 lt MInt m Qua
  • 当我执行“捆绑更新”时,我从不在我的 gemfile 中的 gem 收到错误。我如何忽略这种依赖性?

    我正在开发一个使用 twitter bootstrap rails 的项目 该项目构建在 Linux 机器上 并使用 ruby racer 作为 JavaScript 运行时 我遇到了一些问题 因为 ruby racer 似乎与 Windo
  • FileSystemWatcher 与轮询监视文件更改

    我需要设置一个应用程序来监视在本地或网络驱动器上的目录中创建的文件 会不会FileSystemWatcher或者对计时器进行轮询将是最好的选择 我过去曾使用过这两种方法 但并不广泛 这两种方法都存在哪些问题 性能 可靠性等 我见过文件系统观
  • ARM 代码分析器

    我想在arm 9上分析我的代码 是否有任何分析器可以为我提供函数调用时间和每个函数所花费的总周期 我更喜欢任何免费的分析器 我喜欢在 Linux 中使用 kcachegrind 我不知道有什么免费的 ARM 分析器 你可以试试ARM RVD
  • Node.js 堆内存不足

    今天 我运行文件系统索引脚本来刷新 RAID 文件索引 4 小时后它崩溃并出现以下错误 md5 241613 241627 97 5 md5 241614 241627 97 5 md5 241625 241627 98 1 Creatin
  • SonarLint V3:“可序列化”类中的字段对于 List 接口应该是瞬态的或可序列化的

    我的问题非常类似于this除了我在 SonarLint V3 squid S1948 中遇到的这个问题 我的代码是 public class Page
  • 使用 JSCH Java 反向 SSH 隧道 [关闭]

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 目前不接受答案 是否可以使用 JSCH 进行反向 ssh 连接 如果不是 是否有其他纯 Java 库可以用来进行反向隧道 SSH 连接 我想模仿的命令类似于 ssh
  • 如何使用 DataFrames 在 PySpark 中使用窗口函数?

    试图弄清楚如何在 PySpark 中使用窗口函数 这是我想要做的一个示例 只需计算用户发生 事件 的次数 在本例中 dt 是模拟时间戳 from pyspark sql window import Window from pyspark s
  • Chrome 扩展:后台脚本捕获网络和 HTTP 错误

    我正在开发一个小型 Chrome 扩展程序 供个人在非常特殊的情况下使用 网站自动化 但我遇到了问题 如何捕获后台脚本上的网络错误并调用某个函数 我已经实现了这个方法 chrome webRequest onErrorOccurred ad
  • D3 力定向图:为什么没有出现标志?

    情况 Each node应该有它相应的标志 但事实并非如此 CODE body font family Lato background color F5F5F5 title margin top 30px margin bottom 30p
  • 未调用复制构造函数进行复制初始化或优化?

    如果创建了复制构造函数private then in Case 1 没有错误 编译器不关心复制构造函数是否在类中定义 Case 2 错误 复制构造函数是私有的并且何时创建public 它被省略了 是否直接优化了副本而没有注意到构造函数是否已
  • 使用 WebClient 获取远程图像会产生颗粒状 GIF 并且无法处理 PNG+BMP

    问候 我正在创建一个 Web 表单原型 ImageLaoder aspx 它将返回一个图像 以便可以像这个简单的示例一样使用其他 Web 表单 网页 img src 到目前为止 它加载 JPEG 没有任何问题 但与原始文件相比 GIF 看起