我正在尝试使用favicons并将它们添加到我正在创建的动态图像中。见StackFlair。网站代码在本地工作正常,并在一个共享托管服务器上。 blah blah,免费托管计划,你得到你支付的费用,等等等等。我的麻烦是我从新的托管设置中得到一个例外。 此异常只发生在.ico文件中。我可以在我测试过的所有服务器上处理.gif和.png图像(例如,一个gravatar图像)。我尝试使用的favicon是来自SE网络的favicons,但即使http://www.google.com/favicon.ico也会导致以下异常。
System.ArgumentException:参数无效。
- System.Drawing.Image.FromStream(Stream stream,Boolean useEmbeddedColorManagement,Boolean validateImageData)
- System.Drawing.Image.FromStream(Stream stream)
我正在尝试的代码变体如下。对于所有变体,我得到相同的参数无效异常。
byte[] imageBytes = //pull from Image field in SQL Server
//or
byte[] imageBytes = new WebClient().DownloadData(imageUrl);
MemoryStream ms = new MemoryStream(imageBytes);
Image image = Image.FromStream(ms);
//or
Icon icon = new Icon(ms);
Image image = icon.ToBitmap();
//or
Image image = new Bitmap(ms);
所有这些在本地和坏主机服务器上工作得很好。它们都不能在我想要的服务器上运行。通过使用Trace输出,我可以验证数组的长度是否包含正确的字节数。如果我执行以下操作,则会看到图像按预期显示。
Response.Clear();
Response.BinaryWrite(imageBytes);
Response.End();
如果我循环遍历数组并写出每个字节值,那么从我的本地实例到我得到异常的服务器的输出是相同的。
如果有帮助,我的代码不起作用的服务器是带有sp2的Windows 2003服务器。
显然,框架告诉我字节流无效,但是我检查过的所有内容都会检出。关于为什么这个特定服务器在.ico文件上窒息的任何想法?
答案 0 :(得分:2)
我有一个解决方法。使用ImageMagick将ico文件转换为png文件:
convert favicon.ico[0] favicon.png
然后这些很容易合作。 ImageMagick预先安装在许多共享主机上,或者您可以下载适用于Windows的预编译二进制文件。
如果您不使用[0],那么如果.ico文件中存储了多个图标图像,您将获得一系列文件favicon-0.png favicon-1.png等。然后,您需要对它们进行排序,选择最接近您想要的那个:16x16,具有Alpha透明度。 (我的favicon文件中包含32x32和48x48,适用于将互联网快捷方式拖到桌面上的IE用户。)ImageMagick在转换为png时保留了透明度。
stackapps.com/favicon.ico齿轮图标有两个图像。第一个具有alpha透明度,并且在浅灰色#DBDCDB背景上看起来很棒。
我假设您正在构建一个动态图像,如服务器上的http://i.stack.imgur.com/SNHfF.png,而不是将所有6个顶级站点图标发送到浏览器。如果没有,发送转换为png的图标仍然是一个好主意,因为它们不是为在网页内呈现而设计的。
...汤姆
答案 1 :(得分:1)
我已在Windows Server 2003 SP2上重现了您的问题并成立了解决方案。您的错误是在使用HTTP时进行响应,因此您应该提供响应内容类型。 我还在响应标题中添加了“content-disposition” - 但是没有关系,也没有要求 - 我只是用它来通过浏览器测试服务器响应。
// Part #1: Server
// read ico - you can make it in your manner
Stream fileStream = File.OpenRead( Server.MapPath( @"~\images\myicon.ico" ) );
byte[] fileBytes = new byte[ fileStream.Length ];
fileStream.Read( fileBytes, 0, (int) fileStream.Length );
// here is making response
Response.ContentType = "application/ico";
Response.AddHeader( "content-disposition", string.Format( "attachment;filename=myico.ico" ) );
Response.BinaryWrite( fileBytes );
Response.End();
和服务器部分
// Part#2: Client ( seems same as your )
WebClient client = new WebClient();
byte[] bytes = client.DownloadData( @"http://my url - you can't use it" );
MemoryStream ms = new MemoryStream(bytes);
Icon icon = new Icon( ms );
Image image = icon.ToBitmap(); // 1st way
Image yetOneImage = new Bitmap( ms ); // 2nd way
// or just put your url into browser and preview with your default images viewer
我希望它可以帮到你。
答案 2 :(得分:0)
我们在Media Browser中遇到了ico文件的问题。我记得它发生了,因为GDI +在其中包含PNG的图标上窒息,剥离它们修复它。或者在Vista上应用:http://support.microsoft.com/kb/971644修复它。
服务器2003可能有类似的补丁。
答案 3 :(得分:0)
只是一个想法:你确定你没有弄乱任何涉及的流吗?
我知道GDI +不喜欢在它完成之前关闭一个流,并且在这些情况下错误总是没有用。
您是否有完整的重新编码,以便我们完全帮助您?
答案 4 :(得分:0)
文档中有一条关于在图像生命周期内保持流打开的说明。这可能是问题吗?
http://msdn.microsoft.com/en-us/library/93z9ee4x.aspx
你必须保持流开放 图像的生命周期。
如果这样,流将重置为零 方法被连续调用 同样的流。
答案 5 :(得分:0)
这里有一个非常干净详细的项目,用于从文件中提取多个图标: http://www.codeproject.com/Articles/6171/Access-multiple-icons-in-a-single-icon-file
我添加了这个功能:
Private Sub readIcoFromWebLink(ByVal link As Uri)
' Create the byte array and read it in
'
Dim byteArray() As Byte = New WebClient().DownloadData(link)
' Load the stream with the bytearray
'
icoStream = New MemoryStream(byteArray)
icoStream.Seek(0, SeekOrigin.Begin)
End Function
并将改变者改为:
Public Sub New(ByVal filename As String)
If IO.File.Exists(filename) Then
readIcoFile(filename) ' Load the file
Else
readIcoFromWebLink(New Uri(filename))
End If
icoHeader = New iconHeader ' Read the header
Dim counter As Integer ' Read each icons header
For counter = 1 To icoHeader.Count
icons.Add(New iconEntry(counter - 1))
Next
End Sub
添加对multiIcon
类中的网络链接加载图标的支持。