文档章节

用手机远程控制扫描仪

yushulx
 yushulx
发布于 2014/09/26 09:17
字数 745
阅读 574
收藏 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
博文 91
码字总数 52150
作品 0
杭州
树莓派应用:无线扫描仪

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

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

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

yushulx
2014/06/25
566
0
Linux配置文件的目录位置全集(一)

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

oecp
2011/06/14
0
0
OCR文字识别软件是怎么导入图像的

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

ABBYY
2016/12/07
10
0
Fedora 13 Beta发布 新界面多图赏

距离正式发布还有一个月多点的时候,Fedora 13的第一个Beta测试版今天终于出炉了。简单体验证明,新系统非常令人兴奋,值得期待。 Fedora 13开发代号Goddard,定于5月6日发布RC候选版,5月1...

红薯
2010/04/14
856
5

没有更多内容

加载失败,请刷新页面

加载更多

启动线程以及安全终止线程

启动 使用start()方法可以启动线程。 start()方法的含义是告知线程规划器线程已初始化完毕,可以分给这个线程时间片了(执行run()方法)。 安全终止线程 示例代码 import java.util.concurr...

karma123
7分钟前
1
0
Python+OpenCV 图像风格迁移(模仿名画)

现在很多人都喜欢拍照(自拍)。有限的滤镜和装饰玩多了也会腻,所以就有 APP 提供了模仿名画风格的功能,比如 prisma、versa 等,可以把你的照片变成 梵高、毕加索、蒙克 等大师的风格。 这...

crossin
11分钟前
1
0
karabiner json语法

karabiner json语法 to_if_alone 如果同时制定了to, 那么to对应的key必须是非可见字符,例如control,shift或者command, 为什么呢? If to events are specified, to events are released befo...

黄威
12分钟前
1
0
学习设计模式——工厂方法模式

1. 认识工厂方法模式 1. 功能:定义一个用于创建对象的接口,让子类决定实例化哪一个类,该模式使一个类的实例化延迟到其子类中。 2. 组织结构: Product: 定义工厂方法中用来创建对象的接口...

江左煤郎
12分钟前
1
0
常用的大数据技术有哪些?

大数据技术为决策提供依据,在政府、企业、科研项目等决策中扮演着重要的角色,在社会治理和企业管理中起到了不容忽视的作用,很多国 家,如中国、美国以及欧盟等都已将大数据列入国家发展战...

董黎明
15分钟前
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部