Scannen aus Ihrer App

In diesem Thema wird beschrieben, wie Sie Inhalte aus Ihrer App mithilfe eines Flachbettscanners, eines Durchlaufscanners oder einer automatisch konfigurierten Scanquelle scannen können.

Scanner abrufen

Um von Ihrer App zu scannen, müssen Sie zuerst einen verfügbaren Scanner abrufen, der an den Computer angeschlossen ist. Nur Scanner, die lokal mit Windows Image Acquisition (WIA)-Treibern installiert sind sind aufgeführt und für Ihre App verfügbar.

Um einen angeschlossenen Scanner auszuwählen, können Sie entweder die Systembenutzeroberfläche DevicePicker oder andere APIs in Windows.Devices.Enumeration verwenden, wie unter Enumerate devices gezeigt. In beiden Fällen können Sie den DeviceClass.ImageScanner-Wert als Filter verwenden, sodass devicePicker oder DeviceWatcher nur Bildscannergeräte anzeigt.

Mit den Geräteaufzählungs-APIs erhalten Sie ein DeviceInformation -Objekt, das ein gerät darstellt, das an den Computer angeschlossen ist. Nachdem Sie über das DeviceInformation-Objekt für einen Scanner verfügen, können Sie es verwenden, um ein ImageScanner-Objekt zu erstellen. Der ImageScanner stellt den Scanner im App-Code dar und bietet Ihnen Zugriff auf Eigenschaften und Methoden, die Sie zum Scannen verwenden.

Auswählen eines verfügbaren Scanners

In diesem Beispiel verwenden Sie das System DevicePicker , um dem Benutzer die Auswahl eines angefügten Scanners zu ermöglichen.

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;
}

Aufzählen verfügbarer Scanner

In diesem Beispiel erfolgt die Aufzählung des Scannergeräts mithilfe der Klasse DeviceWatcher aus der Windows. Devices.Enumeration Namespace. Weitere Informationen finden Sie unter "Aufzählen von Geräten".

  1. Fügen Sie zunächst diese using-Anweisungen zu Ihrer Klassendefinitionsdatei hinzu.
    using Windows.Devices.Enumeration;
    using Windows.Devices.Scanners;
  1. Implementieren Sie als Nächstes eine Geräteüberwachung, um mit dem Aufzählen von Scannern zu beginnen.
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. Erstellen Sie einen Ereignishandler für den Abschluss der Geräteaufzählung.
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. Erstellen Sie Ereignishandler für den Fall, dass ein Scanner hinzugefügt oder entfernt wird.
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}";
    });
}

Scannen

Sie verwenden APIs aus dem Windows. Devices.Scanners Namespace zum Konfigurieren und Scannen von einem Scanner. Das ImageScanner -Objekt stellt den Scanner in Ihrem App-Code dar und bietet Ihnen Zugriff auf Eigenschaften und Methoden, die Sie zum Scannen verwenden.

Wie im vorherigen Abschnitt gezeigt, erstellen Sie eine Instanz von ImageScanner, indem Sie ImageScanner.FromIdAsync aufrufen und die DeviceInformation.Id des scanners übergeben, den Sie verwenden möchten.

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

Rufen Sie zum Ausführen eines Scans ImageScanner.ScanFileToFolderAsync auf, und geben Sie die Scanquelle und den Zielordner an. Hier wird in der Bildbibliothek ein Ordner mit dem Namen Scans als Ziel für Scanergebnisse erstellt.  

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

Scannen von Quellen

Ein Scanner kann einen Flachbettscanner, einen Durchlaufscanner oder beides als Scanquelle haben. Einige Scanner unterstützen auch das automatisch konfigurierte Scannen. Diese Scanquellen werden durch die ImageScannerScanSource-Aufzählung identifiziert und durch die folgenden Klassen dargestellt:

Sie können das Scanquellobjekt verwenden, um:

  • Überprüfen Sie, ob die Scanquelle vom Scanner unterstützt wird.
    selectedScannerDevice.IsScanSourceSupported(ImageScannerScanSource.AutoConfigured);
    
  • Überprüfen Sie, ob die Scanquelle Vorschauscans unterstützt.
    selectedScannerDevice.IsPreviewSupported(ImageScannerScanSource.Feeder);
    
  • Geben Sie an, von welcher Quelle gescannt werden soll.
    selectedScannerDevice.ScanFilesToFolderAsync(ImageScannerScanSource.Flatbed, folder);
    

Important

Wenn Sie eine Vorschau anzeigen oder von einer anderen Quelle als der Standardquelle scannen, sollten Sie zunächst prüfen, ob Vorschauscans und die angegebene Scanquelle unterstützt werden.

Sie können auch die ImageScannerFlatbedConfiguration - und ImageScannerFeederConfiguration-Objekte verwenden, um viele Eigenschaften der entsprechenden Scanquelle zu lesen und festzulegen.

Standardscanquelle

Verwenden Sie die ImageScanner.DefaultScanSource-Eigenschaft , um die Standardscanquelle eines Scanners abzurufen. Sie können auch den ImageScannerScanSource.Default-Enumerationswert verwenden, um anzugeben, dass die Standardscanquelle verwendet wird.

Diese beiden Aufrufe sind z. B. gleichwertig:

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

Automatisch konfiguriertes Scannen

Um automatisch konfigurierte Einstellungen zu verwenden, muss der Scanner für die automatische Konfiguration aktiviert sein und darf nicht sowohl über einen Flachbettscanner als auch über einen Durchlaufscanner verfügen. Weitere Informationen finden Sie unter "Automatisch konfiguriertes Scannen".

Ihre App kann das automatisch konfigurierte Scannen des Geräts verwenden, um mit optimalen Scaneinstellungen zu scannen. Mit dieser Option kann das Gerät selbst die besten Scaneinstellungen ermitteln, z. B. farbmodus und Scanauflösung, basierend auf dem gescannten Inhalt. Das Gerät wählt die Scaneinstellungen zur Laufzeit für jeden neuen Scanauftrag aus.

Note

Nicht alle Scanner unterstützen dieses Feature. Daher müssen Sie IsScanSourceSupported aufrufen, um zu überprüfen, ob der Scanner dieses Feature unterstützt, bevor Sie diese Einstellung verwenden.

In diesem Beispiel prüfen Sie zunächst, ob der Scanner die automatische Konfiguration unterstützt, und führen den Scan nur dann durch, wenn dies der Fall ist.

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

Vorschau des Scans

Wenn das Scannergerät dies unterstützt, können Sie dem Benutzer eine Vorschau des Scans vor dem Scannen in einen Ordner ermöglichen. In diesem Beispiel überprüft die App, ob die Scanquelle die Feeder Vorschau unterstützt, und führt dann eine Vorschau des Scans aus, falls dies der Fall ist.

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.";
}

Diese Methode zeigt, wie die Vorschau in der App-UI angezeigt wird.

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;
}

Scannen in die Bilderbibliothek

Benutzer können dynamisch mithilfe der FolderPicker Klasse in einen beliebigen Ordner scannen, aber Sie müssen die Pictures Library-Funktion im Manifest deklarieren, damit Benutzer in diesen Ordner scannen können. Weitere Informationen zu App-Funktionen finden Sie unter App-Funktionsdeklarationen.