WIA的使用及自定义可拖拽大小的picturebox

首先看工程的结构,主要包括主界面,自定义控件和webservice的引用。

需要引用com组建,win7中自带wia2.0,其它系统若不带可注册,注册方法从微软官网下载的wia2.0组建包中有说明。

工程采用clickonce发布:

自定义控件UCPicturebox的界面为下图,由一个picturebox和四个label组成。

后台代码:

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;

namespace WIAapp
{
/// <summary>
/// created by 邢秉公
/// 功能:可调整大小的picturebox
/// </summary>
public partial class UCPictureBox : UserControl
{
private int StartX, StartY, EndX, EndY;

/// <summary>
/// 获取或设置由UCPictureBox显示的图像
/// </summary>
public Image Image
{
get
{
return pictureBox1.Image;
}
set
{
pictureBox1.Image = value;
}
}

/// <summary>
/// 获取或设置控件的位置
/// </summary>
public Point Location
{
get { return base.Location; }
set { base.Location = value; SetLabelPos(); }
}

/// <summary>
/// 设置或获取PictureBox的宽
/// </summary>
public int Width
{
get { return pictureBox1.Width; }
set
{
pictureBox1.Width = value;
base.Width = Convert.ToInt16(value) + lbLeft.Width;
SetLabelPos();
}
}

/// <summary>
/// 设置或获取PictureBox的高
/// </summary>
public int Height
{
get { return pictureBox1.Height; }
set
{
pictureBox1.Height = value;
base.Height = Convert.ToInt16(value) + lbTop.Height ;
SetLabelPos();
}
}

public delegate bool DragEventHandler(DragEventArgs e);

public event DragEventHandler LeftDragEvent;
public event DragEventHandler RightDragEvent;
public event DragEventHandler TopDragEvent;
public event DragEventHandler BottomDragEvent;

public UCPictureBox()
{
InitializeComponent();
SetLabelPos();
ShowDarg(false);
pictureBox1.Click += new EventHandler(pictureBox1_Click);
pictureBox1.DoubleClick += new EventHandler(pictureBox1_DoubleClick);

lbLeft.MouseHover += new EventHandler(Vertical_MouseHover);
lbLeft.MouseLeave += new EventHandler(Vertical_MouseLeave);
lbLeft.MouseDown += new MouseEventHandler(Vertica_MouseDown);
lbLeft.MouseUp += new MouseEventHandler(lbLeft_MouseUp);

lbRight.MouseHover += new EventHandler(Vertical_MouseHover);
lbRight.MouseLeave += new EventHandler(Vertical_MouseLeave);
lbRight.MouseDown += new MouseEventHandler(Vertica_MouseDown);
lbRight.MouseUp += new MouseEventHandler(lbRight_MouseUp);

lbTop.MouseHover += new EventHandler(Horizontal_MouseHover);
lbTop.MouseLeave += new EventHandler(Horizontal_MouseLeave);
lbTop.MouseDown += new MouseEventHandler(Vertical_MouseDown);
lbTop.MouseUp += new MouseEventHandler(lbTop_MouseUp);

lbBottom.MouseHover += new EventHandler(Horizontal_MouseHover);
lbBottom.MouseLeave += new EventHandler(Horizontal_MouseLeave);
lbBottom.MouseDown += new MouseEventHandler(Vertical_MouseDown);
lbBottom.MouseUp += new MouseEventHandler(lbBottom_MouseUp);
}

void Vertical_MouseHover(object sender, EventArgs e)
{
this.Cursor = Cursors.VSplit;
}

void Vertical_MouseLeave(object sender, EventArgs e)
{
this.Cursor = Cursors.Default;
}

void Horizontal_MouseHover(object sender, EventArgs e)
{
this.Cursor = Cursors.HSplit;
}

void Horizontal_MouseLeave(object sender, EventArgs e)
{
this.Cursor = Cursors.Default;
}

void Vertica_MouseDown(object sender, MouseEventArgs e)
{
this.StartX = e.X;
}

void Vertical_MouseDown(object sender, MouseEventArgs e)
{
this.StartY = e.Y;
}

void lbLeft_MouseUp(object sender, MouseEventArgs e)
{
this.EndX = e.X;
int marginX = EndX - StartX;
if (LeftDragEvent != null)
{
DragEventArgs dragArgs = new DragEventArgs(marginX);
if (LeftDragEvent(dragArgs))
{
SetLabelPos();
}
}
}

void lbRight_MouseUp(object sender, MouseEventArgs e)
{
this.EndX = e.X;
int marginX = EndX - StartX;
if (RightDragEvent != null)
{
DragEventArgs dragArgs = new DragEventArgs(marginX);
if (RightDragEvent(dragArgs))
{
SetLabelPos();
}
}
}

void lbTop_MouseUp(object sender, MouseEventArgs e)
{
this.EndY = e.Y;
int marginY = EndY - StartY;
if (TopDragEvent != null)
{
DragEventArgs dragArgs = new DragEventArgs(marginY);
if (TopDragEvent(dragArgs))
{
SetLabelPos();
}
}
}

void lbBottom_MouseUp(object sender, MouseEventArgs e)
{
this.EndY = e.Y;
int marginY = EndY - StartY;
if (BottomDragEvent != null)
{
DragEventArgs dragArgs = new DragEventArgs(marginY);
if (BottomDragEvent(dragArgs))
{
SetLabelPos();
}
}
}

void pictureBox1_DoubleClick(object sender, EventArgs e)
{
ShowDarg(false);
}

void pictureBox1_Click(object sender, EventArgs e)
{
if (pictureBox1.Image == null)
{
return;
}
ShowDarg(true);
}

/// <summary>
/// 规范操作点的位置
/// </summary>
private void SetLabelPos()
{
int HX1 = pictureBox1.Location.X - lbLeft.Width / 2;
int HX2 = pictureBox1.Location.X + pictureBox1.Width - lbRight.Width / 2;
int HY1 = pictureBox1.Location.Y + pictureBox1.Height / 2;

int VX1 = pictureBox1.Location.X + pictureBox1.Width / 2;
int VY1 = pictureBox1.Location.Y - lbTop.Height / 2;
int VY2 = pictureBox1.Location.Y + pictureBox1.Height - lbBottom.Height / 2;

this.lbLeft.Location = new Point(HX1, HY1);
this.lbRight.Location = new Point(HX2, HY1);
this.lbTop.Location = new Point(VX1, VY1);
this.lbBottom.Location = new Point(VX1, VY2);
}

/// <summary>
/// 设置拖动按钮的可见性
/// </summary>
/// <param name="isShow">是否可见</param>
private void ShowDarg(bool isShow)
{
lbLeft.Visible = isShow;
lbRight.Visible = isShow;
lbTop.Visible = isShow;
lbBottom.Visible = isShow;
if (isShow)
{
pictureBox1.BorderStyle = BorderStyle.FixedSingle;
}
else
{
pictureBox1.BorderStyle = BorderStyle.None;
}
}
}

/// <summary>
/// 拖动事件参数
/// </summary>
public class DragEventArgs : EventArgs
{
public DragEventArgs(int margin)
{
this.Margin = margin;
}

public int Margin
{
get;
set;
}
}
}

