目前的扫描仪都还不够智能,没有提供扫描仪和手机之间的直接通信。所以我们可以通过PC作为桥接,使用Dynamic .NET TWAIN在PC上搭建一个扫描服务,实现手机对扫描仪的远程控制。这个简单的sample只需要在手机上点击扫描按钮,就可以触发扫描仪工作,获取图像。
参考:Wireless TWAIN Document Scanning on Android
PC上的TWAIN扫描
下载JSON.NET
运行Visual Studio,创建一个Windows Forms工程:
添加引用:DynamicDotNetTWAIN和Newtonsoft.Json
初始化TWAIN组件:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
private
void
initTWAINComponent()
{
dynamicDotNetTwain =
new
Dynamsoft.DotNet.TWAIN.DynamicDotNetTwain();
dynamicDotNetTwain.IfShowUI =
false
;
dynamicDotNetTwain.IfThrowException =
true
;
dynamicDotNetTwain.MaxImagesInBuffer = 1;
dynamicDotNetTwain.IfAppendImage =
false
;
dynamicDotNetTwain.IfDisableSourceAfterAcquire =
true
;
int
iNum;
dynamicDotNetTwain.OpenSourceManager();
for
(iNum = 0; iNum < dynamicDotNetTwain.SourceCount; iNum++)
{
comboBox1.Items.Add(dynamicDotNetTwain.SourceNameItems(Convert.ToInt16(iNum)));
}
if
(iNum > 0)
comboBox1.SelectedIndex = 0;
dynamicDotNetTwain.OnPostAllTransfers += dynamicDotNetTwain_OnPostAllTransfers;
}
|
使用TCPListener创建Socket服务:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
|
using
System;
using
System.Collections.Generic;
using
System.Linq;
using
System.Text;
using
System.Threading.Tasks;
using
System.IO;
using
System.Net;
using
System.Net.Sockets;
using
Newtonsoft.Json;
using
Newtonsoft.Json.Linq;
namespace
WirelessTWAIN
{
class
ServerManager
{
TcpListener server =
null
;
NetworkStream stream =
null
;
WirelessTWAIN twain =
null
;
Byte[] imageData;
public
ServerManager(WirelessTWAIN twain)
{
this
.twain = twain;
}
public
void
run()
{
try
{
// Set the TcpListener on port 13000.
Int32 port = 2015;
IPAddress localAddr = IPAddress.Parse(
"192.168.8.84"
);
// server IP
// TcpListener server = new TcpListener(port);
server =
new
TcpListener(localAddr, port);
// Start listening for client requests.
server.Start();
// Buffer for reading data
Byte[] bytes =
new
Byte[256];
String data =
null
;
// Enter the listening loop.
while
(
true
)
{
Console.Write(
"Waiting for a connection... "
);
// Perform a blocking call to accept requests.
// You could also user server.AcceptSocket() here.
TcpClient client = server.AcceptTcpClient();
Console.WriteLine(
"Connected!"
);
data =
null
;
// Get a stream object for reading and writing
stream = client.GetStream();
int
i;
// Loop to receive all the data sent by the client.
while
((i = stream.Read(bytes, 0, bytes.Length)) != 0)
{
// Translate data bytes to a ASCII string.
data = System.Text.Encoding.ASCII.GetString(bytes, 0, i);
Console.WriteLine(
"Received: {0}"
, data);
JObject jobj = JObject.Parse(data);
JToken token = jobj.GetValue(
"type"
);
if
(token !=
null
)
{
string
result = token.ToString();
Console.WriteLine(
"Received: {0}"
, result);
if
(result.Equals(
"data"
))
{
stream.Write(imageData, 0, imageData.Length);
stream.Flush();
imageData =
null
;
}
else
if
(result.Equals(
"info"
))
{
twain.scanImage();
}
}
}
stream =
null
;
// Shutdown and end connection
Console.WriteLine(
"close connection"
);
client.Close();
}
}
catch
(SocketException e)
{
Console.WriteLine(
"SocketException: {0}"
, e);
}
finally
{
// Stop listening for new clients.
server.Stop();
}
}
public
void
prepareData(Byte[] data)
{
this
.imageData = data;
}
public
void
sendData()
{
if
(stream !=
null
&& imageData !=
null
)
{
JObject jobj =
new
JObject();
jobj.Add(
"length"
, imageData.Length);
string
msg = jobj.ToString();
byte
[] msgBytes = System.Text.Encoding.ASCII.GetBytes(msg);
stream.Write(msgBytes, 0, msgBytes.Length);
stream.Flush();
}
}
}
}
|
Android手机客户端接收显示图像
新建Android工程,添加一个Button和ImageView。
申明权限:
1
|
<
uses-permission
android:name = "android.permission.INTERNET"/>
|
创建socket链接:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
|
package
com.dynamsoft.io;
import
java.io.BufferedInputStream;
import
java.io.BufferedOutputStream;
import
java.io.ByteArrayOutputStream;
import
java.io.IOException;
import
java.net.Socket;
import
java.net.UnknownHostException;
import
com.dynamsoft.ui.UIListener;
import
com.google.gson.JsonElement;
import
com.google.gson.JsonObject;
import
com.google.gson.JsonParseException;
import
com.google.gson.JsonParser;
public
class
SocketClient
extends
Thread {
private
Socket mSocket;
private
UIListener mUIListener;
public
SocketClient(UIListener client) {
mUIListener = client;
}
@Override
public
void
run() {
// TODO Auto-generated method stub
super
.run();
try
{
mSocket =
new
Socket(
"192.168.8.84"
,
2015
);
BufferedOutputStream outputStream =
new
BufferedOutputStream(mSocket.getOutputStream());
BufferedInputStream inputStream =
new
BufferedInputStream(mSocket.getInputStream());
ByteArrayOutputStream out =
new
ByteArrayOutputStream();
JsonObject jsonObj =
new
JsonObject();
jsonObj.addProperty(
"type"
,
"info"
);
byte
[] buff =
new
byte
[
256
];
int
len =
0
;
String msg =
null
;
outputStream.write(jsonObj.toString().getBytes());
outputStream.flush();
int
sum =
0
;
int
total =
0
;
boolean
isDataReady =
false
;
while
((len = inputStream.read(buff)) != -
1
) {
if
(!isDataReady) {
msg =
new
String(buff,
0
, len);
// JSON analysis
JsonParser parser =
new
JsonParser();
boolean
isJSON =
false
;
JsonElement element =
null
;
try
{
element = parser.parse(msg);
if
(element !=
null
) {
isJSON =
true
;
}
}
catch
(JsonParseException e) {
System.out.println(
"exception: "
+ e);
}
if
(isJSON) {
System.out.println(element.toString());
JsonObject obj = element.getAsJsonObject();
element = obj.get(
"length"
);
if
(element !=
null
) {
total = element.getAsInt();
jsonObj =
new
JsonObject();
jsonObj.addProperty(
"type"
,
"data"
);
outputStream.write(jsonObj.toString().getBytes());
outputStream.flush();
isDataReady =
true
;
}
}
}
else
{
out.write(buff,
0
, len);
sum += len;
if
(sum == total) {
break
;
}
}
}
mUIListener.updateImage(out);
System.out.println(
"close"
);
outputStream.close();
inputStream.close();
}
catch
(UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
catch
(IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
finally
{
try
{
mSocket.close();
mSocket =
null
;
}
catch
(IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println(
"data sent"
);
}
public
void
close() {
if
(mSocket !=
null
) {
try
{
mSocket.close();
}
catch
(IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
|
源码
https://github.com/DynamsoftRD/Wireless-TWAIN-Scan-on-Android
1
|
git clone https://github.com/DynamsoftRD/Wireless-TWAIN-Scan-on-Android.git
|