【问题标题】:WPF Can't retrieve WebP image from url?WPF 无法从 url 检索 WebP 图像?
【发布时间】:2019-08-06 23:27:56
【问题描述】:

我无法从 url 检索图像。以前,在设置 HttpClient 标头之前,我根本无法连接到该站点。我能够从其他来源检索图像,但不能从这个特定来源检索。

获取图片的代码:

var img = new BitmapImage();
        img.BeginInit();
        img.UriSource = new Uri("https://i1.adis.ws/i/jpl/jd_083285_a?qlt=80&w=600&h=425&v=1&fmt=webp", UriKind.RelativeOrAbsolute);
        img.EndInit();
        Console.Out.WriteLine();
        ImageShoe.Source = img;

如果我尝试使用不同的 url 检索不同的图像,例如 https://www.google.com/images/branding/googlelogo/1x/googlelogo_color_272x92dp.png,它可以正常工作。

更新:

似乎使用字节数组是可行的方法,但我仍然不确定这里有什么问题。

        HttpClient client = new HttpClient();
        client.DefaultRequestHeaders.Add("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8");
        var url = "https://i1.adis.ws/i/jpl/jd_083285_a?qlt=80&w=600&h=425&v=1&fmt=webp";//baseUrl + productUrl;
        var result = await client.GetByteArrayAsync(new Uri(
        MemoryStream buf = new MemoryStream(result);
        var image = new BitmapImage();
        image.StreamSource = buf;
        this.ImageShoe.Source = image;

【问题讨论】:

  • 它最后没有 .fileformat,因此您无法解析它,因为 WPF 不知道如何处理数据。试试这个:img-prod-cms-rt-microsoft-com.akamaized.net/cms/api/am/…
  • 我认为这可能是个问题,但使用img-prod-cms-rt-microsoft-com.akamaized.net/cms/api/am/… 之类的网址就可以了。你知道我如何得到图像吗?
  • 下载它并将其添加到您的项目资源中?还是需要动态加载?
  • @DenisSchaf 虽然 WPF 确实无法解码 WebP,但在没有适当的扩展。编码格式由帧缓冲区前几个字节中的幻数确定。这就是为什么您可以将任何支持的图像格式的编码帧作为 MemoryStream 中的字节数组传递给 WPF BitmapImage 的 StreamSource 属性,而无需显式指定编码格式。您可以通过重命名来尝试此操作,例如将 .png 文件转换为 .jpg。它仍然被解码为 PNG。

标签: c# wpf url web-scraping webp


【解决方案1】:

WPF 本身不支持WebP image format

您可以通过在请求 URL 中使用 fmt=png 而不是 fmt=webp 来简单地请求支持的格式,例如 PNG:

ImageShoe.Source = new BitmapImage(
    new Uri("https://i1.adis.ws/i/jpl/jd_083285_a?qlt=80&w=600&h=425&v=1&fmt=png"));

如果您确实需要 WebP 支持,以下方法会下载 WebP 图像并首先借助 libwebp wrapper for .NET 库将其转换为 System.Drawing.Bitmap。然后第二次转换从System.Drawing.Bitmap 转换为BitmapImage

包装库可通过 NuGet 获得,但您还必须为所需平台(即 x86 或 x64)下载包装的 libwebp 库,如包装库主页上所述。

private async Task<BitmapImage> LoadWebP(string url)
{
    var httpClient = new HttpClient();
    var buffer = await httpClient.GetByteArrayAsync(url);
    var decoder = new Imazen.WebP.SimpleDecoder();
    var bitmap = decoder.DecodeFromBytes(buffer, buffer.Length);
    var bitmapImage = new BitmapImage();

    using (var stream = new MemoryStream())
    {
        bitmap.Save(stream, System.Drawing.Imaging.ImageFormat.Png);
        stream.Position = 0;

        bitmapImage.BeginInit();
        bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
        bitmapImage.StreamSource = stream;
        bitmapImage.EndInit();
    }

    return bitmapImage;
}

我已经测试过了

ImageShoe.Source = await LoadWebP(
    "https://i1.adis.ws/i/jpl/jd_083285_a?qlt=80&w=600&h=425&v=1&fmt=webp");

【讨论】:

  • 谢谢!不确定我会采用哪种方法,但这很棒:)
  • 选择支持的图像格式似乎更明智。
  • 当然,这只是从具有各种 url 格式的多个站点解析 url 的问题。如果可能的话,我不希望个别网站例外,但似乎我可能不得不这样做。我认为我最大的问题是,在我的脑海中,我认为“肯定有一个 api”,所以我花更多时间寻找解决方案或最好的方法,而不是仅仅获得结果
  • 这个答案顶部的陈述是错误的。我可以通过UriSourceStreamSource 使用BitmapImage 在WPF 中加载WebP 图像,也可以直接从Web URL 加载。不需要额外的库或转换器。
  • @Herohtar 您可能已经安装了 WebP 编解码器。那是第三方软件。 Windows/WPF 本身不支持 WebP。
猜你喜欢
  • 1970-01-01
  • 2020-08-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-11-18
  • 2014-08-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多