Подтвердить что ты не робот

Проблема преобразования .ico в массив байтов в объект Image в .net

Я пытаюсь принимать значки и добавлять их к динамическому изображению, которое я создаю. См. StackFlair. Код сайта работает нормально локально и на одном общем сервере хостинга. blah blah, бесплатный хостинг, вы получаете то, за что платите, blah blah Моя проблема в том, что я получаю исключение из новой настройки хостинга. Это исключение происходит только для файлов .ico.. Я могу обрабатывать .gif и .png изображения просто отлично на всех проверенных серверах (т.е. изображении гравитара). Фавиконы, которые я пытаюсь использовать, являются знаками из сети SE, но даже http://www.google.com/favicon.ico приводит к следующему исключению.

System.ArgumentException: параметр недействителен.

  • System.Drawing.Image.FromStream(поток потока, логическое использованиеEmbeddedColorManagement, логическое значение validateImageData)
  • System.Drawing.Image.FromStream(поток потока)

Ниже перечислены варианты кода, который я пытаюсь сделать. Я получаю тот же Параметр недействительным исключением для всех вариантов.

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

Если я прохожу через массив и выписываю каждое значение байта, вывод идентичен моему локальному экземпляру на сервер, на котором я получаю исключение.

Если это помогает, сервер, на котором мой код не работает, является сервером Windows 2003 с sp2.

Очевидно, что фреймворк говорит мне, что поток байтов недействителен, но все, что я проверил, проверяет. Любые идеи о том, почему этот конкретный сервер задыхается от файлов .ico?

4b9b3361

Ответ 1

У меня есть обходное решение. Используйте ImageMagick для преобразования файлов ico в файлы png:

convert favicon.ico[0] favicon.png

Тогда с ними легко работать. ImageMagick предварительно установлен на множество общих хостов или вы можете загружать предварительно скомпилированные двоичные файлы для Windows.

Если вы оставите [0], вы получите серию файлов favicon-0.png favicon-1.png и т.д., если в файле .ico сохранено более одного образа значка. Затем вам нужно будет отсортировать их, чтобы выбрать тот, который наиболее близок к тому, что вы хотите: 16x16 с альфа-прозрачностью. (Я включаю 32x32 и 48x48 в свои файлы favicon, для пользователей IE, которые перетаскивают ярлыки для Интернета на свой рабочий стол.) ImageMagick сохраняет прозрачность при преобразовании в png.

Значок шестеренки stackapps.com/favicon.ico имеет два изображения. Первая имеет альфа-прозрачность и отлично смотрится на светло-сером фоне #DBDCDB.

Я предполагаю, что вы создаете динамическое изображение, подобное http://i.stack.imgur.com/SNHfF.png на сервере, вместо того, чтобы отправлять все 6 значков верхнего сайта в браузер, Если нет, по-прежнему рекомендуется отправить значки, преобразованные в png, потому что они не предназначены для рендеринга в веб-страницах.

... Том

Ответ 2

Я воспроизвел вашу проблему на Windows Server 2003 с пакетом обновления 2 (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

Надеюсь, это поможет вам.

Ответ 3

У нас была проблема с файлами ico в Media Browser Я помню, что это произошло, потому что GDI + задыхался от икон, в которых были PNG, удаляя их это исправлено. Или примените: http://support.microsoft.com/kb/971644 в Vista исправил его.

Возможно, аналогичный патч для сервера 2003.

Ответ 4

Просто мысль: вы уверены, что не вникаете в какие-либо вовлеченные потоки?

Я знаю, что GDI + не нравится, что вы закрываете поток до его завершения, и ошибка всегда не очень полезна в этих случаях.

У вас есть точный репрограммный код, чтобы мы могли вам в полной мере помочь?

Ответ 5

В документах есть примечание о том, чтобы сохранить поток открытым для жизни изображения. Это может быть проблема?

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

Вы должны оставить поток открытым для время жизни изображения.

Поток reset равен нулю, если этот метод называется последовательно с тот же поток.

Ответ 6

Здесь есть очень чистый и подробный проект для извлечения нескольких значков из файла: 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

и изменил construnctor на это:

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.