Программное формирование картинки в 1С:Предприятие 8.3.9 (ПотокВПамяти / ЗаписьДанных)

16.05.19

Разработка - Универсальные функции

В статье представлен код программного формирования картинки (двоичные данные) без всяких внешних компонент, без формирования строки Base64, используя лишь встроенные механизмы 1С предприятие 8.3.9 (объекты ПотокВПамяти и ЗаписьДанных). Сам по себе код формирования картинки не несёт ничего нового. Всё описано в википедии. Захотелось попробовать новые методы, но никак не доходитили руки. В приложении обработка практически с этим же кодом.

Скачать файлы

Наименование Файл Версия Размер
Формирование картинки.epf
.epf 9,37Kb
9
.epf 9,37Kb 9 Скачать
СправочникДляКартинок_ФормированиеКартинок.cf
.cf 19,16Kb
6
.cf 19,16Kb 6 Скачать

Приступим к делу.

Будем формировать картинку в два этапа:
1. Сначала подготовим данные картинки, т.н. RGB матрицу. Именно здесь мы рисуем нашу будущую картинку путём определения цвета каждого пикселя. Т.е., если нужно нарисовать что-то своё, то меняем код именно здесь. 
2. А потом по этим данным уже сформируем двоичные данные.
Листинг функций представлен ниже. Плюс небольшие замечания.

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

Итак, к делу:

Сначала вспомогательная функция формирования матрицы цветов пикселей. Собственно здесь мы описываем цвет каждого пикселя по его координатам.
Создаём двумерный массив высотой и шириной в пикселях с нашу картинку. Элементы массива - структура с RGB компонентами цвета. Не самый лучший вариант в плане производительности, но самый наглядный из тех, что я смог придумать.

&НаСервереБезКонтекста
Функция МатрицаЦветовRGB(Высота, Ширина)
	
	// Устанавливаем размеры матрицы по которой сформируется картинка
	ТекМатрицаЦветовRGB = Новый Массив(Высота, Ширина);
	
	Для Индекс1 = 1 По Высота Цикл
		Для Индекс2 = 1 По Ширина Цикл
			
			// Далее идёт установка цвета пикселя в зависимости от координат.
			// Именно этот код предполагается модифицировать
			#Область Определение_цвета_пикселя

			Если ((Cos(Индекс2/Ширина*5*3.14)/2+0.5)*0.6 + 0.4)*Высота > Индекс1 Тогда
				ТекКрасный 	= Цел(255*Индекс1/Высота);
				ТекЗеленый 	= 50;
				ТекСиний 	= 50;
			Иначе
				ТекКрасный = 255;
				ТекЗеленый = 255; 
				ТекСиний = 255; 
			КонецЕсли;			
					
			#КонецОбласти
			
			ТекМатрицаЦветовRGB[Индекс1-1][Индекс2-1] = Новый Цвет(ТекКрасный, ТекЗеленый, ТекСиний);
			
		КонецЦикла;
	КонецЦикла;	
	
	Возврат ТекМатрицаЦветовRGB
	
КонецФункции

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

&НаСервереБезКонтекста
Функция СоздатьКартинку(МатрицаЦветовRGB)
	
	Высота = МатрицаЦветовRGB.Количество();
	Ширина = МатрицаЦветовRGB[0].Количество();
	
	// Для простоты формирования возьемём 24 бита. По 8 бит на каждый канал. Альфаканал не используем. 
	ТекГлубинаЦвета = 3; // Измеряется в байтах. 	
	
	// Каждая строка должна содержать количество байтов кратное 4.
	БайтовДополнение = (4-ТекГлубинаЦвета*Ширина%4)%4; 
	
	РазмерФайла = ТекГлубинаЦвета*Ширина*Высота + Высота*БайтовДополнение;	
	
	///////////////////////////////////////////////////////////////////////////////
		
	ПотокТело = Новый ПотокВПамяти();
	ЗаписьДанных = Новый ЗаписьДанных(ПотокТело);
		
	//BITMAPFILEHEADER
	
	//bfType 
	ЗаписьДанных.ЗаписатьЦелое16(16973, ПорядокБайтов.BigEndian); // 0x424D big-endian = 0x4D42 little-endian. Признак формата. Всегда это значение.
	//bfSize
	ЗаписьДанных.ЗаписатьЦелое32(54 + РазмерФайла);
	//bfReserved1
	ЗаписьДанных.ЗаписатьЦелое16(0);	
	//bfReserved2
	ЗаписьДанных.ЗаписатьЦелое16(0);	
	//bfOffBits
	ЗаписьДанных.ЗаписатьЦелое32(54);
	
	//BITMAPINFOHEADER // версия 3
	// biSize
	ЗаписьДанных.ЗаписатьЦелое32(40); 
	// biWidth
	ЗаписьДанных.ЗаписатьЦелое32(Ширина);			// ширина изображения в пикселах 
	// biHeight
	ЗаписьДанных.ЗаписатьЦелое32(Высота);			// высота изображения в пикселах
	// biPlanes
	ЗаписьДанных.ЗаписатьЦелое16(1);				// содержит единицу
	// biBitCount
	ЗаписьДанных.ЗаписатьЦелое16(ТекГлубинаЦвета*8);	// количество бит на пиксел 
	// biCompression
	ЗаписьДанных.ЗаписатьЦелое32(0);				// тип сжатия 
	// biSizeImage
	ЗаписьДанных.ЗаписатьЦелое32(РазмерФайла);		// размер изображения в байтах
	// biXPelsPerMeter
	ЗаписьДанных.ЗаписатьЦелое32(0);				// горизонтальное разрешение в пикселах на метр 
	// biYPelsPerMeter
	ЗаписьДанных.ЗаписатьЦелое32(0); 				// вертикальное разрешение в пикселах на метр 
	// biClrUsed
	ЗаписьДанных.ЗаписатьЦелое32(0);				//  количество используемых цветовых индексов в палитре 
	// biClrImportant
	ЗаписьДанных.ЗаписатьЦелое32(0);				// количество индексов
	
	///////////////////////////////////////////////////////////////////////////////
		
	Для Выс = 1 По Высота Цикл	// строки снизу вверх		
			
		Для Шир = 1 По Ширина Цикл
			
			ЦветаПикселя = МатрицаЦветовRGB[Выс-1][Шир-1];
			ЗаписьДанных.ЗаписатьБайт(ЦветаПикселя.Синий);
			ЗаписьДанных.ЗаписатьБайт(ЦветаПикселя.Зеленый);
			ЗаписьДанных.ЗаписатьБайт(ЦветаПикселя.Красный);
						
		КонецЦикла;
		
		// Забиваем нулями остаток строки. Так как размер строки должен быть кратен 4 байтам.
		Для Доп = 1 По БайтовДополнение Цикл		
			ЗаписьДанных.ЗаписатьБайт(0); 
		КонецЦикла;
		
	КонецЦикла;
		
	ЗаписьДанных.Закрыть();
	
	ДвоичныеДанныеТело = ПотокТело.ЗакрытьИПолучитьДвоичныеДанные();
	
	Возврат ДвоичныеДанныеТело;
		
