Как я могу взять байтовый массив изображения TIFF и превратить его в объект System.Drawing.Image?

У меня есть массив byte[], содержимое которого представляет собой файл TIFF (например, если я записываю эти байты непосредственно в файл с помощью объекта BinaryWriter, он формирует совершенно правильный файл TIFF), и я пытаюсь превратить его в объект System.Drawing.Image, чтобы я мог использовать его для последующих манипуляций (ввод в многостраничный объект TIFF)

Проблема, с которой я столкнулся, заключается в том, что общепринятый код для этой задачи:

    public Image byteArrayToImage(byte[] byteArrayIn)
    {
        MemoryStream ms = new MemoryStream(byteArrayIn);
        Image returnImage = Image.FromStream(ms, true);
        return returnImage;
    }

у меня не работает. Вторая строка вышеупомянутого метода, в которой он вызывает метод Image.FromStream, умирает во время выполнения, говоря

Parameter Not Valid

Я считаю, что метод задыхается от того факта, что это файл TIFF, но я не могу понять, как заставить метод FromStream принять этот факт.

Как превратить байтовый массив изображения TIFF в объект Image?

Кроме того, как я уже сказал, конечной целью этого является создание массива байтов, представляющего многостраничный файл TIFF, который содержит файлы TIFF, для которых у меня есть объекты массива байтов прямо сейчас. Если есть лучший способ сделать это, я полностью за него.

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
6
0
11 738
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий

Редактировать: Предположение, приведенное ниже, неверно, у меня была возможность запустить свою IDE позже и протестировать с записью и без нее, и оба правильно заполнили MemoryStream.

Я думаю, вам нужно сначала написать в свой MemeoryStream.

Как будто моя память (без каламбура) мне правильно служит:

MemoryStream ms = new MemoryStream(byteArrayIn);

Создает поток памяти такого размера.

Затем вам нужно записать содержимое байтового массива в поток памяти:

ms.Write(byteArrayIn, 0, byteArrayIn.Length);

Посмотрим, исправит ли это это.

Для повышения производительности просто установите ms.Length и ms.Position вместо повторного вызова ms.Write.

Lilith River 28.05.2011 20:41

Хорошо, я обнаружил проблему, и она была связана с частью кода, не связанной с той частью кода, о которой я спрашивал. Данные передавались в виде строки, я преобразовывал ее в массив байтов (это была тестовая установка, поэтому я пытался смоделировать массив байтов, который я получаю в основном приложении), затем преобразовал его в MemoryStream, а затем сделал Изображение из этого.

Чего я не понял, так это того, что строка была закодирована в Base64. Вызов Convert.FromBase64String() привел к тому, что он превратился в массив байтов, который не уничтожил бы метод Image.FromStream().

В общем, все свелось к моей глупой ошибке. Но эй, приведенный выше код по-прежнему полезен, и эта страница, вероятно, будет служить результатом Google, чтобы узнать, как избежать этой ошибки для кого-то еще.

Кроме того, я нашел простой способ создать многостраничный TIFF из моих байтовых массивов здесь.

Все это были подсказки, которые помогли мне разобраться в моей проблеме, которая была той же проблемой, что и вопрос. Итак, я хочу опубликовать свое решение, к которому я пришел благодаря этим полезным подсказкам. Спасибо за все опубликованные на данный момент подсказки!

Как написал Тайм Сондерс в своем ответе, этот метод Write для фактической записи байтов в поток памяти имеет важное значение. Это была моя первая ошибка.

Тогда мои данные тоже были плохими данными TIFF, но в моем случае у меня был дополнительный символ 13 в начале моих данных изображения. Как только я удалил это, у меня все заработало.

Когда я прочитал о некоторых основных спецификациях формата файлов TIFF, я обнаружил, что файлы TIFF должны начинаться с II или MM (два байта со значениями 73 или 77). II означает, что используется порядок байтов с прямым порядком байтов («порядок байтов Intel»). MM означает, что используется большой конец («порядок байтов Motorola»). Следующие два байта представляют собой двухбайтовое целочисленное значение (= Int16 в .NET) 42, двоичное 101010.

Таким образом, правильный поток байтов TIFF начинается с десятичных значений байтов: 73, 73, 42, 0 или 77, 77, 0, 42. Я призываю всех, у кого есть такая же проблема, с которой мы столкнулись, проверить ваш поток байтов данных TIFF и сделать убедитесь, что ваши данные являются действительными данными TIFF!

Спасибо Schnapple и Тиму Сондерсу !!

Другие вопросы по теме