Fazer scan a partir da sua app

Este tópico descreve como digitalizar conteúdo da sua aplicação usando um scanner plano, alimentador ou uma fonte de digitalização auto-configurada.

Obtenha um scanner

Para digitalizar a partir da sua aplicação, deve primeiro obter um scanner disponível que esteja ligado ao computador. Apenas os scanners instalados localmente com controladores Windows Image Acquisition (WIA) são apresentados e ficam disponíveis para a sua aplicação.

Para obter um scanner ligado ao computador, pode utilizar a interface do sistema DevicePicker ou outras APIs de Windows.Devices.Enumeration, como mostrado em Enumerate devices. Em qualquer dos casos, pode usar o valor DeviceClass.ImageScanner como filtro para que o DevicePicker ou o DeviceWatcher mostrem apenas dispositivos scanner de imagem.

As APIs de enumeração de dispositivos dão-lhe um objeto DeviceInformation que representa um dispositivo ligado ao computador. Depois de ter o objeto DeviceInformation para um scanner, pode usá-lo para criar um objeto ImageScanner . O ImageScanner representa o scanner no código da sua aplicação e dá-lhe acesso às propriedades e métodos que irá usar para a digitalização.

Escolha um scanner disponível

Neste exemplo, usa o sistema DevicePicker para permitir ao utilizador escolher um scanner ligado.

DeviceInformation scannerDeviceInfo;
ImageScanner selectedScannerDevice;

private async Task InitializeScannerDevice()
{
    scannerDeviceInfo = await PickScannerDevice();
    if (scannerDeviceInfo is not null)
    {
        selectedScannerDevice = await ImageScanner.FromIdAsync(scannerDeviceInfo.Id);
        StatusBar.Message = $"Scanner selected: {scannerDeviceInfo.Name}.";
    }
    else
    {
        // Either no scanner is attached, or the user cancelled the device picker.
        StatusBar.Message = $"No scanner is selected.";
    }
}

private async Task<DeviceInformation> PickScannerDevice()
{
    var hWnd = WinRT.Interop.WindowNative.GetWindowHandle(App.MainWindow);
    DevicePicker devicePicker = new();
    // Initialize the device picker with the window handle (HWND).
    WinRT.Interop.InitializeWithWindow.Initialize(devicePicker, hWnd);

    // Filter to show only image scanner devices in the picker.
    devicePicker.Filter.SupportedDeviceClasses.Add(DeviceClass.ImageScanner);

    scannerDeviceInfo = await devicePicker.PickSingleDeviceAsync(new Rect());
    return scannerDeviceInfo;
}

Enumerar digitalizadores disponíveis

Neste exemplo, a enumeração do dispositivo scanner é feita usando a classe DeviceWatcher da Windows. Devices.Enumeration espaço de nomes. Para obter mais informações, consulte Listar Dispositivos.

  1. Primeiro, adicione essas instruções using ao seu arquivo de definição de classe.
    using Windows.Devices.Enumeration;
    using Windows.Devices.Scanners;
  1. Em seguida, implemente um inspetor de dispositivo para começar a enumerar scanners.
ObservableCollection<DeviceInformation> scannerDeviceList = new();

private async void WatchScanners()
{
    scannerDeviceList.Clear();
    deviceWatcher = DeviceInformation.CreateWatcher(DeviceClass.ImageScanner);

    deviceWatcher.Added += DeviceWatcher_Added;
    deviceWatcher.Removed += DeviceWatcher_Removed;
    deviceWatcher.EnumerationCompleted += DeviceWatcher_EnumerationCompleted;

    if (deviceWatcher.Status == DeviceWatcherStatus.Created)
    {
        deviceWatcher.Start();
    }
}
  1. Crie um gestor de eventos para quando a enumeração do dispositivo estiver concluída.
private void DeviceWatcher_EnumerationCompleted(DeviceWatcher sender, object args)
{
    DispatcherQueue.TryEnqueue(DispatcherQueuePriority.Normal, () =>
    {
        if (scannerDeviceList.Count == 0)
        {
            StatusBar.Message = "No scanners found. Please make sure that your scanner is on and properly connected.";
        }
        else
        {
            StatusBar.Message = "Enumeration of scanners is complete.";
        }
    });
}
  1. Crie gestores de eventos para quando um scanner for adicionado ou removido.
private void DeviceWatcher_Removed(DeviceWatcher sender, DeviceInformationUpdate args)
{
    DispatcherQueue.TryEnqueue(DispatcherQueuePriority.Normal, () =>
    {
        scannerDeviceList.Remove(scannerDeviceList.Where(x => x.Id == args.Id).FirstOrDefault());
        StatusBar.Message = $"Scanner removed: {args.Id}";
    });
}

private void DeviceWatcher_Added(DeviceWatcher sender, DeviceInformation args)
{
    DispatcherQueue.TryEnqueue(DispatcherQueuePriority.Normal, () =>
    {
        scannerDeviceList.Add(args);
        StatusBar.Message = $"Scanner added: {args.Name}";
    });
}

Digitalizar

Utiliza APIs do namespace Windows.Devices.Scanners para configurar e digitalizar com um scanner. O objeto ImageScanner representa o scanner no código da sua aplicação e dá-lhe acesso às propriedades e métodos que irá usar para a varredura.

Como mostrado na secção anterior, crias uma instância do ImageScanner chamando o ImageScanner.FromIdAsync e passando a DeviceInformation.Id do scanner que queres usar.

ImageScanner selectedScannerDevice;
selectedScannerDevice = await ImageScanner.FromIdAsync(scannerDeviceInfo.Id);

