如何在 powershell 中更改扫描仪 DPI 设置?

How to change scanner DPI settings in powershell?

我正在更新一个旧的图像处理应用程序,这是我在第一次被录用时回信的。我收到的一个请求是在应用程序上有一个 "Scan" 按钮,这样就可以扫描和处理图像,而无需打开 Epson Scan Manager 或按下按钮(一些成像技术人员难以达到他们的要求)从他们的座位上扫描按钮)。我在 powershell 中破解了一些东西,可以完成这项工作,可以轻松链接到 python 应用程序中的按钮,但我不能 select DPI 的值。这些扫描的分辨率很重要,无论是面向客户还是程序原因,它们必须至少为 300 DPI,但它们总是以低得多的分辨率保存,我似乎无法弄清楚如何进入和更改 WIA扫描仪的设置。保存文件后我可以控制压缩,但我无法控制扫描仪在实际扫描图片时使用的分辨率。我找到了 this 资源,但不知道如何实际实施这些设置的更改。我们只使用 jpeg,这些扫描仪只用于扫描产品,没有应用过滤器或蒙版,所以它应该非常简单,但我只需要弄清楚这个 DPI 的东西。这是我目前所拥有的:

Set-ExecutionPolicy RemoteSigned

$deviceManager = new-object -ComObject WIA.DeviceManager
$device = $deviceManager.DeviceInfos.Item(1).Connect()

$imageProcess = new-object -ComObject WIA.ImageProcess

$wiaFormatJPEG = "{B96B3CAE-0728-11D3-9D7B-0000F81EF32E}"

foreach ($item in $device.Items) {
    $image = $item.Transfer() 
}

$Basepath = Join-Path -Path "C:\Users" -ChildPath $env:username
$NewPath = Join-Path -Path $BasePath -ChildPath "Pictures\My Scans\scan daemon"
$filename = Join-Path -Path $NewPath -ChildPath "Scan {0}.jpg"

$index = 0
while (test-path ($filename -f $index)) {[void](++$index)}
$filename = $filename -f $index

$image.SaveFile($filename)

我可以获得扫描件并保存文件,但它总是以低分辨率保存。这是一个问题,因为我们的客户希望看到高分辨率图像,而且因为我的图像处理应用程序需要特定大小的图像,所以如果我们愿意使用它们,甚至无法在这些图像上正常工作。我觉得这应该很简单,甚至可能是一行代码,但我对 Windows 或 powershell 不是很熟悉,目前我不知道那行代码是什么或如何找到它.

基本上我只是想要一种方法来做到这一点:

SetWIAProperty(scannnerItem.Properties, WIA_HORIZONTAL_SCAN_RESOLUTION_DPI, 300);
SetWIAProperty(scannnerItem.Properties, WIA_VERTICAL_SCAN_RESOLUTION_DPI, 300);

在 powershell 中。无论我在哪里看,我似乎都无法在 powershell 中找到 运行 .net 命令的语法指南,这些命令不仅仅处理基本网络。

