2010-09-26 11 views
12

Estoy tratando de tomar iconos de página y agregarlos a una imagen dinámica que estoy creando. Ver StackFlair. El código del sitio web funciona bien localmente, y en un servidor de alojamiento compartido. blah blah, plan de alojamiento gratuito, obtienes lo que pagas, blah blah Mi problema es que recibo una excepción de una nueva configuración de alojamiento. Esta excepción solo se aplica a los archivos .ico. Puedo procesar imágenes .gif y .png sin problemas en todos los servidores que he probado (es decir, una imagen gravatar). Los favicons que trato de usar son favicons de la red SE, pero incluso http://www.google.com/favicon.ico da como resultado la siguiente excepción.Problema al convertir .ico en matriz de bytes al objeto Imagen en .net

System.ArgumentException: El parámetro no es válido.

  • System.Drawing.Image.FromStream (corriente Stream, Boolean useEmbeddedColorManagement, Boolean validateImageData)
  • System.Drawing.Image.FromStream (Secuencia SECUENCIA)

Las variaciones de código que Estoy intentando están abajo. Obtengo la misma excepción de Parámetro no válido para todas las variaciones.

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); 

Todos estos funcionan bien a nivel local y en el servidor de hosting mal. Ninguno de ellos funciona en el servidor en el que quiero estar. Al usar la salida de Trace, puedo verificar que la longitud de la matriz contiene la cantidad correcta de bytes. Si hago lo siguiente, veo que la imagen se muestra como se esperaba.

Response.Clear(); 
Response.BinaryWrite(imageBytes); 
Response.End(); 

Si yo recorrer la matriz y escribir cada valor de byte, la salida es idéntica a mi instancia local al servidor donde consigo la excepción.

Si ayuda, el servidor donde mi código no funciona es un servidor de Windows 2003 con sp2.

Claramente, el marco me está diciendo que la secuencia de bytes no es válida, pero todo lo que he comprobado, marca. ¿Alguna idea de por qué este servidor específico se está ahogando en los archivos .ico?

+0

Sé que es una solución alternativa en lugar de una solución, pero si los archivos .ico que está sirviendo son favicons, podría servirlos en formato PNG y aún así funcionará (incluso en IE6, IIRC). – Piskvor

+0

@Piskvor, necesito ingresarlos en un objeto Imagen porque los estoy agregando a una imagen que estoy creando. Ver [StackFlair] (http://stackapps.com/questions/1567/stackflair-generate-flair-for-your-stackexchange-associated-accounts-now-with). –

+1

@rchern: ah, no importa entonces. – Piskvor

Respuesta

2

Tengo una solución. Utilice ImageMagick para convertir los archivos ico a archivos png:

convert favicon.ico[0] favicon.png 

Entonces, es fácil trabajar con ellos. ImageMagick está preinstalado en muchos hosts compartidos, o puede descargar binarios precompilados para Windows.

Si deja el [0], obtendrá una serie de archivos favicon-0.png favicon-1.png, etc., si hay más de una imagen de icono almacenada en el archivo .ico. Luego deberá ordenarlos para elegir el más cercano a lo que desea: 16x16 con transparencia alfa. (Incluyo 32x32 y 48x48 en mis archivos de favicon, para usuarios de IE que arrastran accesos directos a Internet a su escritorio). ImageMagick conserva la transparencia al convertir a png.

El icono del engranaje stackapps.com/favicon.ico tiene dos imágenes. El primero tiene transparencia alfa, y se ve muy bien en su fondo gris claro #DBDCDB.

Supongo que está creando una imagen dinámica como su http://i.stack.imgur.com/SNHfF.png en el servidor, en lugar de enviar los 6 iconos del sitio superior al navegador. De lo contrario, sigue siendo una buena idea enviar los iconos convertidos a png, ya que no están diseñados para procesarse en páginas web.

... Tom

+0

Al aceptar este porque me dio la idea de ejecutar el tarea diaria a nivel local que convierte .ico a .png y ftp'ing al servidor para que la aplicación web solo pueda usar los archivos .png. –

0

Tuvimos un problema con los archivos ico en Media Browser Recuerdo que sucedió porque GDI + se estaba ahogando en los iconos que tenían PNG en ellos, eliminándolos lo solucionó. O aplicar: http://support.microsoft.com/kb/971644 en Vista lo arregló.

Es posible que exista un parche similar para el servidor 2003.

+0

No veo una versión 2k3. ¿Puedes explicar lo que quieres decir al eliminar los pngs (o una referencia que me ayudaría a comenzar)? No estoy seguro de cómo y no aparecen los resultados de búsqueda. –

0

Es sólo una idea: ¿estás seguro de que no echar a perder con cualquiera de las corrientes involucradas?

Sé que a GDI + no le gusta que cierre una secuencia antes de que haya terminado con ella, y el error siempre es poco útil en estos casos.

¿Tendría un código de reprografía exacto para que podamos ayudarle por completo?

+0

Lo único que te hace falta es configurar imageUrl en http://sstatic.net/stackoverflow/img/favicon.ico o http://google.com/favicon.ico –

+0

uhh :) lo siento, no lo hago Entiendo este comentario –

1

He reproducido su problema en Windows Server 2003 SP2 y solución fundada. Su error fue responder mientras usa HTTP, por lo que debe proporcionar el tipo de contenido de respuesta. También agregué "disposición de contenido" al encabezado de respuesta, pero no tiene importancia y no es obligatorio, lo usé solo para probar la respuesta del servidor a través del navegador.

// 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(); 

y el servidor parte

// 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 

espero que le ayude.

+0

No estoy seguro de entender. Solo estoy tratando de hacer la parte # 2. El punto de mi pregunta fue que escribir en la respuesta funciona en la parte # 1 sin problemas (sin el encabezado). La Parte # 2 ** no funciona ** sin embargo. –

+0

¿me puede proporcionar su imageUrl para que pruebe la respuesta de su servidor? Porque no veo ningún problema con la Parte # 2. – mastak

+0

Ver mi comentario en la respuesta de Simon. –

0

Hay una nota en el documento sobre cómo mantener la transmisión abierta durante toda la vida de la imagen. ¿Podría ser ese el problema aquí?

http://msdn.microsoft.com/en-us/library/93z9ee4x.aspx

Debe mantener el flujo abierto para el vida útil de la Imagen.

La secuencia se restablece a cero si este método se llama sucesivamente con la misma secuencia .

+0

No. Mi código es el que figura en la lista en el OP. Creo un nuevo flujo, y en la línea siguiente trato de ponerlo en la imagen. No use statement. No ocurre nada con el flujo entre esas acciones. –

0

Aquí hay un proyecto muy limpio y detallado para la extracción de varios iconos de un archivo: http://www.codeproject.com/Articles/6171/Access-multiple-icons-in-a-single-icon-file

añadí esta función:

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 

y Construnctor cambiado a esto:

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 

para agregar soporte para cargar iconos de enlaces web en la clase multiIcon.

Cuestiones relacionadas