Para efetuar uma digitalização, chame ImageScanner.ScanFileToFolderAsync e especifique a origem da digitalização e a pasta de destino. Aqui, é criada uma pasta com o nome Scans na biblioteca Imagens como destino para os resultados da digitalização.  

StorageFolder folder = await KnownFolders.PicturesLibrary.CreateFolderAsync("Scans", CreationCollisionOption.OpenIfExists);
                
ImageScannerScanResult result = await selectedScannerDevice.ScanFilesToFolderAsync(ImageScannerScanSource.Default,
        folder);

Origens de digitalização

Um digitalizador pode ter uma mesa plana, um alimentador ou ambos como origem de digitalização. Alguns digitalizadores também suportam digitalização configurada automaticamente. Estas fontes de varrimento são identificadas pela enumeração ImageScannerScanSource e são representadas pelas seguintes classes:

Pode utilizar o objeto de origem da digitalização para:

  • Verifique se a fonte de digitalização é suportada pelo scanner.
    selectedScannerDevice.IsScanSourceSupported(ImageScannerScanSource.AutoConfigured);
    
  • Verifique se a fonte da digitalização suporta digitalizações de pré-visualização.
    selectedScannerDevice.IsPreviewSupported(ImageScannerScanSource.Feeder);
    
  • Especifique a origem a partir da qual digitalizar.
    selectedScannerDevice.ScanFilesToFolderAsync(ImageScannerScanSource.Flatbed, folder);
    

Importante

Quando efetuar uma pré-visualização ou digitalização a partir de uma origem diferente da predefinida, deve primeiro verificar se as pré-visualizações e a origem de digitalização especificada são suportadas.

Também pode usar os objetos ImageScannerFlatbedConfiguration e ImageScannerFeederConfiguration para ler e definir muitas propriedades da fonte de varrimento correspondente.

Fonte de digitalização predefinida

Para obter a fonte de varrimento padrão de um scanner, use a propriedade ImageScanner.DefaultScanSource . Também pode usar o valor de enumeração ImageScannerScanSource.Default para especificar que seja utilizada a origem de digitalização predefinida.

Por exemplo, estas duas chamadas são equivalentes:

selectedScannerDevice.ScanFilesToFolderAsync(ImageScannerScanSource.Default, folder);
selectedScannerDevice.ScanFilesToFolderAsync(selectedScannerDevice.DefaultScanSource, folder);

Varredura auto-configurada

Para usar as configurações configuradas automaticamente, o scanner deve estar habilitado para configuração automática e não deve estar equipado com um scanner de mesa e um scanner de alimentação. Para obter mais informações, consulte Digitalização Configurada Automaticamente.

Seu aplicativo pode usar a Varredura Configurada Automaticamente do dispositivo para verificar com as configurações de verificação ideais. Com essa opção, o próprio dispositivo pode determinar as melhores configurações de digitalização, como modo de cor e resolução de digitalização, com base no conteúdo que está sendo digitalizado. O dispositivo seleciona as configurações de digitalização durante a execução para cada novo trabalho de digitalização.

Note

Nem todos os scanners suportam esta funcionalidade, por isso deve ligar para o IsScanSourceSupported para verificar se o scanner suporta esta funcionalidade antes de usar esta definição.

Neste exemplo, primeiro verifica-se se o scanner é capaz de configuração automática e só se efetua a digitalização se tiver essa capacidade.

if (selectedScannerDevice.IsScanSourceSupported(ImageScannerScanSource.AutoConfigured))
{
    // Scan API call to start scanning with Auto-Configured settings.
    ImageScannerScanResult result = await selectedScannerDevice.ScanFilesToFolderAsync(
        ImageScannerScanSource.AutoConfigured, folder);
}

Pré-visualizar a análise

Se o dispositivo de scanner o suportar, permite ao utilizador visualizar a digitalização antes de digitalizar para uma pasta. Neste exemplo, a aplicação verifica se a Feeder origem da digitalização suporta a pré-visualização e, nesse caso, apresenta uma pré-visualização da digitalização.

if (selectedScannerDevice.IsPreviewSupported(ImageScannerScanSource.Feeder))
{
    IRandomAccessStream stream = new InMemoryRandomAccessStream();
    // Scan API call to get preview from the Feeder.
    ImageScannerScanResult result = 
        await selectedScannerDevice.ScanPreviewToStreamAsync(ImageScannerScanSource.Feeder, stream);
    if (result.Succeeded)
    {
        // ScanPreviewImage is a XAML Image control (not shown).
        SetImageSourceFromStream(stream, ScanPreviewImage);
        StatusBar.Message = "Preview scan is complete.";
    }
    else
    {
        StatusBar.Message = $"Failed to preview from Feeder.";
    }
}
else
{
    StatusBar.Message = $"The selected scanner does not support preview from Feeder.";
}

Este método mostra como mostrar a pré-visualização na interface da tua aplicação.

static async public void SetImageSourceFromStream(IRandomAccessStream stream, Image img)
{
    BitmapImage bitmap = await GetImageFromFile(stream);

    if ((bitmap.PixelHeight > img.Height) || (bitmap.PixelWidth > img.Width))
    {
        img.Stretch = Stretch.Uniform;
    }
    else
    {
        img.Stretch = Stretch.None;
    }
    img.Source = bitmap;
}

Digitalização para a biblioteca de imagens

Os utilizadores podem digitalizar diretamente para qualquer pasta de forma dinâmica utilizando a classe FolderPicker, mas tem de declarar a capacidade Pictures Library no manifesto para permitir que os utilizadores digitalizem para essa pasta. Para saber mais sobre os recursos do aplicativo, veja Declarações de recursos do aplicativo.