Сканирование WIA-драйвером в Библиотеке Стандартных Подсистем

06.07.18

Разработка - БСП (Библиотека стандартных подсистем)

Не секрет, что в БСП не реализована функция получения изображений посредством WIA-драйвера. Однако такая потребность частенько появляется. К примеру, сетевые принтеры и веб-камеры, работающие через стандартный Windows-интерфейс WIA, остаются не у дел. Давайте исправим такую несправедливость!

Описанный прием работает в любой конфигурации, использующей подсистему Работа с файлами из состава БСП.

Внимание! Для этого нам понадобится вмешаться в работу общего модуля РаботаСФайламиСлужебныйКлиент и форму РезультатСканирования обработки Сканирование. Имейте это в виду при обновлении БСП.

Итак, начнем.

1. В общем модуле РаботаСФайламиСлужебныйКлиент нам надо модифицировать экспортную функцию ПроинициализироватьКомпоненту. Суть модификации - если компонента TWAIN не была установлена, то попытаться подсунуть вместо нее нашу компоненту WIA. В разных версиях БСП код незначительно различается, но у меня это выглядит так:

Для БСП 2.4.х.х:

// Инициализация компоненты сканирования.
Функция ПроинициализироватьКомпоненту() Экспорт
	
	СистемнаяИнформация = Новый СистемнаяИнформация;
	Если СистемнаяИнформация.ТипПлатформы <> ТипПлатформы.Windows_x86
		Или ОбщегоНазначенияКлиентСервер.ЭтоВебКлиент() Тогда 
		Возврат Ложь;
	КонецЕсли;
	
	ИмяПараметра = "СтандартныеПодсистемы.КомпонентаTwain";
	Если ПараметрыПриложения[ИмяПараметра] = Неопределено Тогда
		
		// Вызов метода ОбщегоНазначенияКлиент.ПодключитьКомпонентуИзМакета не требуется т.к.
		// Внешняя компонента подключается из макета и сканирование не доступно в веб-клиенте.
		КодВозврата = ПодключитьВнешнююКомпоненту("ОбщийМакет.КомпонентаTWAIN", "twain", ТипВнешнейКомпоненты.Native);
		Если Не КодВозврата Тогда
			Попытка
				ПроверкаНаличияИнтерфейсов = СканированиеWIAКлиент.ПолучитьИнтерфейсWIA();
				ПараметрыПриложения.Вставить(ИмяПараметра, СканированиеWIAКлиент.ЭтотОбъект);
				ПараметрыПриложения.Вставить("СтандартныеПодсистемы.ИнтерфейсWIA", СканированиеWIAКлиент.ПолучитьИнтерфейсWIA());
				Возврат Истина;
			Исключение
				Возврат Ложь;
			КонецПопытки;
		КонецЕсли;
		
		ПараметрыПриложения.Вставить(ИмяПараметра, Новый("AddIn.twain.AddInNativeExtension"));
	КонецЕсли;
	
	Возврат Истина;
	
КонецФункции

Для БСП 3.0.х.х:

