我尝试使用平板扫描仪和Windows 10从C#应用程序扫描A4页面。为了加快速度,我使用了此处的ScanWIA库:https://scanwia.codeplex.com/
但是,我在正确配置页面设置方面存在很大问题。
为A4页面和可变DPI设置设置此选项的正确方法是什么? 如何正确设置捕获区域的大小? 如何控制输出图像的大小? 哪个设置使用哪个单位?最大值范围是多少?
MSDN对这些主题不是很有帮助......
答案 0 :(得分:0)
我已经建立了一个用户控件来扫描附加扫描仪上的文档。 在这里我可以解释细节。 enter image description here
在附加的表格图像中有2个图片框,预览按钮,保存按钮,两个用于显示保存路径的标签和一个用于显示可用扫描仪设备的下拉列表。请参阅附图,以获得有关表单设计的清晰图片。
using System;
using System.Collections.Generic;
using System.IO;
using System.Drawing;
using WIA;
namespace TESTSCAN
{
class WIAScanner
{
const string wiaFormatBMP = "{B96B3CAB-0728-11D3-9D7B-0000F81EF32E}";
const string WIA_DEVICE_PROPERTY_PAGES_ID = "3096";
const string WIA_SCAN_BRIGHTNESS_PERCENTS = "6154";
const string WIA_SCAN_CONTRAST_PERCENTS = "6155";
const string WIA_SCAN_COLOR_MODE = "6146";
class WIA_DPS_DOCUMENT_HANDLING_SELECT
{
public const uint FEEDER = 0x00000001;
public const uint FLATBED = 0x00000002;
}
class WIA_DPS_DOCUMENT_HANDLING_STATUS
{
public const uint FEED_READY = 0x00000001;
}
class WIA_PROPERTIES
{
public const uint WIA_RESERVED_FOR_NEW_PROPS = 1024;
public const uint WIA_DIP_FIRST = 2;
public const uint WIA_DPA_FIRST = WIA_DIP_FIRST + WIA_RESERVED_FOR_NEW_PROPS;
public const uint WIA_DPC_FIRST = WIA_DPA_FIRST + WIA_RESERVED_FOR_NEW_PROPS;
//
// Scanner only device properties (DPS)
//
public const uint WIA_DPS_FIRST = WIA_DPC_FIRST + WIA_RESERVED_FOR_NEW_PROPS;
public const uint WIA_DPS_DOCUMENT_HANDLING_STATUS = WIA_DPS_FIRST + 13;
public const uint WIA_DPS_DOCUMENT_HANDLING_SELECT = WIA_DPS_FIRST + 14;
}
//public void SetProperty(Property property, int value)
//{
// IProperty x = (IProperty)property;
// Object val = value;
// x.set_Value(ref val);
//}
/// <summary>
/// Use scanner to scan an image (with user selecting the scanner from a dialog).
/// </summary>
/// <returns>Scanned images.</returns>
public static List<Image> Scan()
{
WIA.ICommonDialog dialog = new WIA.CommonDialog();
WIA.Device device = dialog.ShowSelectDevice(WIA.WiaDeviceType.UnspecifiedDeviceType, true, false);
if (device != null)
{
return Scan(device.DeviceID,1);
}
else
{
throw new Exception("You must select a device for scanning.");
}
}
/// <summary>
/// Use scanner to scan an image (scanner is selected by its unique id).
/// </summary>
/// <param name="scannerName"></param>
/// <returns>Scanned images.</returns>
public static List<Image> Scan(string scannerId, int pages)
{
List<Image> images = new List<Image>();
bool hasMorePages = true;
int numbrPages = pages;
while (hasMorePages)
{
// select the correct scanner using the provided scannerId parameter
WIA.DeviceManager manager = new WIA.DeviceManager();
WIA.Device device = null;
foreach (WIA.DeviceInfo info in manager.DeviceInfos)
{
if (info.DeviceID == scannerId)
{
// connect to scanner
device = info.Connect();
break;
}
}
// device was not found
if (device == null)
{
// enumerate available devices
string availableDevices = "";
foreach (WIA.DeviceInfo info in manager.DeviceInfos)
{
availableDevices += info.DeviceID + "\n";
}
// show error with available devices
throw new Exception("The device with provided ID could not be found. Available Devices:\n" + availableDevices);
}
SetWIAProperty(device.Properties, WIA_DEVICE_PROPERTY_PAGES_ID, 1);
WIA.Item item = device.Items[1] as WIA.Item;
AdjustScannerSettings(item, 150, 0, 0, 1250, 1700, 0, 0, 1);
try
{
// scan image
WIA.ICommonDialog wiaCommonDialog = new WIA.CommonDialog();
WIA.ImageFile image = (WIA.ImageFile)wiaCommonDialog.ShowTransfer(item, wiaFormatBMP, false);
// save to temp file
string fileName = Path.GetTempFileName();
File.Delete(fileName);
image.SaveFile(fileName);
image = null;
// add file to output list
images.Add(Image.FromFile(fileName));
}
catch (Exception exc)
{
throw exc;
}
finally
{
item = null;
//determine if there are any more pages waiting
WIA.Property documentHandlingSelect = null;
WIA.Property documentHandlingStatus = null;
foreach (WIA.Property prop in device.Properties)
{
if (prop.PropertyID == WIA_PROPERTIES.WIA_DPS_DOCUMENT_HANDLING_SELECT)
documentHandlingSelect = prop;
if (prop.PropertyID == WIA_PROPERTIES.WIA_DPS_DOCUMENT_HANDLING_STATUS)
documentHandlingStatus = prop;
}
// assume there are no more pages
hasMorePages = false;
// may not exist on flatbed scanner but required for feeder
if (documentHandlingSelect != null)
{
// check for document feeder
if ((Convert.ToUInt32(documentHandlingSelect.get_Value()) & WIA_DPS_DOCUMENT_HANDLING_SELECT.FEEDER) != 0)
{
hasMorePages = ((Convert.ToUInt32(documentHandlingStatus.get_Value()) & WIA_DPS_DOCUMENT_HANDLING_STATUS.FEED_READY) != 0);
}
}
}
numbrPages -= 1;
if (numbrPages > 0)
hasMorePages = true;
else
hasMorePages = false;
}
return images;
}
/// <summary>
/// Gets the list of available WIA devices.
/// </summary>
/// <returns></returns>
public static List<string> GetDevices()
{
List<string> devices = new List<string>();
WIA.DeviceManager manager = new WIA.DeviceManager();
foreach (WIA.DeviceInfo info in manager.DeviceInfos)
{
devices.Add(info.DeviceID);
}
return devices;
}
private static void SetWIAProperty(WIA.IProperties properties,
object propName, object propValue)
{
WIA.Property prop = properties.get_Item(ref propName);
prop.set_Value(ref propValue);
}
private static void AdjustScannerSettings(IItem scannnerItem, 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(scannnerItem.Properties, WIA_HORIZONTAL_SCAN_RESOLUTION_DPI, scanResolutionDPI);
SetWIAProperty(scannnerItem.Properties, WIA_VERTICAL_SCAN_RESOLUTION_DPI, scanResolutionDPI);
SetWIAProperty(scannnerItem.Properties, WIA_HORIZONTAL_SCAN_START_PIXEL, scanStartLeftPixel);
SetWIAProperty(scannnerItem.Properties, WIA_VERTICAL_SCAN_START_PIXEL, scanStartTopPixel);
SetWIAProperty(scannnerItem.Properties, WIA_HORIZONTAL_SCAN_SIZE_PIXELS, scanWidthPixels);
SetWIAProperty(scannnerItem.Properties, WIA_VERTICAL_SCAN_SIZE_PIXELS, scanHeightPixels);
SetWIAProperty(scannnerItem.Properties, WIA_SCAN_BRIGHTNESS_PERCENTS, brightnessPercents);
SetWIAProperty(scannnerItem.Properties, WIA_SCAN_CONTRAST_PERCENTS, contrastPercents);
SetWIAProperty(scannnerItem.Properties, WIA_SCAN_COLOR_MODE, colorMode);
}
}
}
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing.Imaging;
using System.Drawing.Drawing2D;
namespace TESTSCAN
{
public partial class Form1 : Form
{
int cropX, cropY, cropWidth, cropHeight;
//here rectangle border pen color=red and size=2;
Pen borderpen = new Pen(Color.Red, 2);
Image _orgImage;
Bitmap crop;
List<string> devices;
//fill the rectangle color =white
SolidBrush rectbrush = new SolidBrush(Color.FromArgb(100, Color.White));
int pages;
int currentPage = 0;
public Form1()
{
InitializeComponent();
IsSaved = false;
}
List<Image> images;
private string f_path;
private string doc_no;
private bool savedOrNot = false;
private List<string> fNames;
public List<string> fileNames
{
get { return fNames; }
set { fNames = value; }
}
public String SavePath
{
get { return f_path; }
set { f_path = value; }
}
public String DocNo
{
get { return doc_no; }
set { doc_no = value; }
}
public bool IsSaved
{
get { return savedOrNot; }
set { savedOrNot = value; }
}
private void Form1_Load(object sender, EventArgs e)
{
lblPath.Text = SavePath;
lblDocNo.Text = DocNo;
//get list of devices available
devices = WIAScanner.GetDevices();
foreach (string device in devices)
{
lbDevices.Items.Add(device);
}
//check if device is not available
if (lbDevices.Items.Count != 0)
{
lbDevices.SelectedIndex = 0;
}
}
private void btnPreview_Click(object sender, EventArgs e)
{
try
{
//get list of devices available
if (lbDevices.Items.Count == 0)
{
MessageBox.Show("You do not have any WIA devices.");
}
else
{
//get images from scanner
pages =3;
images = WIAScanner.Scan((string)lbDevices.SelectedItem, pages);
pages = images.Count;
if (images != null)
{
foreach (Image image in images)
{
pic_scan.Image = images[0];
pic_scan.Show();
pic_scan.SizeMode = PictureBoxSizeMode.StretchImage;
_orgImage = images[0];
crop = new Bitmap(images[0]);
btnOriginal.Enabled = true;
btnSave.Enabled = true;
currentPage = 0;
//pic_scan.Image = image;
//pic_scan.Show();
//pic_scan.SizeMode = PictureBoxSizeMode.StretchImage;
//_orgImage = image;
//crop = new Bitmap(image);
//btnOriginal.Enabled = true;
//btnSave.Enabled = true;
}
}
}
}
catch (Exception exc)
{
MessageBox.Show(exc.Message);
}
}
List<string> sss = new List<string>();
private void btnSave_Click(object sender, EventArgs e)
{
try
{
if (crop != null)
{
SavePath = @"D:\NAJEEB\scanned images\";
DocNo = "4444";
string currentFName = DocNo + Convert.ToString(currentPage + 1) + ".jpeg";
crop.Save(SavePath + currentFName, ImageFormat.Jpeg);
sss.Add(currentFName);
MessageBox.Show("Document Saved Successfully");
IsSaved = true;
currentPage += 1;
if (currentPage < (pages))
{
pic_scan.Image = images[currentPage];
pic_scan.Show();
pic_scan.SizeMode = PictureBoxSizeMode.StretchImage;
_orgImage = images[currentPage];
crop = new Bitmap(images[currentPage]);
btnOriginal.Enabled = true;
btnSave.Enabled = true;
}
else
{ btnSave.Enabled =false;
fileNames = sss;
}
}
}
catch (Exception exc)
{
IsSaved = false;
MessageBox.Show(exc.Message);
}
}
private void btnOriginal_Click(object sender, EventArgs e)
{
if (_orgImage != null)
{
crop = new Bitmap(_orgImage);
pic_scan.Image = _orgImage;
pic_scan.SizeMode = PictureBoxSizeMode.StretchImage;
pic_scan.Refresh();
}
}
private void pic_scan_MouseDown(object sender, MouseEventArgs e)
{
try
{
if (e.Button == MouseButtons.Left)//here i have use mouse click left button only
{
pic_scan.Refresh();
cropX = e.X;
cropY = e.Y;
Cursor = Cursors.Cross;
}
pic_scan.Refresh();
}
catch { }
}
private void pic_scan_MouseMove(object sender, MouseEventArgs e)
{
try
{
if (pic_scan.Image == null)
return;
if (e.Button == MouseButtons.Left)//here i have use mouse click left button only
{
pic_scan.Refresh();
cropWidth = e.X - cropX;
cropHeight = e.Y - cropY;
}
pic_scan.Refresh();
}
catch { }
}
private void pic_scan_MouseUp(object sender, MouseEventArgs e)
{
try
{
Cursor = Cursors.Default;
if (cropWidth < 1)
{
return;
}
Rectangle rect = new Rectangle(cropX, cropY, cropWidth, cropHeight);
Bitmap bit = new Bitmap(pic_scan.Image, pic_scan.Width, pic_scan.Height);
crop = new Bitmap(cropWidth, cropHeight);
Graphics gfx = Graphics.FromImage(crop);
gfx.InterpolationMode = InterpolationMode.HighQualityBicubic;//here add System.Drawing.Drawing2D namespace;
gfx.PixelOffsetMode = PixelOffsetMode.HighQuality;//here add System.Drawing.Drawing2D namespace;
gfx.CompositingQuality = CompositingQuality.HighQuality;//here add System.Drawing.Drawing2D namespace;
gfx.DrawImage(bit, 0, 0, rect, GraphicsUnit.Pixel);
}
catch { }
}
private void pic_scan_Paint(object sender, PaintEventArgs e)
{
Rectangle rect = new Rectangle(cropX, cropY, cropWidth, cropHeight);
Graphics gfx = e.Graphics;
gfx.DrawRectangle(borderpen, rect);
gfx.FillRectangle(rectbrush, rect);
}
}
}
如果讨论工作流程。