КонецФункции

 

Теперь вернёмся к вопросу об использовании. Почему-то в 1С у меня не хотели отображаться bmp-файлы. Даже, если я их создавал в паинте. Получилось обойти проблему с помощью встроенного метода Преобразовать, преобразовывая картинки в формат png:

ТекМатрицаЦветовRGB = МатрицаЦветовRGB(ВысотаКартинок, 200);
ТекКартинкаДвоичныеДанные = СоздатьКартинку(ТекМатрицаЦветовRGB);

ТекКартинка = Новый Картинка(ТекКартинкаДвоичныеДанные);
ТекКартинкаПНГ = ТекКартинка.Преобразовать(ФорматКартинки.PNG);

Здесь же на инфостарте был найден способ отображения картинок в табичной части / динамическом списке используя навигационные ссылки. Статью к сожалению, найти не могу. В кратце:
Создаём справочник КартинкиДляТаблицы с двумя реквизитами:
1. ДанныеКартинки - Тип: ХранилищеЗначения
2. АдресКартинки - Тип: Строка(0)

Формируем картинку, и записываем в элемент справочника:

 

// Создаём картинку
ТекКартинкаДвоичныеДанные = СоздатьКартинку(ТекМатрицаЦветовRGB);
ТекКартинка = Новый Картинка(ТекКартинкаДвоичныеДанные);

// Преобразуем в PNG
ТекКартинкаПНГ = ТекКартинка.Преобразовать(ФорматКартинки.PNG);	

// Создаём элемент справочника
НовЭлемент = Справочники.КартинкиДляТаблицы.СоздатьЭлемент();

// Прописываем наименование, если нужно
НовЭлемент.Наименование = "График1";

// Присваиваем данные картинки. Формат PNG уже сжат, поэтому тратить ресурсы на излишнее сжатие не будем.
НовЭлемент.ДанныеКартинки = Новый ХранилищеЗначения(ТекКартинкаПНГ, Новый СжатиеДанных(0));

// Записываем, так как для ПолучитьНавигационнуюСсылку нужна ссылка.
НовЭлемент.Записать();

// Получаем навигационную ссылку на реквзит "ДанныеКартинки" у данного элемента справочника
// и записываем полученное значение
НовЭлемент.АдресКартинки = ПолучитьНавигационнуюСсылку(НовЭлемент.Ссылка, "ДанныеКартинки");

// После чего сохраняем элемент справочника
НовЭлемент.Записать(); 

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

Запрос = Новый Запрос;
Запрос.Текст = 
"ВЫБРАТЬ
|	КартинкиДляТаблицы.Ссылка КАК Ссылка,
|	КартинкиДляТаблицы.АдресКартинки КАК АдресКартинки
|ИЗ
|	Справочник.КартинкиДляТаблицы КАК КартинкиДляТаблицы";
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
	НовСтрока = Таблица.Добавить();
	НовСтрока.Картинка = Выборка.АдресКартинки;
	НовСтрока.Справочник = Выборка.Ссылка;
КонецЦикла;

Вуаля:

 

