Создание сканов качества фотографий с WIA в C # - PullRequest
2 голосов
/ 07 марта 2019

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

Вместо того, чтобы придерживаться Python и Powershell, я написал обновленное приложение на C #, используя WIA для работы со сканером и Aforge.Net для выполнения задач постобработки изображений.У меня есть код, который работает достаточно хорошо, находит сканер и сканирует изображение в цвете с соответствующим размером, разрешением и сжатием.Проблема в том, что это на самом деле не совсем фотокачественное изображение.Мы сканируем комиксы, и такие вещи, как пятна и складки на обложке, должны быть видны при любом сканировании, даже очень темном.Диспетчер сканирования Epson выполняет это довольно хорошо, хотя в процессе немного стирает изображения, но я не могу понять, какие настройки мне следует изменить, чтобы добиться аналогичного результата.Например, вот тестовое изображение, отсканированное с помощью кнопки сканирования в моем приложении: My Scan Button

А вот то же изображение, отсканированное с помощью Epson Scan Manager: Epson Scan Manager

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

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

Я также могу включить код постобработки, если он необходим, но есть лот о нем (в конце концов, это основная функция приложения), и все, что он на самом деле делает, это получает кучу информации о содержимом изображения, а затем поворачивает и обрезает его.Это не должно влиять на фактический вид изображения, за исключением поворота и обрезки, поэтому я пока оставлю эту часть.Если нужны фрагменты этого кода, дайте мне знать, и я опубликую их.Спасибо за любую помощь, которую вы можете оказать!

1 Ответ

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

Вам нужно уменьшить контраст и увеличить яркость, чтобы получить ожидаемые результаты.

Согласно этой странице Microsoft WIA . Допустимые значения: от -1000 до 1000.

Выполните следующие корректировки метода buttonScan_Click:

// ...
int width_pixel = 3510;
int height_pixel = 5100;
int color_mode = 1;
// Add the following two lines 
int brightness = 500;
int contrast = -500;
//  Change the 0, 0 to brightness, contrast in the next line.
AdjustScannerSettings(scannerItem, resolution, 0, 0, width_pixel, height_pixel, brightness, contrast, color_mode);

Вам нужно будет скорректировать значения в соответствии с результатами.

...