为什么 WebClient.DownloadData 有时会降低图像的分辨率?
Why does WebClient.DownloadData sometimes reduce the resolution of images?
我正在尝试从我目前正在开发的应用程序的网站动态下载网站图标,并编写了一些代码以从给定网站中提取可能的候选者。这一切都很好,但由于某些原因,使用 WebClient.DownloadData
下载某些图像文件后质量会下降很多,而其他图像文件则按预期下载。
例如,使用以下代码下载 Microsoft's 128 x 128 px favicon 会生成 16 x 16 像素的位图:
public static string Temp()
{
string iconLink = "https://c.s-microsoft.com/favicon.ico?v2"; // <-- 128 x 128 PX FAVICON
ServicePointManager.ServerCertificateValidationCallback += ValidateRemoteCertificate;
SecurityProtocolType[] protocolTypes = new SecurityProtocolType[] { SecurityProtocolType.Ssl3, SecurityProtocolType.Tls, SecurityProtocolType.Tls11, SecurityProtocolType.Tls12 };
string base64Image = string.Empty;
bool successful = false;
for (int i = 0; i < protocolTypes.Length; i++)
{
ServicePointManager.SecurityProtocol = protocolTypes[i];
try
{
using (WebClient client = new WebClient())
using (MemoryStream stream = new MemoryStream(client.DownloadData(iconLink)))
{
Bitmap bmpIcon = new Bitmap(Image.FromStream(stream, true, true));
if (bmpIcon.Width < 48 || bmpIcon.Height < 48) // <-- THIS CHECK FAILS, DEBUGGER SAYS 16 x 16 PX!
{
break;
}
bmpIcon = (Bitmap)bmpIcon.GetThumbnailImage(350, 350, null, new IntPtr());
using (MemoryStream ms = new MemoryStream())
{
bmpIcon.Save(ms, ImageFormat.Png);
base64Image = Convert.ToBase64String(ms.ToArray());
}
}
successful = true;
break;
}
catch { }
}
if (!successful)
{
throw new Exception("No Icon found");
}
return base64Image;
}
正如我之前所说,在其他领域也发生了这种缩小,然后又在一些领域没有发生。
所以我想知道:
- 我是否漏掉了任何明显的东西,因为这看起来很奇怪?
- 为什么会发生这种情况(以及为什么 protonmail's 48x48 px favicon 等其他图像文件)可以正常下载而没有任何损失?
- 有没有办法更改我的代码以防止此类行为?
正如所指出的,Image.FromStream()
在处理 .ico 文件时不会自动选择可用的最佳质量。
因此改变
Bitmap bmpIcon = new Bitmap(Image.FromStream(stream, true, true));
到
System.Drawing.Icon originalIcon = new System.Drawing.Icon(stream);
System.Drawing.Icon icon = new System.Drawing.Icon(originalIcon, new Size(1024, 1024));
Bitmap bmpIcon = icon.ToBitmap();
成功了。
通过创建一个非常大的新图标,它会采用可用的最佳质量,然后将其转换为位图。
我正在尝试从我目前正在开发的应用程序的网站动态下载网站图标,并编写了一些代码以从给定网站中提取可能的候选者。这一切都很好,但由于某些原因,使用 WebClient.DownloadData
下载某些图像文件后质量会下降很多,而其他图像文件则按预期下载。
例如,使用以下代码下载 Microsoft's 128 x 128 px favicon 会生成 16 x 16 像素的位图:
public static string Temp()
{
string iconLink = "https://c.s-microsoft.com/favicon.ico?v2"; // <-- 128 x 128 PX FAVICON
ServicePointManager.ServerCertificateValidationCallback += ValidateRemoteCertificate;
SecurityProtocolType[] protocolTypes = new SecurityProtocolType[] { SecurityProtocolType.Ssl3, SecurityProtocolType.Tls, SecurityProtocolType.Tls11, SecurityProtocolType.Tls12 };
string base64Image = string.Empty;
bool successful = false;
for (int i = 0; i < protocolTypes.Length; i++)
{
ServicePointManager.SecurityProtocol = protocolTypes[i];
try
{
using (WebClient client = new WebClient())
using (MemoryStream stream = new MemoryStream(client.DownloadData(iconLink)))
{
Bitmap bmpIcon = new Bitmap(Image.FromStream(stream, true, true));
if (bmpIcon.Width < 48 || bmpIcon.Height < 48) // <-- THIS CHECK FAILS, DEBUGGER SAYS 16 x 16 PX!
{
break;
}
bmpIcon = (Bitmap)bmpIcon.GetThumbnailImage(350, 350, null, new IntPtr());
using (MemoryStream ms = new MemoryStream())
{
bmpIcon.Save(ms, ImageFormat.Png);
base64Image = Convert.ToBase64String(ms.ToArray());
}
}
successful = true;
break;
}
catch { }
}
if (!successful)
{
throw new Exception("No Icon found");
}
return base64Image;
}
正如我之前所说,在其他领域也发生了这种缩小,然后又在一些领域没有发生。 所以我想知道:
- 我是否漏掉了任何明显的东西,因为这看起来很奇怪?
- 为什么会发生这种情况(以及为什么 protonmail's 48x48 px favicon 等其他图像文件)可以正常下载而没有任何损失?
- 有没有办法更改我的代码以防止此类行为?
正如所指出的,Image.FromStream()
在处理 .ico 文件时不会自动选择可用的最佳质量。
因此改变
Bitmap bmpIcon = new Bitmap(Image.FromStream(stream, true, true));
到
System.Drawing.Icon originalIcon = new System.Drawing.Icon(stream);
System.Drawing.Icon icon = new System.Drawing.Icon(originalIcon, new Size(1024, 1024));
Bitmap bmpIcon = icon.ToBitmap();
成功了。
通过创建一个非常大的新图标,它会采用可用的最佳质量,然后将其转换为位图。