Сохранение растрового изображения в файл имеет ноль в поле размера изображения

Когда я использую метод Bitmap.Save с форматом ImageFormat.Bmp, я обнаружил, что информация заголовка растрового изображения в файле имеет ноль в поле biSizeImage.

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

Итак, вопрос в том, как сделать так, чтобы это информационное поле заголовка всегда устанавливалось при сохранении растрового изображения?


person user380689    schedule 27.01.2011    source источник


Ответы (2)


Проблема, как вы подозреваете, в том, что 0 является вполне допустимым значением для поля размера изображения растрового изображения RGB. документация MSDN для структуры BITMAPINFOHEADER подтверждает этот факт:

biSizeImage
Размер изображения в байтах. Это может быть установлено равным нулю для растровых изображений BI_RGB.

Если biCompression равно BI_JPEG или BI_PNG, biSizeImage указывает размер буфера изображения JPEG или PNG соответственно.

Таким образом, реализация в .NET Framework просто делает все стандартным, задокументированным способом. Поскольку вам нужно что-то еще, вам придется самостоятельно обрабатывать процесс сохранения в файл, что позволит вам вручную изменить член biSizeImage структуры BITMAPINFOHEADER.

Довольно полный пример доступен здесь: Сохранение контрольного изображения в растровый файл. Конечно, он написан для Compact Framework, но большинство отдельных компонентов по-прежнему применимы. Вам потребуется P/вызвать несколько функций из Windows API (посетите www.pinvoke.net для определений) , и работать с DC.

Взять чертеж в свои руки, вероятно, также будет быстрее, потому что вы используете подсистему GDI, а не GDI+. Статью об этом общем подходе можно найти здесь: 1bpp на C#. чтобы продемонстрировать, как взять дело в свои руки с помощью структуры BITMAPINFOHEADER.

Если вы разбираетесь в неуправляемом коде C++, здесь доступно руководство, которое может дать вам некоторое представление о том, что вам нужно реализовать в C#, чтобы сделать то же самое: Загрузка и сохранение растровых изображений. Как видите, требуемый код на самом деле не такой длинный, хотя и больше, чем однострочный метод Bitmap.Save.

person Cody Gray    schedule 27.01.2011
comment
хорошо, спасибо, я надеялся избежать pinvoke, но похоже, что это единственный способ. - person user380689; 28.01.2011
comment
@ user380689: Я не знаю другого способа. Я думаю, проблема в том, как вы указали, что 0 является ожидаемым значением для члена biSaveImage. документация MSDN для структуры BITMAPINFOHEADER подтверждает это: это может быть установлено до нуля для растровых изображений BI_RGB. На самом деле константа BI_RGB имеет значение 0. .NET Framework работает стандартным, задокументированным способом. Если вам нужно что-то еще, вам придется взять дело в свои руки. - person Cody Gray; 28.01.2011

Я тоже столкнулся с этой проблемой, и она была решена с помощью простого трюка. сохраните растровое изображение, затем откройте его как файловый поток и измените поле biSizeimage вручную.

picbpp.Save("pic.bmp", ImageFormat.Bmp);
string path = "pic.bmp";
FileStream fs = File.Open(path, FileMode.Open, FileAccess.Write, FileShare.None);
// Change biSizeimage field manually.
Byte[] info = new byte[] {0x10,0x59};
fs.Seek(34, SeekOrigin.Begin);
fs.Write(info, 0, info.Length);
fs.Close();
person mohammad mohammadi bidmeshki    schedule 09.08.2018