首页 > 代码库 > 用手机远程控制扫描仪

用手机远程控制扫描仪

目前的扫描仪都还不够智能,没有提供扫描仪和手机之间的直接通信。所以我们可以通过PC作为桥接,使用Dynamic .NET TWAIN在PC上搭建一个扫描服务,实现手机对扫描仪的远程控制。这个简单的sample只需要在手机上点击扫描按钮,就可以触发扫描仪工作,获取图像。

参考:Wireless TWAIN Document Scanning on Android

PC上的TWAIN扫描

下载Dynamic .NET TWAIN SDK

下载JSON.NET

运行Visual Studio,创建一个Windows Forms工程:

添加引用:DynamicDotNetTWAINNewtonsoft.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工程,添加一个ButtonImageView

申明权限:

<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


用手机远程控制扫描仪