文档章节

用手机远程控制扫描仪

yushulx
 yushulx
发布于 2014/09/26 09:17
字数 745
阅读 554
收藏 4

目前的扫描仪都还不够智能,没有提供扫描仪和手机之间的直接通信。所以我们可以通过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


本文转载自:http://www.codepool.biz/tech-frontier/android/wireless-twain-document-scanning-on-android.html

共有 人打赏支持
yushulx
粉丝 25
博文 88
码字总数 49460
作品 0
杭州
树莓派应用:无线扫描仪

传统的扫描仪都是需要通过USB连接到PC上使用的。如果多人共用扫描仪,比如办公室里,需要经常插拔,更换PC,安装驱动,非常麻烦。现在搭载Android系统的智能扫描仪已经出现了,用户可以很方便...

yushulx
2016/11/15
128
0
如何通过WebSocket实现远程文件扫描

当我们使用的硬件设备变得更加多元化,各种尺寸,各种系统的手机,平板,电脑会让开发消耗更多的时间和精力。因此把应用部署到服务端才是上策。 参考原文: How to Remotely Scan Documents...

yushulx
2014/06/25
566
0
OCR文字识别软件是怎么导入图像的

ABBYY FineReader Pro for Mac作为ABBYY旗下重要的OCR文字识别软件之一,专为Mac用户定制,为各种各样的任务提供了单一、全面的解决方案,它是所有需要扫描和处理数字纸质文档副本或PDF文件的...

ABBYY
2016/12/07
10
0
Linux配置文件的目录位置全集(一)

好久没有再学习linux了,为了不被遗忘的太快整理了相关的一些文件来给大家共享一下。 关于Linux中各类程序的配置文件有很多,写这个文章的主要目的就是为了让大家能方便的找到linux中的程序的...

oecp
2011/06/14
0
0
Google Android SDK开发范例大全(第2版)

内容简介 《Google Android SDK开发范例大全(第2版)》在上一版的基础上,以Android手机应用程序开发(采用AndroidSDK2.1)为主题,通过160多个范例全面且深度地整合了手机、网络及服务等多个...

21gprs
2014/05/04
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

MySQL 8 在 Windows 下安装及使用

MySQL 8 带来了全新的体验,比如支持 NoSQL、JSON 等,拥有比 MySQL 5.7 两倍以上的性能提升。本文讲解如何在 Windows 下安装 MySQL 8,以及基本的 MySQL 用法。 下载 下载地址 https://dev....

waylau
35分钟前
0
0
微信第三方平台 access_token is invalid or not latest

微信第三方开发平台code换session_key说的特别容易,但是我一使用就带来无穷无尽的烦恼,搞了一整天也无济于事. 现在记录一下解决问题的过程,方便后来人参考. 我遇到的这个问题搜索了整个网络也...

自由的开源
今天
0
0
openJDK之sun.misc.Unsafe类CAS底层实现

注:这篇文章参考了https://www.cnblogs.com/snowater/p/8303698.html 1.sun.misc.Unsafe中CAS方法 在sun.misc.Unsafe中CAS方法如下: compareAndSwapObject(java.lang.Object arg0, long a......

汉斯-冯-拉特
今天
1
0
设计模式之五 责任链模式(Chain of Responsibility)

一. 场景 相信我们都有过这样的经历; 我们去职能部门办理一个事情,先去了A部门,到了地方被告知这件事情由B部门处理; 当我们到了B部门的时候,又被告知这件事情已经移交给了C部门处理; ...

JackieRiver
今天
1
0
Android中的设计模式之命令模式

参考 《设计模式:可复用面向对象软件的基础 》5.2 Command 命令 对象行为型模式 《Android源码设计模式解析与实战》第11章 让程序畅通执行--命令模式 意图 将一个请求封装为一个对象,从而使...

newtrek
昨天
5
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部