В файлах:
1. обработка с этим кодом
2. выгрузка конфигурации с этим справочником картинок и обработкой.

картинка bmp программно

См. также

Вставляем картинку из буфера обмена (платформа 1С 8.3.24)

Универсальные функции Платформа 1С v8.3 Конфигурации 1cv8 Абонемент ($m)

Задача: вставить картинку из буфера обмена на форму средствами платформы 1С.

1 стартмани

18.03.2024    2678    1    John_d    8    

55

GUID в 1С 8.3 - как с ними быть

Универсальные функции Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

Пришлось помучиться с GUID-ами немного, решил поделиться опытом, мало ли кому пригодится.

12.02.2024    4614    atdonya    22    

45

Переоткрытие внешних обработок

Универсальные функции Платформа 1С v8.3 Бесплатно (free)

На заключительных этапах, когда идет отладка или доработка интерфейса, необходимо много раз переоткрыть внешний объект. Вот один из способов автоматизации этого.

30.11.2023    3963    ke.92@mail.ru    16    

61

Валидация JSON через XDTO (включая массивы)

WEB-интеграция Универсальные функции Механизмы платформы 1С Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

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

28.08.2023    8844    YA_418728146    6    

141

Печать непроведенных документов для УТ, КА, ERP. Настройка печати по пользователям, документам и печатным формам

Пакетная печать Печатные формы Адаптация типовых решений Универсальные функции Платформа 1С v8.3 1С:ERP Управление предприятием 2 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х Россия Абонемент ($m)

Расширение для программ 1С:Управление торговлей, 1С:Комплексная автоматизация, 1С:ERP, которое позволяет распечатывать печатные формы для непроведенных документов. Можно настроить, каким пользователям, какие конкретные формы документов разрешено печатать без проведения документа.

2 стартмани

22.08.2023    2077    21    progmaster    7    

3

Расширение: Быстрые отборы через буфер [Alt+C] Копировать список, [Alt+V] Вставить список, [Ctrl+C] Копировать из файлов

Инструментарий разработчика Универсальные функции Платформа 1С v8.3 Конфигурации 1cv8 1С:Розница 2 1С:ERP Управление предприятием 2 1С:Бухгалтерия 3.0 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х 1С:Зарплата и Управление Персоналом 3.x Абонемент ($m)

Копирует в буфер значения из списков, из ячеек отчетов, таблиц, настроек списков, других отборов и вставляет в выбранную настройку отбора. Работает с Объект не найден. Работает как в одной так и между разными базами 1С. Использует комбинации [Alt+C] Копировать список, [Alt+V] Вставить список. Также для копирования данных используется стандартная [Ctrl+C] (например из открытого xls, mxl, doc и т.п. файла скопировать список наименований)

1 стартмани

13.10.2022    16151    133    sapervodichka    112    

129

Система контроля ведения учета [БСП]

Универсальные функции Механизмы типовых конфигураций БСП (Библиотека стандартных подсистем) Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

В данном материале рассмотрим типовой алгоритм подсистемы контроля учета БСП в конфигурациях на примерах.

18.07.2022    7243    quazare    8    

109
Комментарии
В избранное Подписаться на ответы Сортировка: Древо развёрнутое
Свернуть все
1. Serj1C 483 17.05.19 11:39 Сейчас в теме
Круто!
Тоже с 2013 года хочу свою обработку адаптировать под новые возможности 8.3
https://infostart.ru/public/77713/

Как долго генерируется картинка?
2. yku 372 17.05.19 12:56 Сейчас в теме
(1) Пример из статьи: 25*200 пикселей. Рисунок тоже из статьи - герерируется за 0.17-0.20 сек в среднем.

Я твою кстати скачивал. И возможно часть кода из неё почерпнул.
Тоже хочу сделать команды для рисования.
5. KAV2 156 17.05.19 18:02 Сейчас в теме
(2) И создать обертку над ними в JS Canvas )).
3. Darklight 32 17.05.19 15:25 Сейчас в теме
Волны в примере бегут? Если нет динамики - то это не так интересно
6. yku 372 17.05.19 18:48 Сейчас в теме
(3) конечно бегут. Это же bmp. И статья так и называется: "создаём анимацию" нет.
nagimo; almierm; user1870444; mrChOP93; pavlov_dv; SlavaKron; oleg-m; tsmult; CyberCerber; Itilive.ru; +10 Ответить
4. Поручик 4670 17.05.19 15:35 Сейчас в теме
Пригодится на будущее
7. Жолтокнижниг 258 09.06.19 23:54 Сейчас в теме
Есть еще вариант формирования картинок - SVG, поддержка с 8.3.?

Увы 1с не умеет SVG анимацию.
8. frkbvfnjh 786 06.01.21 09:44 Сейчас в теме
Всё описано в википедии

Можете ссылку дать?
9. yku 372 08.01.21 11:41 Сейчас в теме
10. frkbvfnjh 786 08.01.21 11:54 Сейчас в теме
11. insurgut 207 02.02.21 06:46 Сейчас в теме
Первое, что вижу - генерация штрихкодов без компонент :)
nagimo; yku; +2 Ответить
Оставьте свое сообщение