目前的扫描仪都还不够智能,没有提供扫描仪和手机之间的直接通信。所以我们可以通过PC作为桥接,使用Dynamic .NET TWAIN在PC上搭建一个扫描服务,实现手机对扫描仪的远程控制。这个简单的sample只需要在手机上点击扫描按钮,就可以触发扫描仪工作,获取图像。
参考:Wireless TWAIN Document Scanning on Android
PC上的TWAIN扫描
下载JSON.NET
运行Visual Studio,创建一个Windows Forms工程:
添加引用:DynamicDotNetTWAIN和Newtonsoft.Json
初始化TWAIN组件:
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服务:
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。
申明权限:
<uses-permission android:name = "android.permission.INTERNET"/>
创建socket链接:
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
git clone https://github.com/DynamsoftRD/Wireless-TWAIN-Scan-on-Android.git