【问题标题】:Generating photo quality scans with WIA in C#在 C# 中使用 WIA 生成照片质量扫描
【发布时间】:2019-07-29 16:18:12
【问题描述】:

所以我一直在努力更新我不久前推出的一个相当简单且特定于任务的图像处理应用程序。由于使用此软件的成像技术人员倾向于以要求程序适应不必要的更改(有时是有意的有时是意外的)的方式弄乱他们的扫描仪设置,我想在更新中添加一个扫描按钮,它将标准化诸如图像分辨率和颜色设置,以加强统一性,同时减少员工必须打开和切换的程序数量。最初,我尝试使用由原始 python 程序调用的 Powershell 脚本来完成此操作。那是一场噩梦,不是我现在正在做的事情,这不是与我发布的关于该问题的问题的重复。那么问题来了:

我没有坚持使用 python 和 Powershell,而是使用 C# 编写了升级后的应用程序,使用 WIA 处理扫描仪和 Aforge.Net 执行图像后处理任务。我的代码运行良好,可以找到扫描仪,并以适当的尺寸、分辨率和压缩方式扫描彩色图像。问题是这仍然不是真正的“照片质量”图像。我们正在扫描漫画书,封面上的污迹和折痕之类的东西必须在所有扫描中都可见,即使是非常暗的扫描。爱普生扫描管理器很好地完成了这一点,虽然它在这个过程中稍微洗掉了图像,但我不知道我应该改变什么设置才能达到类似的目的。例如,这是使用我的应用程序上的扫描按钮扫描的测试图像:

这是使用 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);
}

如果需要,我也可以包含后处理代码,但其中有很多 (毕竟这是应用程序的主要功能),它真正要做的就是获取一堆关于图像内容的信息,然后旋转和裁剪它。除了旋转和裁剪之外,它不应该对图像的实际外观产生影响,所以我暂时不考虑这部分。如果需要此代码的 sn-ps,请告诉我,我将发布它们。感谢您提供的任何帮助!

【问题讨论】:

    标签: c# image-processing epson wia


    【解决方案1】:

    您需要降低对比度并增加亮度才能获得预期的效果。

    据此Microsoft WIA page。有效范围是 -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);
    

    您必须根据结果调整值。

    【讨论】:

    • 更改亮度和对比度对图像中存在的覆盖缺陷没有影响。这是我尝试的第一件事。它看起来与暗图像完全相同,只是更亮。我认为与扫描仪灯本身有关的东西需要调整,但不确定。无论如何,改变亮度无济于事。我需要它来查看扫描时实际存在的白色污点,而不是在后期处理期间添加均匀的亮度。
    • @Jeremiah 亮度值设置在硬件上(调整扫描仪中的光线,请参阅提供的链接中的WIA_IPS_BRIGHTNESS),使用上面的代码,而不是在后期处理中。 Epson 软件似乎正在使用 WIA 中未实现的伽马校正。
    • 不管怎样都行不通。同样,摆弄亮度确实是我尝试的第一件事。
    猜你喜欢
    • 2016-05-08
    • 2011-05-20
    • 2010-09-05
    • 1970-01-01
    • 2012-02-07
    • 1970-01-01
    • 2015-08-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多