Создание приложения сканирования в Winforms с C #

Чтобы работать со сканером в WinForms с C # в Visual Studio, мы будем использовать WIA API. Windows Image Acquisition (WIA), иногда также называемая Windows Imaging Architecture), представляет собой модель драйвера Microsoft и интерфейс прикладного программирования (API) для Microsoft Windows 2000 и более поздних операционных систем, которые позволяют графическому программному обеспечению взаимодействовать с оборудованием для обработки изображений, таким как сканеры, цифровые камеры и цифровые Видео-оборудование.

WIA упрощает разработку приложений, производителей устройств и пользователей сканеров, которым необходимо взаимодействовать с оборудованием для обработки изображений. Набор API предоставляет приложениям обработки изображений аппаратную функциональность для получения неподвижных изображений, обеспечивая поддержку для:

  • Перечень доступных устройств захвата изображений (установленных сканеров в Windows).
  • Создание подключений к нескольким устройствам одновременно.
  • Запрос свойств устройств стандартным и расширяемым способом.
  • Получение данных устройства с использованием стандартных и высокопроизводительных механизмов передачи.
  • Поддержание свойств изображения при передаче данных.
  • Уведомление о состоянии устройства и обработка событий сканирования.

В этой статье вы узнаете, как управлять сканером изображений через WIA с помощью C #.

Требования

  • Visual Studio> = 2007 (мы собираемся использовать сообщество Visual Studio)
  • Установленный и работающий сканер

Давайте начнем !

1. Добавьте ссылку на WIA