// Инициализация компоненты сканирования.
Функция ПроинициализироватьКомпоненту(ПопытатьсяУстановитьКомпоненту = Истина) Экспорт
	
	СистемнаяИнформация = Новый СистемнаяИнформация;
	Если СистемнаяИнформация.ТипПлатформы <> ТипПлатформы.Windows_x86
		Или ОбщегоНазначенияКлиентСервер.ЭтоВебКлиент() Тогда 
		Возврат Ложь;
	КонецЕсли;
	
	ИмяПараметра = "СтандартныеПодсистемы.КомпонентаTwain";
	Если ПараметрыПриложения[ИмяПараметра] = Неопределено Тогда
		
		// Вызов метода ОбщегоНазначенияКлиент.ПодключитьКомпонентуИзМакета не требуется т.к.
		// Внешняя компонента подключается из макета и сканирование не доступно в веб-клиенте.
		КодВозврата = ПодключитьВнешнююКомпоненту("ОбщийМакет.КомпонентаTWAIN", "twain");
		Если Не КодВозврата Тогда
				
			Если Не ПопытатьсяУстановитьКомпоненту Тогда
				Попытка
					ПроверкаНаличияИнтерфейсов = СканированиеWIAКлиент.ПолучитьИнтерфейсWIA();
					ПараметрыПриложения.Вставить(ИмяПараметра, СканированиеWIAКлиент.ЭтотОбъект);
					ПараметрыПриложения.Вставить("СтандартныеПодсистемы.ИнтерфейсWIA", СканированиеWIAКлиент.ПолучитьИнтерфейсWIA());
					Возврат Истина;
				Исключение
					Возврат Ложь;
				КонецПопытки;
			КонецЕсли;
			
			НачатьУстановкуВнешнейКомпоненты(, "ОбщийМакет.КомпонентаTWAIN");
			
			Возврат ПроинициализироватьКомпоненту(Ложь); // Рекурсивно.
			
		КонецЕсли;
		
		ПараметрыПриложения.Вставить(ИмяПараметра, Новый("AddIn.twain.AddInNativeExtension"));
	КонецЕсли;
	
	Возврат Истина;
	
КонецФункции

2. В форме РезультатСканирования обработки Сканирование добавляем обработчик события ОбработкаОповещения, который будет перенаправлять реакцию от диалогового окна сканирования WIA на стандартный обработчик ВнешнееСобытие.

&НаКлиенте
Процедура ОбработкаОповещения(ИмяСобытия, Параметр, Источник)
	
	Если Источник = "WIA" Тогда
		ВнешнееСобытие("TWAIN", ИмяСобытия, Параметр);
	КонецЕсли;
	
КонецПроцедуры

3. Добавляем общий модуль СканированиеWIAКлиент с флажками Клиент (управляемое приложение) и Клиент (обычное приложение) и следующим нехитрым содержанием:


Функция ПолучитьИнтерфейсWIA() Экспорт
	
	Соответсвие = Новый Соответствие;
	
	Соответсвие.Вставить("DeviceManager", Новый COMОбъект("WIA.DeviceManager"));
	Соответсвие.Вставить("ImageFile", Новый COMОбъект("WIA.ImageFile"));
	Соответсвие.Вставить("CommonDialog", Новый COMОбъект("WIA.CommonDialog"));
	Соответсвие.Вставить("ImageProcess", Новый COMОбъект("WIA.ImageProcess"));
	
	Возврат Соответсвие;
	
КонецФункции

Функция ЕстьУстройства() Экспорт
	
	DeviceInfos = ПараметрыПриложения["СтандартныеПодсистемы.ИнтерфейсWIA"]["DeviceManager"].DeviceInfos();
	Возврат DeviceInfos.Count() > 0;
	
КонецФункции

Функция ПолучитьУстройства() Экспорт
	
	Массив = Новый Массив;
	
	Для Каждого DeviceInfo Из ПараметрыПриложения["СтандартныеПодсистемы.ИнтерфейсWIA"]["DeviceManager"].DeviceInfos() Цикл
		Массив.Добавить(DeviceInfo.Properties("Name").Value);
	КонецЦикла;
	
	Возврат СтрСоединить(Массив, Символы.ПС);
	
КонецФункции

Функция ПолучитьУстройство(ИмяУстройства)
	
	Для Каждого DeviceInfo Из ПараметрыПриложения["СтандартныеПодсистемы.ИнтерфейсWIA"]["DeviceManager"].DeviceInfos() Цикл
		Если DeviceInfo.Properties("Name").Value = ИмяУстройства Тогда
			Возврат DeviceInfo;
		КонецЕсли;
	КонецЦикла;
	
	Возврат Неопределено;
	
КонецФункции

Функция ПолучитьНастройку(ИмяУстройства, ИмяНастройки) Экспорт
	
	CurrentDeviceInfo = ПолучитьУстройство(ИмяУстройства);
	
	Если CurrentDeviceInfo = Неопределено Тогда
		Возврат -1;
	КонецЕсли;
	
	Если ИмяНастройки = "XRESOLUTION" Тогда
		
	ИначеЕсли ИмяНастройки = "YRESOLUTION" Тогда
		
	КонецЕсли;
	
	Возврат -1;
	