所以我回答这个问题,严格来说并不是因为它已经解决了,而是因为我最终以不同的方式解决了潜在的问题。我用C#重写了需要这样做的app,直接使用WIA完成扫描任务。这种方法存在新问题,但我可以进行扫描并调整图像大小和分辨率。由于 Powershell 可以使用 .Net 程序集,甚至是自定义程序集,如果我决定继续使用 powershell,则可以 运行 通过 powershell 扫描代码,但在 .Net 中重写所有内容更为明智。 Net,因为这样做还改进了程序的其他功能。不管怎样,这是我的 .Net 代码,以防其他人想做这样的事情:

    private static void AdjustScannerSettings(IItem scannerItem, 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(scannerItem.Properties, "4104", 24);
        SetWIAProperty(scannerItem.Properties, WIA_HORIZONTAL_SCAN_RESOLUTION_DPI, scanResolutionDPI);
        SetWIAProperty(scannerItem.Properties, WIA_VERTICAL_SCAN_RESOLUTION_DPI, scanResolutionDPI);
        SetWIAProperty(scannerItem.Properties, WIA_HORIZONTAL_SCAN_START_PIXEL, scanStartLeftPixel);
        SetWIAProperty(scannerItem.Properties, WIA_VERTICAL_SCAN_START_PIXEL, scanStartTopPixel);
        SetWIAProperty(scannerItem.Properties, WIA_HORIZONTAL_SCAN_SIZE_PIXELS, scanWidthPixels);
        SetWIAProperty(scannerItem.Properties, WIA_VERTICAL_SCAN_SIZE_PIXELS, scanHeightPixels);
        SetWIAProperty(scannerItem.Properties, WIA_SCAN_BRIGHTNESS_PERCENTS, brightnessPercents);
        SetWIAProperty(scannerItem.Properties, WIA_SCAN_CONTRAST_PERCENTS, contrastPercents);
        SetWIAProperty(scannerItem.Properties, WIA_SCAN_COLOR_MODE, colorMode);
    }
    private static void SetWIAProperty(IProperties properties, object propName, object propValue)
    {
        Property prop = properties.get_Item(ref propName);
        prop.set_Value(ref propValue);
    }
    private void buttonScan_Click(object sender, EventArgs e)
    {
        var deviceManager = new DeviceManager();
        DeviceInfo firstScannerAvailable = null;
        for (int i = 1; i <= deviceManager.DeviceInfos.Count; i++)
        {
            if (deviceManager.DeviceInfos[i].Type != WiaDeviceType.ScannerDeviceType)
            {
                continue;
            }
            firstScannerAvailable = deviceManager.DeviceInfos[i];
            break;
        }
        var device = firstScannerAvailable.Connect();
        var scannerItem = device.Items[1];
        int resolution = 300;
        int width_pixel = 3510;
        int height_pixel = 5100;
        int color_mode = 1;
        AdjustScannerSettings(scannerItem, resolution, 0, 0, width_pixel, height_pixel, 0, 0, color_mode);

        var imageFile = (ImageFile)scannerItem.Transfer("{B96B3CAE-0728-11D3-9D7B-0000F81EF32E}");

        var pathbase = Path.Combine(pictures, basedaemonpath);
        string filebase = DateTime.Now.ToString("dd-MM-yyyy-hh-mm-ss-fffffff") + ".jpg";
        var path = Path.Combine(pathbase, filebase);

        WIA.ImageProcess myip = new WIA.ImageProcess();  // use to compress jpeg.
        myip.Filters.Add(myip.FilterInfos["Convert"].FilterID);
        myip.Filters[1].Properties["FormatID"].set_Value("{B96B3CAE-0728-11D3-9D7B-0000F81EF32E}");
        myip.Filters[1].Properties["Quality"].set_Value(84);

        ImageFile image = myip.Apply(imageFile);

        image.SaveFile(path);
    }

这有一些我仍在努力解决的问题,但除非您需要真正的照片质量图像,否则它会很好用。当然你需要更改你的路径和变量名以适应你的项目,然后,如果你想在 powershell 中调用模块,你可以将其编译为 .exe 文件,然后像调用任何其他文件一样直接调用它,或者您可以直接将其作为 .Net 对象使用:

Create-Object -TypeName AdjustScannerSettings

同样,我最终没有这样做,所以我不会称这个问题为 "solved" 本身,但这段代码在我的 C# 应用程序中有效,如果我决定保留,则在 powershell 中也能正常工作使用它来调用设置更改。如果其他人正在尝试使用 powershell 进行扫描,如果您愿意处理编写 .Net 代码来执行此操作,那么这应该可行。如果你想要一个纯粹的 powershell 解决方案,那仍然在等待比我更擅长的人来提供它。如果发生这种情况,我会很乐意重新分配复选标记。 ;)