Создайте новый проект WinForms с последней версией .NET Framework (или старым проектом C #). Затем перейдите к ссылке на компонент COM Image Acquisition Windows непосредственно из Visual Studio. Компонентная объектная модель (COM) — это независимая от платформы распределенная объектно-ориентированная система для создания бинарных программных компонентов, которые могут взаимодействовать. Компоненты .NET могут вызывать и взаимодействовать с компонентами COM.

Перейдите в обозреватель решений, расположенный в верхнем правом углу Visual Studio, и щелкните правой кнопкой мыши свой проект, затем нажмите «Добавить»> «Ссылка».

Добавить ссылку Visual Studio C #

В появившемся окне выберите параметр COM в левом меню, найдите библиотеку Microsoft Windows Image Acquisition v2.0 и нажмите OK.

WIA C # COM Ссылка на компонент

Как только вы нажмете «ОК», ссылка будет добавлена ​​в ваш проект. Теперь вам нужно установить Вставить типы взаимодействия свойство компонента WIA для False, В Visual Studio перейдите в Обозреватель решений и выберите свой проект, затем в своем проекте нажмите «Ссылки» в компоненте древовидного представления и выполните поиск WIA. Выберите ссылку на WIA, найдите параметр «Вставить типы взаимодействия» на панели «Свойства» и установите для этого значения значение False:

Встроить типы взаимодействия WIA C #

Теперь вы сможете использовать WIA в своем проекте.

2. Список сканеров устройств

Чтобы составить список устройств, вам нужно получить список из объекта DevicesManager WIA. В качестве первого шага вам нужно импортировать компонент WIA в ваш код в верхней части вашего класса:

using WIA;

Затем просто переберите диспетчер устройств, чтобы получить список устройств:

// Create a DeviceManager instance
var deviceManager = new DeviceManager();
// Loop through the list of devices
for (int i = 1; i <= deviceManager.DeviceInfos.Count; i++)
{
// Skip the device if it's not a scanner
if (deviceManager.DeviceInfos[i].Type != WiaDeviceType.ScannerDeviceType)
{
continue;
}
// Print something like e.g "WIA Canoscan 4400F"
Console.WriteLine(deviceManager.DeviceInfos[i].Properties["Name"].get_Value());
// e.g Canoscan 4400F
//Console.WriteLine(deviceManager.DeviceInfos[i].Properties["Description"].get_Value());
// e.g \\.\Usbscan0
//Console.WriteLine(deviceManager.DeviceInfos[i].Properties["Port"].get_Value());
}

Объект Properties имеет другие свойства, такие как Id, Port, Manufacturer а также Type, посетите страницу MSDN о классе информации устройства WIA для получения дополнительной информации.

3. Использование устройства для сканирования

Для сохранения отсканированного изображения вам потребуется импортировать следующие типы:

using WIA;
using System.IO;

Тогда логика использования сканера следующая:

  1. Получить DeviceInfo экземпляр сканера, который вы хотите использовать.
  2. Подключитесь к сканеру, используя экземпляр DeviceInfo.
  3. Выберите сканер через элемент с индексом 1 внутри свойства items с экземпляром соединения.
  4. Используйте метод Передачи выбранного сканера и укажите в качестве первого аргумента формат вывода отсканированного изображения.
  5. Сохраните возвращенные данные изображения в файл.

Предыдущая логика реализована с помощью следующего кода. Мы собираемся выбрать первый доступный сканер в системе, и мы будем следовать предыдущему алгоритму:

Заметка

Процесс выбора сканера и последующего использования оставшегося кода для запуска процесса сканирования может быть немного сложным, если вы не справитесь с этим должным образом. Мы рекомендуем вам, например, добавить элемент списка в форму и добавить новый элемент, который отображает имя и объект DeviceInfos тоже (пример вы увидите в конце статьи).

 // Create a DeviceManager instance
var deviceManager = new DeviceManager();
// Create an empty variable to store the scanner instance
DeviceInfo firstScannerAvailable = null;
// Loop through the list of devices to choose the first available
for (int i = 1; i <= deviceManager.DeviceInfos.Count; i++)
{
// Skip the device if it's not a scanner
if (deviceManager.DeviceInfos[i].Type != WiaDeviceType.ScannerDeviceType)
{
continue;
}
firstScannerAvailable = deviceManager.DeviceInfos[i];
break;
}
// Connect to the first available scanner
var device = firstScannerAvailable.Connect();
// Select the scanner
var scannerItem = device.Items[1];
// Retrieve a image in JPEG format and store it into a variable
var imageFile = (ImageFile)scannerItem.Transfer(FormatID.wiaFormatJPEG);
// Save the image in some path with filename
var path = @"C:\Users\\Desktop\scan.jpeg";
if (File.Exists(path))
{
File.Delete(path);
}
// Save image !
imageFile.SaveFile(path);

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

4. Изменение свойств WIA

Существует несколько изменяемых свойств WIA, таких как ширина и высота сканирования, цветовой режим и т. Д. Чтобы установить эти свойства, нам нужно получить свойство WIA.Properties класс, а затем установить новое значение. Импортируйте требуемые типы первыми:

using WIA;
using System.IO;

Следующий метод AdjustScannerSettings установит некоторые основные свойства через вспомогательную функцию SetWIAProperty, чтобы заставить его работать, по крайней мере, в большинстве сканирующих устройств. Обратите внимание, что вам нужно предоставить элемент сканера в качестве первого параметра в AdjustScannerSettings (сканер выбрал и назначил переменной через элемент с индексом 1 в свойстве items в экземпляре соединения) и другие параметры, которые документированы в функции.

Важный

Помните, что в WIA есть множество констант свойств, которые вы можете изменить, и которые могут быть или не доступны на разных сканирующих устройствах (например для изменения горизонтального разрешения используйте константу 6147), прочитайте следующую страницу MSDN для получения дополнительной информации.

///
/// Adjusts the settings of the scanner with the providen parameters.
///
/// Scanner Item
/// Provide the DPI resolution that should be used e.g 150
///
///
///
///
///
/// Modify the contrast percent
/// Set the color mode
private static void AdjustScannerSettings(IItem scannnerItem, int scanResolutionDPI, int scanStartLeftPixel, int scanStartTopPixel, int scanWidthPixels, int scanHeightPixels, int brightnessPercents, int contrastPercents, int colorMode)
{
const string WIA_SCAN_COLOR_MODE = "6146";
const string WIA_HORIZONTAL_SCAN_RESOLUTION_DPI = "6147";
const string WIA_VERTICAL_SCAN_RESOLUTION_DPI = "6148";
const string WIA_HORIZONTAL_SCAN_START_PIXEL = "6149";
const string WIA_VERTICAL_SCAN_START_PIXEL = "6150";
const string WIA_HORIZONTAL_SCAN_SIZE_PIXELS = "6151";
const string WIA_VERTICAL_SCAN_SIZE_PIXELS = "6152";
const string WIA_SCAN_BRIGHTNESS_PERCENTS = "6154";
const string WIA_SCAN_CONTRAST_PERCENTS = "6155";
SetWIAProperty(scannnerItem.Properties, WIA_HORIZONTAL_SCAN_RESOLUTION_DPI, scanResolutionDPI);
SetWIAProperty(scannnerItem.Properties, WIA_VERTICAL_SCAN_RESOLUTION_DPI, scanResolutionDPI);
SetWIAProperty(scannnerItem.Properties, WIA_HORIZONTAL_SCAN_START_PIXEL, scanStartLeftPixel);
SetWIAProperty(scannnerItem.Properties, WIA_VERTICAL_SCAN_START_PIXEL, scanStartTopPixel);
SetWIAProperty(scannnerItem.Properties, WIA_HORIZONTAL_SCAN_SIZE_PIXELS, scanWidthPixels);
SetWIAProperty(scannnerItem.Properties, WIA_VERTICAL_SCAN_SIZE_PIXELS, scanHeightPixels);
SetWIAProperty(scannnerItem.Properties, WIA_SCAN_BRIGHTNESS_PERCENTS, brightnessPercents);
SetWIAProperty(scannnerItem.Properties, WIA_SCAN_CONTRAST_PERCENTS, contrastPercents);
SetWIAProperty(scannnerItem.Properties, WIA_SCAN_COLOR_MODE, colorMode);
}
///
/// Modify a WIA property
///
///
///
///
private static void SetWIAProperty(IProperties properties, object propName, object propValue)
{
Property prop = properties.get_Item(ref propName);
prop.set_Value(ref propValue);
}

Стоит сказать еще раз, это зависит от вас, настройки свойств, но мы предоставляем вам простой способ настроить их с помощью SetWIAProperty метод.

Наконец, чтобы правильно запустить сканирование, вам просто нужно выполнить AdjustScannerSettings Метод перед инициализацией сканера (смешивание шагов 3 и 4):

// Create a DeviceManager instance
var deviceManager = new DeviceManager();
// Create an empty variable to store the scanner instance
DeviceInfo firstScannerAvailable = null;
// Loop through the list of devices to choose the first available
for (int i = 1; i <= deviceManager.DeviceInfos.Count; i++)
{
// Skip the device if it's not a scanner
if (deviceManager.DeviceInfos[i].Type != WiaDeviceType.ScannerDeviceType)
{
continue;
}
firstScannerAvailable = deviceManager.DeviceInfos[i];
break;
}
// Connect to the first available scanner
var device = firstScannerAvailable.Connect();
// Select the scanner
var scannerItem = device.Items[1];
/**
* Set the scanner settings
*/
int resolution = 150;
int width_pixel = 1250;
int height_pixel = 1700;
int color_mode = 1;
AdjustScannerSettings(scannerItem, resolution, 0, 0, width_pixel, height_pixel, 0, 0, color_mode);
// Retrieve a image in JPEG format and store it into a variable
var imageFile = (ImageFile)scannerItem.Transfer(FormatID.wiaFormatJPEG);
// Save the image in some path with filename
var path = @"C:\Users\\Desktop\scan.jpeg";
if (File.Exists(path))
{
File.Delete(path);
}
// Save image !
imageFile.SaveFile(path);

5. Ловля исключений

Методы функций WIA могут генерировать исключения, которые можно идентифицировать с помощью кодов ошибок. Список кодов ошибок можно найти в документация WIA на сайте MSDN здесь. Чтобы обработать ошибки WIA, перехватите объект COMException. Не забудьте предварительно импортировать InteropServices тип:

using System.Runtime.InteropServices;

А затем оберните код, который использует WIA, в оператор try-catch. Вы можете идентифицировать ошибку с помощью свойства ErrorCode исключения, но не забудьте преобразовать ее в представление uint, чтобы иметь возможность сравнить ее с коды ошибок таблицы в MSDN.

try
{
// Some code that uses WIA
// e.g
//
// var device = firstScannerAvailable.Connect();
// var scannerItem = device.Items[1];
// var imageFile = (ImageFile)scannerItem.Transfer(FormatID.wiaFormatJPEG);
}
catch (COMException e)
{
// Convert the error code to UINT
uint errorCode = (uint)e.ErrorCode;
// See the error codes
if (errorCode ==  0x80210006)
{
Console.WriteLine("The scanner is busy or isn't ready");
}
else if(errorCode == 0x80210064)
{
Console.WriteLine("The scanning process has been cancelled.");
}
else if(errorCode == 0x8021000C)
{
Console.WriteLine("There is an incorrect setting on the WIA device.");
}
else if(errorCode == 0x80210005)
{
Console.WriteLine("The device is offline. Make sure the device is powered on and connected to the PC.");
}
else if(errorCode == 0x80210001)
{
Console.WriteLine("An unknown error has occurred with the WIA device.");
}
}

6. Отображение прогресса сканирования

Чтобы показать прогресс сканера, вы можете использовать ShowTransfer метод CommonDialogClass, Элемент управления CommonDialog - это элемент управления невидимым во время выполнения, который можно создать с помощью «WIA.CommonDialog» в качестве ProgID при вызове CreateObject или путем удаления объекта CommonDialog в форме. Вы можете получить изображение, преобразовав результат сканирования (объект, возвращенный из ShowTransfer метод) к ImageFile тип.

Диалог процесса сканирования WIA

Этот метод отображает мини-диалог с индикатором выполнения, который указывает и обновляется в процессе сканирования. В качестве первого параметра он ожидает элемент сканера, в качестве второго параметра - формат отсканированного изображения, а в качестве третьего параметра - логическое значение, указывающее, должна ли отображаться кнопка Отмена сканирования или нет. Если пользователь отменяет процесс сканирования, следует помнить о добавлении оператора try-catch, чтобы предотвратить сбой приложения. Импортируйте следующие типы вверху вашего класса:

using WIA;
using System.Runtime.InteropServices;

Затем выберите сканер и запустите процесс сканирования.

// Create a DeviceManager instance
var deviceManager = new DeviceManager();
// Create an empty variable to store the scanner instance
DeviceInfo firstScannerAvailable = null;
// Loop through the list of devices to choose the first available
for (int i = 1; i <= deviceManager.DeviceInfos.Count; i++)
{
// Skip the device if it's not a scanner
if (deviceManager.DeviceInfos[i].Type != WiaDeviceType.ScannerDeviceType)
{
continue;
}
firstScannerAvailable = deviceManager.DeviceInfos[i];
break;
}
// Connect to the first available scanner
var device = firstScannerAvailable.Connect();
// Select the scanner
var scannerItem = device.Items[1];
CommonDialogClass dlg = new CommonDialogClass();
try
{
object scanResult = dlg.ShowTransfer(scannerItem, WIA.FormatID.wiaFormatPNG, true);
if (scanResult != null){
ImageFile image = (ImageFile)scanResult;
// Do the rest of things as save the image
}
}
catch (COMException e)
{
// Display the exception in the console.
Console.WriteLine(e.ToString());
uint errorCode = (uint)e.ErrorCode;
// Catch 2 of the most common exceptions
if (errorCode ==  0x80210006)
{
Console.WriteLine("The scanner is busy or isn't ready");
}else if(errorCode == 0x80210064)
{
Console.WriteLine("The scanning process has been cancelled.");
}
}

Со всеми этими основными инструкциями вы сможете создать собственное приложение для сканирования в WinForms с C #.

Пример реализации

Мы только что написали пример приложения в этом списке перечислены все доступные устройства сканера в списке и вы можете сканировать и сохранять файл по произвольному пути. Он реализует диалог прогресса сканирования и позволяет сохранять изображение в различных форматах, таких как PNG, JPEG или TIFF:

Пример сканирования приложения

Просто клонируйте репозиторий, откройте проект с Visual Studio и протестируйте его. Исходный код можно найти в это хранилище Github.

Ссылка на основную публикацию
Adblock
detector