КонецФункции

Процедура НачатьСканирование(ПоказыватьДиалог,
								ИмяУстройства, 
								ФорматКартинки, 
								Разрешение, 
								Цветность, 
								Поворот, 
								РазмерБумаги,
								ПараметрСжатие,
								ДвустороннееСканирование) Экспорт
	
	CurrentDeviceInfo = ПолучитьУстройство(ИмяУстройства);
	
	Если CurrentDeviceInfo = Неопределено Тогда
		Возврат;
	КонецЕсли;
	
	СоответствиеФорматID = Новый Соответствие;
	СоответствиеФорматID.Вставить(-1, "{B96B3CAF-0728-11D3-9D7B-0000F81EF32E}");
	СоответствиеФорматID.Вставить("BMP", "{B96B3CAB-0728-11D3-9D7B-0000F81EF32E}");
	СоответствиеФорматID.Вставить("PNG", "{B96B3CAF-0728-11D3-9D7B-0000F81EF32E}");
	СоответствиеФорматID.Вставить("GIF", "{B96B3CB0-0728-11D3-9D7B-0000F81EF32E}");
	СоответствиеФорматID.Вставить("JPG", "{B96B3CAE-0728-11D3-9D7B-0000F81EF32E}");
	СоответствиеФорматID.Вставить("JPEG", "{B96B3CAE-0728-11D3-9D7B-0000F81EF32E}");
	СоответствиеФорматID.Вставить("TIFF", "{B96B3CB1-0728-11D3-9D7B-0000F81EF32E}");
	
	СоответствиеЦветностьID = Новый Соответствие;
	СоответствиеЦветностьID.Вставить(-1, 0);	//Не задано
	СоответствиеЦветностьID.Вставить(0, 4);		//Монохромное (текст)
	СоответствиеЦветностьID.Вставить(1, 2);		//Чернобелое
	СоответствиеЦветностьID.Вставить(2, 1);		//Цветное

	ImageFile = ПараметрыПриложения["СтандартныеПодсистемы.ИнтерфейсWIA"]["ImageFile"];
	CommonDialog = ПараметрыПриложения["СтандартныеПодсистемы.ИнтерфейсWIA"]["CommonDialog"];
	
	WiaDeviceType = 1; //Сканер
	WiaImageIntent = СоответствиеЦветностьID.Получить(Цветность);
	WiaMaximizeQuality = 131072;
	WiaMinimizeSize = 65536;
	WiaImageBias = ?(Разрешение = -1 ИЛИ Разрешение > 300, WiaMaximizeQuality, WiaMinimizeSize);
	
	Image = CommonDialog.ShowAcquireImage(WiaDeviceType, WiaImageIntent, WiaImageBias, СоответствиеФорматID.Получить(ФорматКартинки));
	Если Image = Неопределено Тогда
		Оповестить("UserPressedCancel", Неопределено, "WIA");
		Возврат;
	КонецЕсли;
	//ImageProcess = ПараметрыПриложения["СтандартныеПодсистемы.ИнтерфейсWIA"]["ImageProcess"];
	//ImageProcess.Filters.Add(ImageProcess.FilterInfos("Convert").FilterID);
	//ImageProcess1 = ImageProcess.Filters(1);
	//Для К = 1 По ImageProcess1.Properties.Count Цикл
	//	Если ImageProcess1.Properties(К).Name = "FormatID" Тогда
	//		ImageProcess1.Properties(К).Value = СоответствиеФорматID.Получить(ФорматКартинки);
	//		Прервать;
	//	КонецЕсли;
	//КонецЦикла;
	//
	//Image = ImageProcess.Apply(Image); //применяем фильтр на изображение
	
	ИмяФайла = ПолучитьИмяВременногоФайла(ФорматКартинки);
	
    Image.SaveFile(ИмяФайла); //сохраним на жесткий диск объект WIA
	
	Оповестить("ImageAcquired", ИмяФайла, "WIA");
	
