AXForum  
Вернуться   AXForum > Microsoft Dynamics AX > DAX: Программирование
DAX
Забыли пароль?
Зарегистрироваться Правила Справка Пользователи Сообщения за день Поиск Все разделы прочитаны

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 25.02.2020, 17:59   #1  
Logger is offline
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
3,279 / 2179 (79) +++++++++
Регистрация: 12.10.2004
Адрес: Москва
Записей в блоге: 2
Поговорим о сохранении картинки в файл.
Всем привет.
Хотел обсудить, кто как сохраняет картинки в файл из аксапты.
Столкнулся со странным поведением.

Дано:
Ax4.0
В серверном коде из бд начитывается контейнер с картинкой. Нужно сохранить его в файл.
Перегоняем картинку в System.IO.MemoryStream а его уже сохраняем на диск.
Все хорошо работало.

Но! В какой-то момент попалась нехорошая картинка, при сохранении которой на диск выскакивала ошибка "A generic error occurred in GDI+."

Сохранение на диск через вызов
X++:
        image = System.Drawing.Image::FromStream(memoryStream);
        image.Save(_fileName);
падало на этой вредной картинке. При этом сохраняло только 72 кб из 286.

Если переделать вызов на
X++:
        byteArray = memoryStream.ToArray();
        netFile = _fileName;
        CLRInterop::staticInvoke(@'System.IO.File', @'WriteAllBytes', netFile, byteArray);
то все отлично работает.

Jpg файлы, получаемые этими методами - разные. При общем размере порядка 286 кб отличаются на 32 байта. При открытии в браузере IE визуально никакой разницы не заметно.


Вопрос:

1. Почему так происходит (ошибка GDI) ?
2. Почему размер и содержимое разное, хотя визуально разницы незаметно. Всегда ли так будет ?
3. Как правильно сохранять картинку в файл ?


P.S.
Зачем это было надо. В бд хранятся картинки, они начитываются, сохраняются на диск в виде файла, вставляются в Excel, который сохраняется как pdf отчет и отдается наружу через бизнес коннектор.

P.P.S. Image класс клиентский, поэтому для нашего случая не подходит.

P.P.P.S
Несколько ссылок где была подсказка при разработке исправленной версии:

1. В этой ссылке
https://habr.com/ru/post/482274/
идет критика System.Drawing и не рекомендуется его использовать при работе с изображениями в ASP.NET. Все из-за проблем с GDI и блокировками.

2. Здесь предложено решение:
https://stackoverflow.com/questions/...-save-the-file

Но нет уверенности, что результат эквивалентен и его везде можно применять.
Старый 26.02.2020, 07:37   #2  
dech is offline
dech
Участник
Аватар для dech
Самостоятельные клиенты AX
 
568 / 254 (10) ++++++
Регистрация: 25.06.2009
Адрес: Омск
Записей в блоге: 3
Не пробовали переделать вызов image.Save() на image.SaveImage()?
Или у вас падало именно на System.Drawing.Image::FromStream()?
__________________
// no comments

Последний раз редактировалось dech; 26.02.2020 в 07:39.
За это сообщение автора поблагодарили: Logger (3).
Старый 26.02.2020, 07:57   #3  
dech is offline
dech
Участник
Аватар для dech
Самостоятельные клиенты AX
 
568 / 254 (10) ++++++
Регистрация: 25.06.2009
Адрес: Омск
Записей в блоге: 3
Цитата:
Сообщение от Logger Посмотреть сообщение
2. Почему размер и содержимое разное, хотя визуально разницы незаметно. Всегда ли так будет ?
Честно говоря, я не знаю как у вас хранится картинка в БД. Обычно это bitmap, т.е. формат BMP. Если у вас JPG, то либо хранится у вас все же в BMP,а потом сохраняете в JPG, либо как-то хитро храните JPG, собственно из-за чего и возможны ошибки GDI+.

Немного о JPG. Этот формат подразумевает, что вы сжимаете данные с потерей качества. Соответственно при сохранении файла, вы должны указывать степень сжатия/потери качества. Если не указываете, используется какое-то стандартное значение. Поэтому в большинстве случаев размер и содержимое - разное. Например, у вас картинка содержит 300 цветов, сжатие с потерей качества уменьшает это количество до 256 цветов. Разницу глаз может и не заметить, особенно если нет плавных переходов, однако сжатие цвета до 1 байта дает существенное уменьшение размера.
__________________
// no comments
Старый 28.02.2020, 13:48   #4  
Logger is offline
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
3,279 / 2179 (79) +++++++++
Регистрация: 12.10.2004
Адрес: Москва
Записей в блоге: 2
Падало именно на image.Save()

Проанализировал получше в чем отличаются файлы.
Есть небольшое отличие в заголовке, и в середине jpg файла есть xml кусок, который в одном случае отформатирован (вставлены отступы и переносы кареток) а в другом случае - нет. С учетом этого включили новый способ сохранения везде в системе. Не думаю что это что-то поломает.

Никаких преобразований формата картинок мы не делали. У нас просто хранится в базе в контейнере jpg или png файл. Поэтому я не предполагал, что при сохранении бинарных данных на диск винда пытается с ними что-то дополнительное делать и как-то задействовать GDI ресурсы. То что виндовая функция image.Save() как-то задействовала GDI и пыталась делать некие обработки при сохранении - оказалось сюрпризом.
Теги
error, gdi, system.drawing.image, баг

 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
Как удалить меточный файл в 2012? macklakov DAX: Администрирование 8 04.11.2012 03:05
axforum blogs: Экспорт лицензии AX 4.0 и AX 2009 в файл Blog bot DAX Blogs 0 28.05.2012 16:11
SysMailer, отправка PDF, приходит пустой файл ena_ax DAX: Программирование 12 19.11.2010 10:56
Вывод отчета в файл в пакетном режиме Egor_bl DAX: Программирование 3 09.11.2006 09:36
Вывод отчета в файл в пакетном режиме Egor_bl DAX: Программирование 16 09.10.2006 19:10
Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

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

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход

Рейтинг@Mail.ru
Часовой пояс GMT +3, время: 14:15.
Powered by vBulletin® v3.8.5. Перевод: zCarot
Контактная информация, Реклама.