主界面如下图,由上至下,由左至右分别为:操作框,保存进度条,panel (属性AutoScroll为true),ucPictureBox(ID为pictureBox1),backgroundworker

下面看代码:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Collections.Specialized;
using System.Deployment.Application;
using System.Web;
using WIA;

namespace WIAapp
{
/// <summary>
/// created by 邢秉公
/// 功能:扫描
/// </summary>
public partial class Main : Form
{
public Main()
{
InitQueryStringParameters();
InitializeComponent();
DisableControls();
comboBox1.SelectedIndex = 0;
/*
for (int i = 0; i < 2; i++)
{
using (FileStream fs = new FileStream(@"c:\" + i + ".jpg", FileMode.OpenOrCreate))
{
int leng=(int)fs.Length;
byte[] buffer = new byte[fs.Length];
fs.Read(buffer, 0, buffer.Length);
fs.Seek(0, SeekOrigin.Begin);
FillImageBuffers(buffer);
}
}
*/
pictureBox1.LeftDragEvent += new UCPictureBox.DragEventHandler(pictureBox1_LeftDragEvent);
pictureBox1.RightDragEvent += new UCPictureBox.DragEventHandler(pictureBox1_RightDragEvent);
pictureBox1.TopDragEvent += new UCPictureBox.DragEventHandler(pictureBox1_TopDragEvent);
pictureBox1.BottomDragEvent += new UCPictureBox.DragEventHandler(pictureBox1_BottomDragEvent);

}

bool pictureBox1_BottomDragEvent(DragEventArgs e)
{
if (Math.Abs(e.Margin) >= pictureBox1.Height)
{
return false;
}
int originalBottom = Convert.ToInt32(textBoxBottom.Text);
int currentBottom = originalBottom - e.Margin;
if (currentBottom <= 0)
{
currentBottom = 0;
}
textBoxBottom.Text = currentBottom.ToString();
if (!SetImageFile())
{
textBoxBottom.Text = originalBottom.ToString();
return false;
}
return true;
}

bool pictureBox1_TopDragEvent(DragEventArgs e)
{
if (Math.Abs(e.Margin) >= pictureBox1.Height)
{
return false;
}
int originalTop = Convert.ToInt32(textBoxTop.Text);
int currentTop = originalTop + e.Margin;
if (currentTop <= 0)
{
currentTop = 0;
}

textBoxTop.Text = currentTop.ToString();
if (!SetImageFile())
{
textBoxTop.Text = originalTop.ToString();
return false;
}
return true;
}

bool pictureBox1_RightDragEvent(DragEventArgs e)
{
if (Math.Abs(e.Margin) >= pictureBox1.Width)
{
return false;
}
int originalRight = Convert.ToInt32(textBoxRight.Text);
int currentRight = originalRight - e.Margin;
if (currentRight <= 0)
{
currentRight = 0;
}
textBoxRight.Text = currentRight.ToString();
if (!SetImageFile())
{
textBoxRight.Text = originalRight.ToString();
return false;
}
return true;
}

bool pictureBox1_LeftDragEvent(DragEventArgs e)
{
if (e.Margin >= pictureBox1.Width)
{
return false;
}
int originalLeft = Convert.ToInt32(textBoxLeft.Text);
int currentLeft = originalLeft + e.Margin;
if (currentLeft <= 0)
{
currentLeft = 0;
}
textBoxLeft.Text = currentLeft.ToString();
if (!SetImageFile())
{
textBoxLeft.Text = originalLeft.ToString();
return false;
}
return true;
}

/// <summary>
/// 扫描后的文件集合
/// </summary>
List<ImageFile> ImageFiles = new List<ImageFile>();

/// <summary>
/// 所有图片的字符序列集合
/// </summary>
List<byte[]> ImageBuffers = new List<byte[]>();

/// <summary>
/// 参数集合
/// </summary>
NameValueCollection Parameters = null;

//扫描
private void scanToolStripMenuItem_Click(object sender, EventArgs e)
{
//AddImageFile();
AddImageFileDefaultDevice();
}

//退出
private void exitToolStripMenuItem_Click(object sender, EventArgs e)
{
CloseForm();
}

//保存
private void saveToolStripMenuItem_Click(object sender, EventArgs e)
{
//SaveImage(); //若使用此方法,请修改扫描和编辑方法的currentBuffer为CurrentBuffer
DisableControls();
backgroundWorker1.RunWorkerAsync();

}

/// <summary>
/// 调整ImageFile
/// </summary>
private void buttonConvert_Click(object sender, EventArgs e)
{
SetImageFile();
}

private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
textBoxLeft.Text = "0";
textBoxRight.Text = "0";
textBoxTop.Text = "0";
textBoxBottom.Text = "0";
}

/// <summary>
/// 调整图片
/// </summary>
private bool SetImageFile()
{
try
{
ImageProcess imgProcess = new ImageProcessClass();

//旋转角度
object flipName = "RotateFlip";
Object angleName = "RotationAngle";
object angleValue = Convert.ToInt16(comboBox1.SelectedItem);
imgProcess.Filters.Add(imgProcess.FilterInfos.get_Item(ref flipName).FilterID, 0);
imgProcess.Filters[1].Properties.get_Item(ref angleName).set_Value(ref angleValue);

//调整百分比
double width = ImageFiles[ImageFiles.Count - 1].Width * Convert.ToDouble(textBoxPercent.Text) / 100;
double height = ImageFiles[ImageFiles.Count - 1].Height * Convert.ToDouble(textBoxPercent.Text) / 100;
int angle = Convert.ToInt16(comboBox1.SelectedItem);
object scaleName = "Scale";
Object widthName = "MaximumWidth";
Object widthValue = width;
Object heightName = "MaximumHeight";
Object heightValue = height;
Object preserveName = "PreserveAspectRatio";
Object preserveValue = false;

imgProcess.Filters.Add(imgProcess.FilterInfos.get_Item(ref scaleName).FilterID, 1);
imgProcess.Filters[1].Properties.get_Item(ref widthName).set_Value(ref widthValue);
imgProcess.Filters[1].Properties.get_Item(ref heightName).set_Value(ref heightValue);
imgProcess.Filters[1].Properties.get_Item(ref preserveName).set_Value(ref preserveValue);

//左右上下缩进
string left="0", right="0", top="0", bottom="0";
switch (Convert.ToInt16(comboBox1.SelectedItem))
{
case 0:
left = textBoxLeft.Text;
right = textBoxRight.Text;
top = textBoxTop.Text;
bottom = textBoxBottom.Text;
break;
case 90:
left = textBoxTop.Text;
right = textBoxBottom.Text;
top = textBoxRight.Text;
bottom = textBoxLeft.Text;
break;
case 180:
left = textBoxRight.Text;
right = textBoxLeft.Text;
top = textBoxBottom.Text;
bottom = textBoxTop.Text;
break;
case 270:
left = textBoxBottom.Text;
right = textBoxTop.Text;
top = textBoxLeft.Text;
bottom = textBoxRight.Text;
break;
default:
break;
}
object cropName = "Crop";
Object leftName = "Left";
Object leftValue = Convert.ToDouble(left);
Object rightName = "Right";
Object rightValue = Convert.ToDouble(right);
Object topName = "Top";
Object topValue = Convert.ToDouble(top);
Object bottomName = "Bottom";
Object bottomValue = Convert.ToDouble(bottom);
imgProcess.Filters.Add(imgProcess.FilterInfos.get_Item(ref cropName).FilterID, 2);
imgProcess.Filters[2].Properties.get_Item(ref leftName).set_Value(ref leftValue);
imgProcess.Filters[2].Properties.get_Item(ref rightName).set_Value(ref rightValue);
imgProcess.Filters[2].Properties.get_Item(ref topName).set_Value(ref topValue);
imgProcess.Filters[2].Properties.get_Item(ref bottomName).set_Value(ref bottomValue);

//显示图像

byte[] currentBuffer = imgProcess.Apply(ImageFiles[ImageFiles.Count - 1]).FileData.get_BinaryData() as byte[];
FillImageBuffers(currentBuffer);
using (MemoryStream ms = new MemoryStream())
{
ms.Write(currentBuffer, 0, currentBuffer.Length);
//if (angle == 90 || angle == 270)
//{
// double temp = width;
// width = height;
// height = temp;
////pictureBox1.Width = Convert.ToInt16(width) - Convert.ToInt16(topValue) - Convert.ToInt16(bottomValue);
////pictureBox1.Height = Convert.ToInt16(height) - Convert.ToInt16(leftValue) - Convert.ToInt16(rightValue);
//}
// pictureBox1.Width = Convert.ToInt16(width) - Convert.ToInt16(leftValue) - Convert.ToInt16(rightValue);
// pictureBox1.Height = Convert.ToInt16(height) - Convert.ToInt16(topValue) - Convert.ToInt16(bottomValue);
Bitmap bitMap = new Bitmap(ms);
pictureBox1.Width = bitMap.Width;
pictureBox1.Height=bitMap.Height;

pictureBox1.Image = Image.FromStream(ms);
}
return true;
}
catch (Exception ex)
{
MessageBox.Show("设置值超出范围,请修改参数");
return false;
}
}

/// <summary>
/// 选择扫描仪扫描
/// </summary>
private void AddImageFile()
{
ImageFile imageFile = null;
CommonDialogClass dig = new WIA.CommonDialogClass();
try
{
imageFile = dig.ShowAcquireImage(WiaDeviceType.ScannerDeviceType,
WiaImageIntent.ColorIntent,
WiaImageBias.MaximizeQuality,
FormatID.wiaFormatJPEG, true, true, false);
}
catch (System.Runtime.InteropServices.COMException ex)
{
MessageBox.Show(ex.Message);
imageFile = null;
}
if (imageFile != null)
{
panel1.Visible = true;
ImageFiles.Add(imageFile);
var buffer = imageFile.FileData.get_BinaryData() as byte[];
using (MemoryStream ms = new MemoryStream())
{
ms.Write(buffer, 0, buffer.Length);
pictureBox1.Image = Image.FromStream(ms);
}
}
}

/// <summary>
/// 使用默认扫描仪扫描
/// </summary>
private void AddImageFileDefaultDevice()
{
InitOperParas();
DeviceManager manager = new DeviceManagerClass();
Device device = null;
foreach (DeviceInfo info in manager.DeviceInfos)
{
if (info.Type != WiaDeviceType.ScannerDeviceType)
continue;
device = info.Connect();
break;
}
Item item = device.Items[1];

CommonDialogClass cdc = new WIA.CommonDialogClass();
ImageFile imageFile = cdc.ShowTransfer(item, FormatID.wiaFormatJPEG, true) as ImageFile;
if (imageFile != null)
{
panel1.Visible = true;
ImageFiles.Add(imageFile);
byte[] currentBuffer = imageFile.FileData.get_BinaryData() as byte[];
FillImageBuffers(currentBuffer);
//using (MemoryStream ms = new MemoryStream())
//{
// ms.Write(currentBuffer, 0, currentBuffer.Length);
// Bitmap map = new Bitmap(ms);
// pictureBox1.Width = map.Width;
// pictureBox1.Height = map.Height;
// pictureBox1.Image = Image.FromStream(ms);
//}
SetImageFile();
EnableControls();
}
}

/// <summary>
/// 初始化参数
/// </summary>
private void InitQueryStringParameters()
{
Parameters = new NameValueCollection();

if (ApplicationDeployment.IsNetworkDeployed)
{
string queryString = ApplicationDeployment.CurrentDeployment.ActivationUri.Query;
Parameters = HttpUtility.ParseQueryString(queryString);

}
}

/// <summary>
/// 初始化和保存后,保存和操作不可用
/// </summary>
private void DisableControls()
{
saveToolStripMenuItem.Enabled = false;
panel1.Visible = false;
}

/// <summary>
/// 扫描后,保存和操作可用
/// </summary>
private void EnableControls()
{
saveToolStripMenuItem.Enabled = true;
panel1.Visible = true;
}

/// <summary>
/// 初始化操作参数
/// </summary>
private void InitOperParas()
{
textBoxLeft.Text = "0";
textBoxRight.Text = "0";
textBoxTop.Text = "0";
textBoxBottom.Text = "0";
comboBox1.SelectedIndex = 0;
textBoxPercent.Text = "50";
}

/// <summary>
/// 更新或填充图片集合
/// </summary>
private void FillImageBuffers(byte[] buffer)
{
if (ImageBuffers.Count == ImageFiles.Count && ImageBuffers.Count > 0)
{
int i = ImageBuffers.Count;
ImageBuffers.RemoveAt(i - 1);
}
ImageBuffers.Add(buffer);
}

/// <summary>
/// 关闭当前窗口
/// </summary>
private void CloseForm()
{
this.ImageBuffers.Clear();
this.ImageFiles.Clear();
this.Close();
}

/// <summary>
/// 批量保存
/// </summary>
/// <param name="worker"></param>
/// <param name="e"></param>
private void DoWork(BackgroundWorker worker, DoWorkEventArgs e)
{
worker.ReportProgress(10);
//List<byte[]> buffers = e.Argument as List<byte[]>;
for (int i = 0; i < ImageBuffers.Count; i++)
{
using (ScanServiceRef.ScanServiceSoapClient client = new WIAapp.ScanServiceRef.ScanServiceSoapClient())
{
client.SaveStream(ImageBuffers[i], new Guid(Parameters["bizID"]),
new Guid(Parameters["userID"]), Parameters["userName"], Parameters["formObjectID"]);
}
int percent = (int)((double)(i + 1) / ImageBuffers.Count * 100);
worker.ReportProgress(percent);
}
}

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker worker = sender as BackgroundWorker;
DoWork(worker, e);
}

private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
progressBar1.Value = e.ProgressPercentage;
}

private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
progressBar1.Value = 100;
ImageBuffers.Clear();
ImageFiles.Clear();
DialogResult dialog = MessageBox.Show("保存成功,是否继续扫描?", "", MessageBoxButtons.YesNo);
if (dialog == DialogResult.Yes)
{
AddImageFileDefaultDevice();
}
else
{
CloseForm();
}
}
}
}

运行结果:



原文地址:https://www.cnblogs.com/xingbinggong/p/2342760.html