КонецПроцедуры

Вуаля!

TWAIN WIA

См. также

Создать на основании - своя кнопка (БСП). Проблема двух подменю Создать на основании

БСП (Библиотека стандартных подсистем) Адаптация типовых решений Платформа 1С v8.3 1С:ERP Управление предприятием 2 Бесплатно (free)

Понадобилось в подменю "Создать на основании" добавить свою команду, которая открывает обработку. В процессе доработок появилась проблема двух подменю "Создать на основании". В статье о том, как решились проблемы.

01.03.2024    1281    dimanich70    6    

13

Заполнение поля адреса в своей обработке [БСП]

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

Небольшая шпаргалка по функциям БСП касательно адреса. Так скажем, еще один способ помимо https://infostart.ru/1c/articles/1060970/

12.02.2024    686    FilippovRI    0    

15

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

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

Уже не одна веб-страница исписана знаниями о дополнительных обработках, как создать, как подключить. Есть масса вариантов, как их можно отладить. Я разобрался в кишках работы библиотеки и покажу, как можно расширить возможности дополнительных отчетов, а также покажу удобный способ отладки.

07.02.2024    2347    YA_418728146    11    

40

1С:БСП Дополнительные реквизиты и сведения

БСП (Библиотека стандартных подсистем) Платформа 1С v8.3 Бесплатно (free)

В этой статье расскажем об архитектуре, использовании и особенностях реализации подсистемы «Свойства» из инструментария разработчика «1С:Библиотека стандартных подсистем» (1С: БСП).

19.01.2024    5144    PROSTO-1C    5    

45

Бесплатный митап 9 февраля «Библиотеки и фреймворки на 1С и всё, что с этим связано»

БСП (Библиотека стандартных подсистем) Мероприятия Бесплатно (free)

Митап посвящен вопросам создания, использования и поддержке переиспользуемого кода при разработке решений на платформе 1С:Предприятие 8.

15.01.2024    3795    0    Infostart    0    

20

Шаблоны новых объектов 1С для 1С:Бухгалтерии предприятия

Инструментарий разработчика БСП (Библиотека стандартных подсистем) Механизмы типовых конфигураций Платформа 1С v8.3 1С:Бухгалтерия 3.0 Бесплатно (free)

Используются для создания новых объектов в конфигурации, чтобы не забыть, что нужно сделать. Сделано на примере 1С:Бухгалтерия предприятия, в других конфигурациях могут быть другие, а могут быть и похожие объекты.

28.12.2023    4823    mrXoxot    11    

99
Комментарии
В избранное Подписаться на ответы Сортировка: Древо развёрнутое
Свернуть все
1. DmitrySinichnikov 285 10.10.18 00:42 Сейчас в теме
Доброй ночи! Спасибо за описание работы с компонентой.
Вы не могли бы подсказать где вы нашли документацию по работе с ней. Я перечитал всю портянку мелкомягких https://docs.microsoft.com/ru-ru/windows/desktop/wia/-wia-startpage но не нашел описания работы с wia через ком. Например WIA.CommonDialog, откуда вы взяли данную команду, что она выполняет и т.д. Очень хотелось бы разобраться самому досконально, но либо я туплю либо инфа "секретная".
2. nuctoh 31 10.10.18 10:47 Сейчас в теме
(1) День добрый! Мне на глаза в свое время попался макрос на VB. Кто его писал - ХЗ. Когда у меня возникла вышеописанная задача в 1С, я просто нашел его и портировал.
3. dikar40 8 26.12.19 16:42 Сейчас в теме
Добрый вечер, с сетевым сканером не заработало. Показывает, что подключенных сканеров нет.
 Device = Новый COMОбъект("WIA.DeviceManager");
    DeviceInfo = Device.DeviceInfos();
DeviceInfo.Count()=0
Оставьте свое сообщение