Обработка, прикрепленная к статье, опять написана в стол и не имеет практического применения, но имея ее, конфигуратор и клавишу F10, думаю, понять, как там все устроено в bmp, гораздо легче. Потому помимо выкладок кода прикреплю и ее, хотя слепить такую же, скопировав код ниже - не составит проблем.
Так вот, поняв, что сначала надо разобраться с самим форматом, научиться его читать, я, естественно, подумал о "повороте" изображения. Но, вспомнив про встроенные методы платформы, которые позволяют делать это проще и быстрее, решил, что это не интересно.
Неинтересный поворот картинки:
Картинка = Новый Картинка("C:\My Documents\My Pictures\home.bmp");
ОбработчикКартинок = Новый ОбработкаКартинок;
Картинка_90 = ОбработчикКартинок.Повернуть(Картинка, 90);
Вопросы преобразования в 1С тоже более или менее решены:
Картинка.Преобразовать(ФорматКартинки.PNG);
В общем, решено было хотя бы просто считать картинку как набор двоичных данных и вывести ее на некую канву. Канвой послужил ТабДок :)) размер ячеек которого необходимо "зажать" до приемлемого размера пикселя и задать цвет фона ячейки, соответсвующий битмапу.
Описание формата bmp подробно расписано на вики: https://ru.wikipedia.org/wiki/BMP мы будем читать, полагая, что на вход нам подали файл версии №3. Декодер на все возможные версии занял бы много кода, да и не имеет практического смысла. Исходя из описания формата получилась следующая процедура чтения:
&НаКлиенте
Функция ДекодироватьИВывести(ПутьКФайлу)
ПотокИсходный = ФайловыеПотоки.ОткрытьДляЧтения(ПутьКФайлу);
ЧтениеДанных = Новый ЧтениеДанных(ПотокИсходный);
//читаем 14 байт соответствующих структуре описания файла
Буфер_BITMAPFILEHEADER = ЧтениеДанных.ПрочитатьВБуферДвоичныхДанных(14);
//для bitmap допустима сигнатура 424D или 4D42
Сигнатура = Буфер_BITMAPFILEHEADER.ПрочитатьЦелое16(0);
Если Сигнатура <> 19778 И Сигнатура <> 16973 Тогда
Возврат "Выбранный файл не является файлом формата bitmap";
КонецЕсли;
РазмерФайлБайт = Буфер_BITMAPFILEHEADER.ПрочитатьЦелое32(2);
ПоложениеМассиваПикселей = Буфер_BITMAPFILEHEADER.ПрочитатьЦелое32(10);
//т.к. читаем не все сразу (в образовательных целях)следующей итерацией просто считаем
//один байт, это будет адрес 0E. в нем содержится информация
//о размере следующей структуры - BITMAPINFO
Длина_BITMAPINFO = ЧтениеДанных.ПрочитатьЦелое32();
//пока мы работаем только с 3й версией файла,
//для него длина структуры BITMAPINFO заявлена
//длинной в 40 байт
Если Длина_BITMAPINFO <> 40 Тогда
Возврат "Выбранный файл является файлом bitmap неподходящей версии. Для чтения доступна только вер. 3.";
КонецЕсли;
//читаем BITMAPINFO
//вычитаем из длины структуры 4 байта т.к. выше мы их уже считали
//для определения длины
Буфер_BITMAPINFO = ЧтениеДанных.ПрочитатьВБуферДвоичныхДанных(Длина_BITMAPINFO - 4);
//расшифровка структуры 3й версии
//12 04 4 biWidth Ширина растра в пикселях. Указывается целым числом со знаком. Ноль и отрицательные не документированы.
//16 08 4 biHeight Целое число со знаком, содержащее два параметра: высота растра в пикселях (абсолютное значение числа) и порядок следования строк в двумерных массивах (знак числа). Нулевое значение не документировано.
//1A 0C 2 biPlanes В BMP допустимо только значение 1. Это поле используется в значках и курсорах Windows.
//1C 0E 2 biBitCount Количество бит на пиксель (список поддерживаемых смотрите в отдельном разделе ниже).
//1E 10 4 biCompression Указывает на способ хранения пикселей (см. в разделе ниже).
//22 14 4 biSizeImage Размер пиксельных данных в байтах. Может быть обнулено если хранение осуществляется двумерным массивом.
//26 18 4 biXPelsPerMeter Количество пикселей на метр по горизонтали и вертикали (см. раздел «Разрешение изображения» данной статьи).
//2A 1C 4 biYPelsPerMeter
//2E 20 4 biClrUsed Размер таблицы цветов в ячейках.
//32 24 4 biClrImportant Количество ячеек от начала таблицы цветов до последней используемой (включая её саму).
//мы ведь ЧтениеДанных продолжили считывать в новый буфер
//адресация теперь в пределах этого буфера (или другими словами - в пределах структуры BITMAPINFO)
ШиринаРастра = Буфер_BITMAPINFO.ПрочитатьЦелое32(0);
ВысотаРастра = Буфер_BITMAPINFO.ПрочитатьЦелое32(4);
Уровень = Буфер_BITMAPINFO.ПрочитатьЦелое16(8);
БитНаПиксель = Буфер_BITMAPINFO.ПрочитатьЦелое16(10);
Компрессия = Буфер_BITMAPINFO.ПрочитатьЦелое32(12);
БайтПикселей = Буфер_BITMAPINFO.ПрочитатьЦелое32(16);
ПикселейНаМетрГоризонт = Буфер_BITMAPINFO.ПрочитатьЦелое32(20);
ПикселейНаМетрВертикаль = Буфер_BITMAPINFO.ПрочитатьЦелое32(24);
РазмерТаблицыЦветов = Буфер_BITMAPINFO.ПрочитатьЦелое32(28);
ЯчеекТаблицыЦветов = Буфер_BITMAPINFO.ПрочитатьЦелое32(32);
//выведем подробное описание считанного
стрПредставление = "Размер файла: %1 байт
|Сигнатура: %2
|Положение массива пикселей: %3
|Длина структуры BITMAPINFO: %4 байт
|Ширина растра: %5 px
|Высота растра: %6 px
|Уровень: %7
|Бит на пиксель: %8 px
|Компрессия: %9
|Размер пикселей: %A байт
|Пикселей на метр по горизонтали: %B px
|Пикселей на метр по вертикали: %C px
|Размер таблицы цветов: %D байт
|Ячеек в таблице цветов: %F ";
ОписаниеФайла = ПодставитьПараметрыВСтроку(стрПредставление, РазмерФайлБайт, Сигнатура, ПоложениеМассиваПикселей,
Длина_BITMAPINFO, ШиринаРастра, ВысотаРастра, Уровень, БитНаПиксель,
Компрессия, БайтПикселей, ПикселейНаМетрГоризонт, ПикселейНаМетрВертикаль,
РазмерТаблицыЦветов, ЯчеекТаблицыЦветов);
//между структурами файла и массивом самих пикселей может быть
//не задействованный промежуток
//высчитаем его исходя из длины структур
ЧтениеДанных.Пропустить(ПоложениеМассиваПикселей - (14 + Длина_BITMAPINFO));
//теперь читаем поток до конца
БуферПикселей = ЧтениеДанных.ПрочитатьВБуферДвоичныхДанных();
ВывестиПотокНаКанвуТабДок(БуферПикселей, ШиринаРастра, ВысотаРастра, БитНаПиксель);
ЧтениеДанных.Закрыть();
КонецФункции
Процедуру вывода результата в ТабДок тоже приведу... Дело в том, что в bmp при количестве пикселей по горизонтали, не кратному 4 байтам, строка пикселей дополняется нулями. При выводе это надо учитывать, иначе изображение съедет по диагонали:
вот она:
&НаКлиенте
Функция ВывестиПотокНаКанвуТабДок(БуферПикселей, ШиринаКанвы, ВысотаКанвы, БитНаПиксель)
//рассчитаем длину строки в байт, т.к. для bmp
//строки не кратные четрым байтам заполняются
//не используемыми значениями - их нужно отсечь
ДействительныхБайт = ШиринаКанвы * 3;
ДлинаСтрокиБайт = Цел((ШиринаКанвы * 3) / 4) * 4;
ДлинаСтрокиБайт = ?(ДлинаСтрокиБайт < ДействительныхБайт, ДлинаСтрокиБайт + 4, ДлинаСтрокиБайт);
БайтНаДополнениеСтроки = ДлинаСтрокиБайт - (ШиринаКанвы * 3);
КурсорПикселя = -1;
КоординатаПикселя_R = ВысотаКанвы;
Пока КоординатаПикселя_R > 0 Цикл
Для КоординатаПикселя_C = 1 По ШиринаКанвы Цикл
ИмяПикселя = "R" + Формат(КоординатаПикселя_R, "ЧН=; ЧГ=") + "C" + Формат(КоординатаПикселя_C, "ЧН=; ЧГ=");
Пиксель = Канва.Область(ИмяПикселя);
Пиксель.ШиринаКолонки = 0.3;
Пиксель.ВысотаСтроки = 1;
КурсорПикселя = КурсорПикселя +1;
ЦветB = БуферПикселей[КурсорПикселя];
КурсорПикселя = КурсорПикселя +1;
ЦветG = БуферПикселей[КурсорПикселя];
КурсорПикселя = КурсорПикселя +1;
ЦветR = БуферПикселей[КурсорПикселя];
Пиксель.ЦветФона = Новый Цвет(ЦветR, ЦветG, ЦветB);
//смещаем курсор на размер пустых байт
Если КоординатаПикселя_C % ШиринаКанвы = 0 Тогда
КурсорПикселя = КурсорПикселя + БайтНаДополнениеСтроки;
КонецЕсли;
КонецЦикла;
КоординатаПикселя_R = КоординатаПикселя_R - 1;
КонецЦикла;
КонецФункции
В следующий раз нарисуем битмап, думаю, это опять будет картинка штрихкод EAN-13. Но когда дойдут руки до новой поделки - пока не знаю(
PS. Не давайте обработке большие файлы либо файлы с большим количеством цветов в палитре. Все-таки табличный документ не есть канва, и он плотно подвисает в попытках отрисовать сколько-нибудь серьезную картинку... 200х200 максимум и желательно минимум цветов при этом))
PSS. Тестовые картинки с лого Infostart - изображения Infostart - на всякий случай)