Как изменить настройки DPI сканера в powershell? - PullRequest
0 голосов
/ 15 февраля 2019

Я делаю обновления для старого приложения для обработки изображений, которое я написал, когда меня впервые наняли.Один запрос, который я получил, состоит в том, чтобы в приложении была кнопка «Сканировать», чтобы изображения можно было сканировать и обрабатывать без необходимости открывать Epson Scan Manager или нажимать кнопку (некоторые специалисты по обработке изображений испытывают трудности с достижением своей кнопки сканирования).со своих мест).Я взломал что-то вместе в PowerShell, который выполняет свою работу и может быть легко связан с кнопкой в ​​приложении Python, но я не могу выбрать значение для DPI.Разрешение имеет значение для этих сканирований, как для клиентов, так и для программных целей, и они должны быть не менее 300 DPI, но они всегда экономят при гораздо более низком разрешении, и я не могу понять, как войти и изменить WIAнастройки для сканера.Я могу контролировать сжатие после сохранения файла, но не могу контролировать разрешение, которое сканер использует, когда фактически сканирует изображение.Я обнаружил этот ресурс, но не знаю, как на самом деле реализовать изменение этих настроек.Мы работаем только с jpegs, и эти сканеры используются только для сканирования продуктов, без применения фильтров или масок, поэтому это должно быть довольно просто, но мне просто нужно разобраться с этим параметром 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.Независимо от того, где я смотрю, я не могу найти руководство по синтаксису для запуска команд .net в powershell, которые не имеют отношения только к базовым сетям.

1 Ответ

0 голосов
/ 07 марта 2019

Так что я отвечаю на этот вопрос не потому, что он решен, строго говоря, а потому, что я в конечном итоге решил основную проблему другим способом.Я переписал приложение, которое должно делать это на C #, используя WIA напрямую для выполнения задачи сканирования.При таком подходе возникают новые проблемы, но я могу выполнить сканирование и настроить размер изображения и разрешение.Поскольку Powershell может использовать сборки .Net, даже пользовательские, было бы возможно запустить код сканирования с помощью powershell, если бы я решил продолжать использовать powershell, но было бы разумнее переписать все в .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

Опять же, я не закончил этим заниматься, поэтому я бы не назвал эту проблему "решенной" как таковой, но этот код работаетв моем приложении C # и работал бы в powershell, если бы я решил продолжать использовать это для вызова изменений настроек.Если кто-то еще пытается сканировать с помощью powershell, это должно сработать, если вы готовы заняться написанием кода .Net для этого.Если вам нужно чистое решение PowerShell, оно все еще ждет кого-то лучше, чем я, чтобы предоставить его.Я с радостью перераспределю галочку, когда и если это произойдет.;)

...