官网链接:http://www.sane-project.org/ //简介、源码以及文档应有尽有
参考链接:https://blog.csdn.net/yushulx/article/details/52996199#commentBox //非常感谢该篇博主的答疑解惑
SANE( Scanner Access Now Easy),是一个应用程序编程接口(API),它提供给任何光栅图像扫描仪硬件标准化的访问(平板扫描仪,手持式扫描仪,视频和静止相机,图像采集卡等。 )。该API是公共领域,它的讨论和发展,是对所有人开放。目前的源代码是UNIX(包括GNU / Linux)的和GNU通用公共许可证(下可用SANE API可用于专有应用程序和后端为好,不过)。有关许可证的更多细节上可以找到我们的许可页面。
SANE是一种通用扫描仪接口。这样的通用接口的价值在于,它允许写入每个图像采集装置,而不是为每个设备和应用的一个驱动器只有一个驱动器。所以,如果你有三个应用程序和四个设备,传统上你不得不写12次不同的程序(3*4种驱动程序); 有了 SANE,这个数字减少到7(3+4种驱动程序)。当然,储蓄获得的越来越多的驱动程序和/或应用程序被添加更大。
不仅SANE减少开发时间和代码重复,这也引发了在哪些应用程序可以工作的水平。这样,就会使这在以前是闻所未闻的,在UNIX世界的应用。虽然SANE主要是针对UNIX环境中,该标准已被精心设计,使之可以实现在几乎任何硬件或操作系统的API。
虽然SANE是“Scanner Access Now Easy”的首字母缩写的希望当然是SANE在某种意义上确实是明智的,这将是很容易实现的API,同时适应今天的扫描仪硬件和应用程序所需的所有功能。具体而言,SANE应足够宽,以适应装置,例如扫描仪,数码相机和摄像机,以及如图像文件的过滤器的虚拟设备。
如果你熟悉TWAIN,你可能会问,为什么有需要 SANE。简单地说,TWAIN不会将用户界面从设备的驱动程序分开。很不幸,使得它很难,如果不是不可能的,提供图像采集设备的网络透明地访问(如果你有一个LAN全机的是有用的,但是扫描仪连接到只有一两台机器,这显然也为远程相机和这样)。这也意味着,任何特定的TWAIN驱动程序是相当多取一个特定的GUI API(无论是Win32的或Mac的API)。与此相反,SANE干净地从他们的在一个用户界面表示分离控制。结果是,SANE支持命令行驱动接口或网络透明的扫描。
总之,如果TWAIN是一个好一点的设计的话,SANE也就没有存在必要了,存在即合理!事实上TWAIN根本不SANE(sane英文adj. 健全的;理智的;[临床] 神志正常的)。
下载SANE后端
sudo apt-get install sane
or
sane-utilssudo apt-get install
最好做一个libsane.so的软链接(lisane.so.1(本身也是个软链接)可能在lib64或其他lib文件夹下,具体情况根据系统情况而定,)
ln -s /usr/lib/lisane.so.1 /usr/lib/libsane.sosudo
下载SANE官方前端程序(Xsane:很好用)
sudo apt-get install xsane
红帽系下载使用yum
相关命令行
sane-find-scanner //找到SCSI和USB扫描仪和他们的设备文件,具体请看 -h 或 man
scanimage -V //查看当前版本,具体请看 -h 或 man
scanimage -L //查看当前可用设备列表,具体请看 -h 或 man
xsane & //好用的GUI扫描仪前端应用程序,后台启动
xscanimage & //官方简单的GUI前端程序,功能、界面较上者要简单
...... ...... ...... ...... ...... ......
SANE是开源的C语言库,其动态库名称为lisane.so.1的软链接,SANE的标准旨在通过提供一个标准的应用编程接口来访问光栅扫描仪硬件,简化软件的开发。这将减少不同的驱动程序执行的数目,从而减少重新实现类似的代码的需要。
SANE是应用编程接口(API),其提供到任何光栅图像扫描仪硬件标准化访问。标准化的接口允许写只是一个为每个扫描仪设备驱动程序,而不是针对每个扫描仪和应用的一个驱动程序。在所需的驱动程序数量的减少提供了开发时间,节省显著。更重要的是,SANE的提出在哪些应用程序可以工作的水平。这样,就会使这在以前是闻所未闻的,在UNIX世界的应用。虽然SANE主要是针对UNIX环境中,该标准已被精心设计,使之可以实现在几乎任何硬件或操作系统的API。
通过一个健全的前端连接到后端的过程是依赖于平台。存在几种可能性:
有了这样的定义,后端是将出口函数名be_sane_read() 。因此,所有的后端将出口唯一的名称。只要一元后端知道这些名字,有可能几个后端链接时相结合,选择并在运行时动态地使用它们。#define sane_read be_sane_read
更重要的是,动态链接可以很容易地实现加载其它后端元后端需求。这是一个强大的机制,因为它允许通过安装共享库和更新配置文件只是增加新的后端。 (项目中使用:推荐链接)
可以说是一个图像采集系统的最重要的方面是如何将图像表示。SANE的方法是定义一个简单而强大的表现足以为大多数应用程序和设备。虽然表示是简单,界面经过精心定义的,允许在不破坏向后兼容性,将来扩展它。因此,将有可能以适应将来的应用程序或没有在这个标准被创建时的预期设备。
一个健全的图像是一个矩形区域。矩形区域被细分成若干个行和列的。在每行和每列的交叉点是二次像素。一个像素由一个或多个样本值的。每个采样值表示一个信道(例如,红色通道)。每个样本值具有一定的位深度。比特深度是固定的整个图像,并且可以是小至一个位。有效位深度是每个样品1,8,或16位。如果一个设备的自然位深度为别的东西,它是由驾驶员适当地缩放的样本值(例如,4位样品可通过四个因素来表示深度为8的采样值进行缩放)。
所述SANE API发送图像作为帧序列。每个帧覆盖相同的矩形区域作为整个图像,但也可以仅包含在最终图像中的信道的子集。例如,红色/绿色/蓝色图像既可以被发送作为包含样本值对于所有三个通道,或者它可以作为三个帧的序列来发送的单个帧:包含红色通道的第一帧,第二个绿色通道,第三蓝色通道。
从概念上讲,每个帧被发送一次一个字节。每个字节可以包含8个采样值(对于1中的图像的位深度),一个完整的样本值(对于8的图像的位深度),或部分样本值(对于16或更大的图像位深度)。在后一种情况下,每个样值的字节在机器的本地字节顺序被发送。对于深度图1中,最左边的像素被存储在最显著位,并在至少显著位的最右边的像素。
后端实现注意
一种基于网络的元后端将必须确保在图像数据中的字节顺序在必要时适当地调节。例如,当元后端连接到服务器代理,代理可以通知服务器的字节顺序的后端。然后,后端可以根据需要申请调整。在本质上,这实现了'接收机从左到右'的做法。
其中一帧中的样本值被发送的顺序在图中所示。如可以看到的,该值由行发送行和每行从发送最左侧到最右边的列中。左到右,顶到底部发送顺序适用于当图像在其正常方向看(因为这将在屏幕上显示)。
如果一个帧包含多个信道,则信道被以交错的方式发送。图示出了该对其中帧包含完整的红/绿/蓝色的8比特深度对于1比特深度图像,每一个字节包含8个样本值的情况下的单信道。换句话说,一比特深度1帧以字节交错的方式发送。
当发送一帧的图像帧,前端需要知道一个框架代表什么图像的一部分(它应该多少帧期望的那样)。为此,在SANE的API标记,类型为每一帧。这个标准SANE的版本支持以下帧类型:
SANE_FRAME_GRAY:
该帧包含表示从覆盖人的视觉范围内的光谱带的采样值的数据的一个单个信道。图像仅由该帧的。
SANE_FRAME_RGB:
该帧包含数据的三个通道,从红色,绿色和蓝色光谱带代表样本值。样本值交错顺序红色,绿色和蓝色。图像仅由该帧的。
SANE_FRAME_RED:
该帧包含数据的一个信道,它表示从红色光谱带样本值。完整的图像由三个框架: SANE_FRAME_RED,SANE_FRAME_GREEN和 SANE_FRAME_BLUE。的顺序的帧传输由后端选择。
SANE_FRAME_GREEN:
该帧包含数据的一个信道,它表示从绿色光谱带样本值。完整的图像由三个框架: SANE_FRAME_RED,SANE_FRAME_GREEN和 SANE_FRAME_BLUE。的顺序的帧传输由后端选择。
SANE_FRAME_BLUE:
该帧包含数据的一个信道,它表示从蓝色光谱带样本值。完整的图像由三个框架: SANE_FRAME_RED,SANE_FRAME_GREEN和 SANE_FRAME_BLUE。的顺序的帧传输由后端选择。
在SANE_FRAME_GRAY类型的帧中,当位深度为1时,可能只有两个采样值,1表示最小强度(黑色),0表示最大强度(白色)。对于所有其他位深度和帧类型组合,样本值0表示最小强度,较大的值表示强度增加。
位深度1和SANE_FRAME_RGB(或 SANE_FRAME_RED,SANE_FRAME_GREEN,SANE_FRAME_BLUE)的组合很少使用,可能并非每个前端都支持。
本节定义了SANE应用程序编程器接口(API)的版本1。任何SANE前端必须仅取决于本节中定义的接口。反之,任何SANE后端都必须根据此规范实现其功能。此处记录的接口在名为sane / sane.h的文件中声明为C可调用接口。通常应通过以下形式的C预处理程序指令包含此文件:
#include
SANE标准有望随着时间的推移而发展。只要对SANE标准进行了更改,可能会使现有的前端或后端与新标准不兼容,则必须增加主版本号。因此,只要它们实现的SANE标准的主要版本号相同,任何前端/后端对都是兼容的。前端可以通过允许小于预期的主要数字的主要数字来实现向后兼容(前提是该前端确实可以应付较早的版本)。相反,后端始终提供对标准的一个且仅一个版本的支持。如果特定应用程序确实要求可以同时访问同一后端的两个不同版本,则可以通过以不同名称安装两个版本来实现。
SANE版本控制还包括次要版本号和内部版本。虽然这些数字的控制权仍由后端的实现者控制,但建议的用法如下。次要版本随后端的每个正式发布而增加。后端的每个版本都会增加版本修订。
SANE API提供以下五个宏来管理版本号。
SANE_CURRENT_MAJOR:
该宏的值是接口实现的SANE标准的编号。
SANE_VERSION_CODE (maj,min,bld):
该宏可用于构建单调递增的版本代码。SANE版本代码由SANE标准主要版本号( maj),次要版本号 min和后端的构建修订版( bld)组成。主版本号和次版本号必须在0 ... 255范围内,并且内部版本必须在0 ... 65535范围内。在可以将关系运算符(例如,相等性或小于测试)直接应用于版本代码而不是分别应用于版本代码的三个组件的意义上,版本代码是单调的。
请注意,主要版本号仅确定前端/后端对是否兼容。次要版本和内部修订仅用于提供信息和修正错误的目的。
SANE_VERSION_MAJOR (vc):
此宏返回参数vc中传递的版本代码的主要版本号组件。
SANE_VERSION_MINOR(vc):
此宏返回参数vc中传递的版本代码的次要版本号部分。
SANE_VERSION_BUILD(vc):
此宏返回在参数vc中传递的版本代码的构建修订组件 。
SANE标准仅基于SANE特定的两种基本类型:SANE字节和字。
typedef some-scalar-type SANE_Byte ;
typedef some-scalar-type SANE_Word ;
SANE_Byte必须与某种能够容纳0到255范围内的值的标量C类型相对应 。SANE_Word必须能够容纳以下任何一项:
请注意,SANE标准未定义C类型的 SANE_Byte和SANE_Word映射到。例如,在某些平台上,后者可能映射到long int,而在其他平台上,它可能映射到int。因此,便携式SANE前端或后端必须不依赖于特定的映射。
SANE_Bool用于可以采用两个真值SANE_FALSE之一的变量和 SANE_TRUE。前一个值定义为0,而后一个定义为1。1个 下面给出了此类型的C声明。
#define SANE_FALSE 0 #define SANE_TRUE 1 typedef SANE_Word SANE_Bool;
需要注意的是SANE_Bool仅仅是一个别名SANE_Word。因此,始终使用后一种代替前一种是合法的。但是,为清楚起见,建议每当给定变量或形式参数对布尔对象具有固定解释时,均应使用 SANE_Bool。
SANE_Int用于变量,该变量可以采用-2^32至2^31 -1之间的整数值。其C声明如下。
typedef SANE_Word SANE_Int;
需要注意的是SANE_Int仅仅是一个别名SANE_Word。因此,始终使用后一种代替前一种是合法的。但是,为清楚起见,建议每当给定变量或形式参数具有固定解释作为整数对象时,都使用 SANE_Int。
SANE_固定用于变量,定点值可以在-32768到32767.9999之间,分辨率为1/65535。下面给出了与此类型有关的C声明。
#define SANE_FIXED_SCALE_SHIFT 16 typedef SANE_Word SANE_Fixed;
宏SANE_FIXED_SCALE_SHIFT给出固定二进制点的位置。该标准将该值定义为16,从而产生1/65536的分辨率。
需要注意的是SANE_Fixed仅仅是一个别名SANE_Word。因此,始终使用后一种代替前一种是合法的。但是,为清楚起见,建议每当给定变量或形式参数具有固定解释作为定点对象时,都使用 SANE_Fixed。
为方便起见,SANE还定义了两个宏,这些宏将定点值与C个双浮点值相互转换。
SANE_FIX (d):
返回小于双精度值 d的最大SANE定点值。不执行范围检查。如果 d的值超出范围,则结果不确定。
SANE_UNFIX (w):
返回与定点值 w对应的最接近的双精度机器编号 。
理智并没有要求在以下两个表达式保持为真(即使值w ^和d在范围内):
SANE_UNFIX(SANE_FIX(d))== d SANE_FIX(SANE_UNFIX(w))== w
换句话说,固定值和双精度值之间的转换可能是有损的。因此,建议避免在两种表示形式之间重复转换。
4.2.5.1字符类型
类型SANE_Char表示单个文本字符或符号。目前,此类型直接映射到基础C char类型(通常为一个字节)。此类字符的编码当前固定为ISO LATIN-1。该标准的未来版本可能将此类型映射到更大的类型,并允许多字节编码支持国际化。结果,应注意避免sizeof(SANE_Char)== sizeof(char)的假设 。
typedef char SANE_Char;
4.2.5.2字符串类型
类型SANE_String将文本字符串表示为C个char值的序列。序列的结尾由'\ 0'(NUL )字符指示 。
typedef SANE_Char * SANE_String; typedef const SANE_Char * SANE_String_Const;
类型SANE_String_Const由SANE提供,用于声明内容不可更改的字符串。请注意,在ANSI C中,声明
const SANE_String str;
声明一个常量字符串指针(不是指向常量值的字符串指针)。
通过称为SANE_Handle的不透明类型可以访问扫描仪 。下面给出了这种类型的C声明。
typedef void * SANE_Handle;
尽管此类型被声明为void指针,但应用程序不得尝试解释SANE_Handle的值。特别是,SANE不需要此类型的值是合法指针值。
大多数SANE操作都返回SANE_Status类型的值 指示操作是否完成。如果操作成功完成,则返回SANE_STATUS_GOOD。如果发生错误,将返回一个指示问题性质的值。表1 列出了可用状态码的完整列表。建议使用函数 sane_strstatus()将状态代码转换为清晰的字符串。
符号 | 码 | 描述 |
SANE_STATUS_GOOD | 0 | 操作成功完成。 |
SANE_STATUS_UNSUPPORTED | 1 | 不支持该操作。 |
SANE_STATUS_CANCELLED | 2 | 操作被取消。 |
SANE_STATUS_DEVICE_BUSY | 3 | 设备正忙--请稍后重试。 |
SANE_STATUS_INVAL | 4 | 数据或参数无效。 |
SANE_STATUS_EOF | 5 | 没有更多可用数据(文件结束)。 |
SANE_STATUS_JAMMED | 6 | 文档进纸器卡纸。 |
SANE_STATUS_NO_DOCS | 7 | 文档进纸器中的文档不足。 |
SANE_STATUS_COVER_OPEN | 8 | 扫描仪盖板已打开。 |
SANE_STATUS_IO_ERROR | 9 | 设备I / O期间出错。 |
SANE_STATUS_NO_MEM | 10 | 记不清。 |
SANE_STATUS_ACCESS_DENIED | 11 | 对资源的访问已被拒绝。 |
表1:状态码
每个SANE设备都由SANE_Device类型的结构表示 。下面给出了这种类型的C声明。
typedef struct { SANE_String_Const name; SANE_String_Const vendor; SANE_String_Const model; SANE_String_Const type; } SANE_Device;
该结构在成员名称中提供了扫描仪的唯一 名称。在调用sane_open()时应传递此唯一名称。此名称的格式完全取决于后端。唯一的限制是该名称在后端支持的所有设备中都是唯一的,并且该名称是合法的SANE文本字符串。为了简化唯一名称的表示,其长度不应过多。这是建议的是后端保持低于长度为32个字符的唯一名称。但是,应用程序 必须能够处理任意长度的唯一名称。
设备结构中的其余成员在设备上提供了与唯一名称相对应的其他信息。具体而言,成员vendor,model和type是单行字符串,用于提供有关卖方(制造商),型号和设备类型的信息。为了保持一致性,应在适当的时候使用以下字符串(列表将根据需要扩展):
供应商字符 Vendor Strings | |
AGFA | Microtek |
Abaton | Minolta |
Acer | Mitsubishi |
Apple | Mustek |
Artec | NEC |
Avision | Nikon |
CANON | Plustek |
Connectix | Polaroid |
Epson | Relisys |
Fujitsu | Ricoh |
Hewlett-Packard | Sharp |
IBM | Siemens |
Kodak | Tamarack |
Lexmark | UMAX |
Logitech | Noname |
Type Strings |
film scanner |
flatbed scanner |
frame grabber |
handheld scanner |
multi-function peripheral |
sheetfed scanner |
still camera |
video camera |
virtual device |
表2:预定义的设备信息字符串
请注意,供应商字符串Noname可以用于没有物理供应商关联的虚拟设备。而且,由于这些字符串是特定于供应商的,因此没有预定义的型号名称字符串,因此完全在各个后端的控制之下。
同时,选项描述符是SANE标准中最复杂,功能最强大的类型。选项用于控制设备操作的几乎所有方面。SANE API的强大功能主要是因为大多数设备控件均由其各自的选项描述符完全描述。因此,前端可以抽象地控制扫描仪,而无需了解任何给定选项的目的是什么。相反,扫描仪可以描述其控件,而无需了解前端的操作方式。SANE_Option_Descriptor的C声明 类型如下。
typedef struct { SANE_String_Const name; SANE_String_Const title; SANE_String_Const desc; SANE_Value_Type type; SANE_Unit unit; SANE_Int size; SANE_Int cap; SANE_Constraint_Type constraint_type; union { const SANE_String_Const *string_list; const SANE_Word *word_list; const SANE_Range *range; } constraint; } SANE_Option_Descriptor;
4.2.9.1选项名称
成员名称是唯一标识该选项的字符串。该名称对于给定的设备必须是唯一的(即,跨不同后端或设备的选项名称不必是唯一的)。选项名必须由小写字母ASCII(一 - Ž),数字(0 - 9)或连字符(- )只。第一个字符必须是小写的ASCII字符(即,不是数字或破折号)。
4.2.9.2选项标题
成员标题是单行字符串,前端可以将其用作标题字符串。通常应该是根据选项功能选择的短字符串(一个或两个单词)。
4.2.9.3选项说明
成员desc是一个(可能非常长)的字符串,可以用作描述该选项的帮助文本。前端负责将字符串分成可管理长度的行。此字符串中的换行符应解释为段落分隔符。
4.2.9.4选项值类型
成员类型指定选项值的类型。类型SANE_Value_Type的可能值在表3 中描述。
符号 | 码 | 描述 |
SANE_TYPE_BOOL |
0 | 选项值的类型为 SANE_Bool。 |
SANE_TYPE_INT |
1 | 选项值的类型为 SANE_Int。 |
SANE_TYPE_FIXED |
2 | 选项值的类型为 SANE_Fixed。 |
SANE_TYPE_STRING |
3 | 选项值的类型为 SANE_String。 |
SANE_TYPE_BUTTON |
4 | 此类型的选项没有价值。而是,设置此类型的选项会产生特定于选项的副作用。例如,后端可以使用按钮类型的选项来提供选择默认值的方法,或者告诉自动文档进纸器前进到下一页纸。 |
SANE_TYPE_GROUP |
5 | 此类型的选项没有价值。此类型用于对逻辑相关选项进行分组。一个组选项在遇到另一个组选项之前一直有效(或者,如果没有其他组选项,则一直到选项列表的末尾)。对于组选项,在选项描述符中仅成员标题和 类型有效。 |
|
表3:选项值类型(SANE_Value_Type)
4.2.9.5选项值单位
成员单位指定选项值的物理单位是什么。SANE_Unit类型的可能值在表4中进行了描述。请注意,指定的单位是SANE后端期望的单位。这些单元如何呈现给用户完全取决于前端。例如,SANE以毫米表示所有长度。通常期望前端提供适当的转换例程,以便用户可以用惯常单位(例如,英寸或厘米)表示数量。
符号 | 码 | 描述 |
SANE_UNIT_NONE |
0 | 值是无单位的(例如,页数)。 |
SANE_UNIT_PIXEL | 1 | 值以像素数为单位。 |
SANE_UNIT_BIT | 2 | 值以位数为单位。 |
SANE_UNIT_MM | 3 | 值以毫米为单位。 |
SANE_UNIT_DPI | 4 | 值是以点/英寸为单位的分辨率。 |
SANE_UNIT_PERCENT | 5 | 值是一个百分比。 |
SANE_UNIT_MICROSECOND | 6 | 值是以秒为单位的时间。 |
|
表4:物理单位(SANE_Unit)
4.2.9.6选项值大小
成员大小指定选项值的大小(以字节为单位)。根据选项值的类型,此成员的解释稍有不同:
SANE_TYPE_STRING:
大小是字符串的最大大小。为了计算字符串大小,将终止NUL字符视为字符串的一部分。请注意,终止NUL字符必须始终出现在字符串选项值中。
SANE_TYPE_INT,SANE_TYPE_FIXED:
该大小必须是SANE_Word大小的正整数倍 。选项值是长度的向量size / sizeof(SANE_Word)。
SANE_TYPE_BOOL:
大小必须设置为 sizeof(SANE_Word)。
SANE_TYPE_BUTTON,SANE_TYPE_GROUP:
选项大小被忽略。
4.2.9.7选项功能
成员上限描述了该选项具备的功能。这是一个位集,形成为表5中所述功能的包含性逻辑或。SANE API为宏提供了以下功能,以测试给定功能位集的某些功能:
SANE_OPTION_IS_ACTIVE (上限):
当且仅当具有功能设置 上限的选项当前处于活动状态时,此宏才返回SANE_TRUE。
SANE_OPTION_IS_SETTABLE (上限):
当且仅当具有功能设置上限的选项是可软件设置的,此宏才返回SANE_TRUE。
符号 | 码 | 描述 |
SANE_CAP_SOFT_SELECT |
1 | 可以通过调用sane_control_option()来设置选项值。 |
SANE_CAP_HARD_SELECT |
2 | 可以通过用户干预(例如,通过拨动开关)来设置选项值。用户界面应提示用户执行适当的操作以设置此类选项。此功能与SANE_CAP_SOFT_SELECT互斥(可以设置一个,但不能同时设置)。 |
SANE_CAP_SOFT_DETECT |
4 | 选项值可以通过软件检测。如果 设置了SANE_CAP_SOFT_SELECT,则必须 设置此功能。如果设置了SANE_CAP_HARD_SELECT,则可能会或可能不会设置此功能。如果设置了此功能,但是 SANE_CAP_SOFT_SELECT和SANE_CAP_HARD_SELECT 都没有,则无法控制该选项。也就是说,该选项仅提供当前值的读取。 |
SANE_CAP_EMULATED |
8 | 如果设置了此功能,则表明该设备不直接支持该选项,而是在后端进行仿真。复杂的前端可以选择使用自己的(可能更好)的仿真来代替仿真选项。 |
SANE_CAP_AUTOMATIC |
16 | 如果设置,此功能表示后端(或设备)能够自动选择合理的选项值。对于此类选项,可以通过 使用动作值SANE_ACTION_SET_AUTO调用sane_control_option()来选择自动操作。 |
SANE_CAP_INACTIVE |
32 | 如果设置了此功能,则表明该选项当前未激活(例如,因为仅当另一个选项设置为其他值时才有意义)。 |
SANE_CAP_ADVANCED |
64 | 如果设置了此功能,则表明该选项应被视为“高级用户选项”。前端通常以比常规选项不那么明显的方式显示此类选项(例如,命令行界面可能会在最后列出此类选项或以图形方式界面可能会使它们在单独的``高级设置''对话框中可用)。 |
|
表5:选件功能
4.2.9.8选项值限制
约束一个选项可以采用的值通常很有用。例如,前端可以使用约束来确定如何表示给定的选项。成员constraint_type指示该选项有效的约束条件。该选项允许的约束值由成员约束的并集成员之一描述。SANE_Constraint_Type类型的可能值 表6 描述了约束并集的解释 。
符号 | 码 | 描述 |
SANE_CONSTRAINT_NONE |
0 | 该值不受限制。该选项可以采用选项类型可能的任何值。 |
SANE_CONSTRAINT_RANGE |
1个 | 此约束仅适用于整数和定点值的期权。它将期权价值限制在可能量化的数字范围内。选项描述符成员constraint.range指向SANE_Range类型的范围。这种类型如下所示:
根据选项值类型(SANE_TYPE_INT或SANE_TYPE_FIXED)解释此结构中的所有三个成员。成员min和max分别指定最小值和最大值。如果成员quantit非零,则它指定量化值。如果l是最小值,u是最大值,q是范围的(非零)量化,那么对于k的所有非负整数值,合法值是v = k * q + 1,从而v <=你 |
SANE_CONSTRAINT_WORD_LIST |
2 | 此约束仅适用于整数和定点值的期权。它将选项值限制为数字值列表。选项描述符成员 constraint.word_list指向枚举合法值的单词列表。该列表中的第一个元素是一个整数(SANE_Int),它指定列表的长度(不计算长度本身)。列表中的其余元素根据选项值的类型(SANE_TYPE_INT或SANE_TYPE_FIXED)进行解释。 |
SANE_CONSTRAINT_STRING_LIST |
3 | 此约束仅适用于字符串值的选项。它将选项值限制为字符串列表。选项描述符成员 constraint.string_list指向以NULL结尾的字符串列表,这些列表枚举了选项值的合法值。 |
表6:选项值限制
必须先调用此函数,然后才能调用任何其他SANE函数。如果此功能未先叫或SANE后端的行为都是不确定如果返回的状态代码sane_init不同于 SANE_STATUS_GOOD。后端的版本代码以version_code指向的值返回。如果该指针为 NULL,则不返回任何版本代码。参数授权是指向后端要求对特定资源进行身份验证时调用的函数的指针,或者如果前端不支持身份验证则为NULL。
SANE_Status sane_init (SANE_Int * version_code, SANE_Authorization_Callback authorize)
后端可以响应以下任何调用来调用授权功能:
sane_open,sane_control_option,sane_start
如果后端在没有授权功能的情况下初始化,那么后端本身无法处理的授权请求将自动失败,并且可能会阻止用户访问受保护的资源。鼓励后端实施不需要用户协助的身份验证方法。例如,在通过登录过程验证用户身份的多用户系统上,后端可以根据资源和用户名自动查找适当的密码。
认证功能类型具有以下声明:
#define SANE_MAX_USERNAME_LEN 128 #define SANE_MAX_PASSWORD_LEN 128 typedef void (*SANE_Authorization_Callback) (SANE_String_Const resource, SANE_Char username[SANE_MAX_USERNAME_LEN], SANE_Char password[SANE_MAX_PASSWORD_LEN]);
三个参数传递给授权函数: resource是一个字符串,用于指定需要授权的资源的名称。前端应使用此字符串来构建一个要求用户名和密码的用户提示。的用户名 和密码参数是(指针)的阵列 SANE_MAX_USERNAME_LEN和SANE_MAX_PASSWORD_LEN 字符,分别。授权调用应将输入的用户名和密码放在这些数组中。返回的字符串 必须以ASCII-NUL终止。
必须调用此函数以终止使用后端。该函数将首先关闭所有可能仍处于打开状态的设备句柄(建议通过调用sane_close()显式关闭设备句柄,但要求后端在调用此函数时释放所有资源)。此函数返回后,不能调用sane_init()以外的任何函数(无论sane_exit()返回的状态值如何。忽略调用此函数可能会导致某些资源无法正确释放。
void sane_exit (void);
此功能可用于查询可用设备的列表。如果函数成功执行,它将 在* device_list中存储指向NULL终止数组的指针,该数组指向SANE_Device结构。保证返回的列表保持不变并有效,直到(a)对该函数的另一次调用或(b)对sane_exit()的调用。可以重复调用此功能以检测何时有新设备可用。如果参数local_only为true,则仅返回本地设备(直接连接到运行SANE的计算机的设备)。如果为假,则设备列表包括SANE库可访问的所有远程设备。
SANE_Status sane_get_devices(const SANE_Device *** device_list, SANE_Bool local_only);
如果没有足够的内存,此功能可能会因SANE_STATUS_NO_MEM而失败。
后端实施说明
SANE不需要在执行sane_open()调用之前调用此函数 。设备名称可以由用户明确指定,这将导致不必要且不希望先调用此功能。
此功能用于建立到特定设备的连接。要打开的设备的名称在参数name中传递 。如果调用成功完成,则在* h中返回设备的句柄。在特殊情况下,将零长度字符串指定为设备会请求打开第一个可用设备(如果有的话)。
SANE_Status sane_open (SANE_String_Const name, SANE_Handle * h);
此功能可能因以下状态代码之一而失败。
SANE_STATUS_DEVICE_BUSY:
设备当前正忙(其他人正在使用)。
SANE_STATUS_INVAL:
设备名称无效。
SANE_STATUS_IO_ERROR:
与设备通信时发生错误。
SANE_STATUS_NO_MEM:
可用的内存量不足。
SANE_STATUS_ACCESS_DENIED:
由于身份验证不充分或无效,因此无法访问设备。
此函数终止在参数h中传递的设备句柄与其表示的设备之间的关联。如果设备当前处于活动状态,则首先执行对sane_cancel()的调用。此函数返回后,不能再使用句柄h。
void sane_close (SANE_Handle h);
此函数用于访问选项描述符。该函数返回由句柄h表示的设备的选项号n的选项描述符。选项号0保证是有效的选项。它的值是一个整数,它指定可用于设备句柄h的选项数量(计数包括选项0)。如果n不是有效的选项索引,则该函数返回NULL。保证返回的选项描述符在关闭设备之前一直保持有效(并在返回的地址处)。
const SANE_Option_Descriptor * sane_get_option_descriptor(SANE_Handle h,SANE_Int n);
此功能用于设置或查询由句柄h表示的设备的选件编号n的当前值。选项a的控制方式由参数a指定 。该参数的可能值将在下面更详细地描述。该选项的值通过参数v传递 。它是指向保存选项值的内存的指针。v指向的内存区域必须足够大以容纳整个选项值(由相应选项描述符中的成员大小确定)。该规则的唯一例外是,在设置字符串选项的值时,参数v指向的字符串可能会更短,因为在遇到 字符串中的第一个NUL终止符时,后端将停止读取选项值。如果参数i不为NULL,则将设置* i的值以提供有关如何满足请求的详细信息。该参数的含义将在下面更详细地描述。
SANE_Status sane_control_option(SANE_Handle h,SANE_Int n, SANE_Action a,void* v, SANE_Int * i);
通过调用此函数影响选项的方式由参数a控制,参数a是SANE_Action类型的值 。可能的值及其含义在表7中描述。
符号 | 码 | 描述 |
SANE_ACTION_GET_VALUE |
0 | 获取当前的期权价值。 |
SANE_ACTION_SET_VALUE |
1个 | 设置选项值。如果无法精确设置通过参数v传递的选项值,则后端可能会对其进行修改。 |
SANE_ACTION_SET_AUTO |
2 | 打开自动模式。后端或设备将自动选择适当的值。此模式将保持有效,直到被显式设置值请求覆盖为止。在这种情况下,参数v的值将被完全忽略,并且可以为NULL。 |
|
表7:操作值(SANE_Action)
通过SANE_ACTION_SET_VALUE的操作值设置一个值后 ,在* i中返回有关如何满足请求的其他信息(如果i为非NULL)。返回的值是一个位集,可以包含表8中描述的值的任何组合。
符号 | 码 | 描述 |
SANE_INFO_INEXACT |
1个 | 当设置选项值导致选择的值与请求的值不完全匹配时,将返回此值。例如,如果扫描仪只能以30dpi的增量调整分辨率,则将分辨率设置为307dpi可能会导致实际设置为300dpi。发生这种情况时,* i中返回的位集具有此成员集。另外,修改了选项值以反映后端使用的实际(四舍五入)值。请注意,字符串也可以使用不精确的值。后端可以选择将字符串``舍入''到最接近的匹配合法字符串以获取受约束的字符串值。 |
SANE_INFO_RELOAD_OPTIONS |
2 | 选项的设置可能会影响一个或多个 其他选项的价值或可用性。发生这种情况时,SANE后端会在* i中设置此成员,以指示应用程序应重新加载所有选项。仅当更改了至少一个选项时,才能设置此成员。 |
SANE_INFO_RELOAD_PARAMS |
4 | 选项的设置可能会影响参数值(请参见sane_get_parameters())。如果设置选项影响参数值,则该成员将在* i中设置。请注意,即使参数没有实际更改,也可以设置该成员。但是,可以确保不设置此成员就不会更改参数。 |
|
表8:设置选项时返回的其他信息
此功能可能因以下状态代码之一而失败。
SANE_STATUS_UNSUPPORTED:
指定的句柄和选项号不支持该操作。
SANE_STATUS_INVAL:
选项值无效。
SANE_STATUS_IO_ERROR:
与设备通信时发生错误。
SANE_STATUS_NO_MEM:
可用的内存量不足。
SANE_STATUS_ACCESS_DENIED:
由于身份验证不充分或无效,因此无法访问该选件。
此功能用于获取当前的扫描参数。在开始扫描(调用sane_start())与完成请求之间,保证返回的参数是准确的。在该窗口之外,返回值是在调用sane_start()时参数将尽力而为的估计 。例如,在实际开始扫描之前调用此函数可以例如估算出扫描图像的大小。传递给此函数的参数是应为其获取参数的设备的句柄h,以及指向参数结构的指针p。参数结构在下面更详细地描述。
SANE_Status sane_get_parameters(SANE_Handle h, SANE_Parameters * p);
扫描参数以SANE_Parameters类型的结构返回 。下面给出了此结构的C声明。
typedef struct { SANE_Frame format; SANE_Bool last_frame; SANE_Int bytes_per_line; SANE_Int pixels_per_line; SANE_Int lines; SANE_Int depth; } SANE_Parameters;
成员格式指定要返回的下一帧的格式。SANE_Frame类型的可能值在表9中进行了描述。这些值的含义在3.2节中有更详细的描述。
符号 | 码 | 描述 |
SANE_FRAME_GRAY |
0 | 乐队覆盖了人类的视觉范围。 |
SANE_FRAME_RGB | 1 | 像素交错的红色/绿色/蓝色带。 |
SANE_FRAME_RED | 2 | 红色/绿色/蓝色图像的红色带。 |
SANE_FRAME_GREEN | 3 | 红色/绿色/蓝色图像的绿色带。 |
SANE_FRAME_BLUE | 4 | 红色/绿色/蓝色图像的蓝色带。 |
|
表9:帧格式(SANE_Frame)
当且仅当当前正在获取的帧(或者如果当前帧不存在时,下一个将要获取的帧)是多帧图像的最后一个帧(例如,当前帧是当前帧)时,成员last_frame设置为SANE_TRUE。红色,绿色,蓝色图像的蓝色成分)。
成员行指定框架包含多少条扫描线。如果此值为-1,则行数是先验未知的,并且前端应调用sane_read(),直到返回状态SANE_STATUS_EOF为止。
成员bytes_per_line指定组成一条扫描线的字节数。
成员深度指定每个样本的位数。
成员pixels_per_line指定组成一条扫描线的像素数。
假设B是帧中的通道数,则位深度d(由member depth给出)和每行像素数n(由此memberpixels_per_line给出)与c(每行字节数)相关(由成员bytes_per_line给出 )如下:
c> = \ left {ll B * \ lfloor(n + 7)/ 8 \ rfloor如果d = 1(1)B * n * d / 8如果d> 1 \ right。
请注意,每行的字节数可以大于此方程式右侧施加的最小值。前端必须能够正确处理此类``填充''图像格式。
此功能启动从手柄h表示的设备获取图像。
SANE_Status sane_start(SANE_Handle h);
此功能可能因以下状态代码之一而失败。
SANE_STATUS_CANCELLED:
通过调用sane_cancel取消了该操作。
SANE_STATUS_DEVICE_BUSY:
设备忙。该操作应稍后重试。
SANE_STATUS_JAMMED:
文档进纸器被卡住。
SANE_STATUS_NO_DOCS:
文件进纸器中没有文件。
SANE_STATUS_COVER_OPEN:
扫描仪盖板打开。
SANE_STATUS_IO_ERROR:
与设备通信时发生错误。
SANE_STATUS_NO_MEM:
可用的内存量不足。
SANE_STATUS_INVAL:
无法使用当前选项集开始扫描。前端应该重新加载选项描述符,就像 SANE_INFO_RELOAD_OPTIONS已从对sane_control_option()的调用返回 ,因为设备的功能可能已更改。
此功能用于从手柄h代表的设备中读取图像数据。参数buf是一个指向至少maxlen个字节长的存储区的指针。返回的字节数存储在* len中。当返回SANE_STATUS_GOOD以外的状态时,后端必须将此值设置为零。当调用成功,返回的字节的数目可以在从0到的范围内的任何地方的maxlen字节。
SANE_Status sane_read(SANE_Handle h,SANE_Byte * buf, SANE_Int maxlen,SANE_Int * len);
如果在没有可用数据时调用此函数,则可能发生两种情况之一,具体取决于对句柄h生效的I / O模式。
可以通过调用sane_set_io_mode()来设置 句柄h的I / O模式。
此功能可能因以下状态代码之一而失败。
SANE_STATUS_CANCELLED:
通过调用sane_cancel取消了该操作。
SANE_STATUS_EOF:
当前帧没有更多数据。
SANE_STATUS_JAMMED:
文档进纸器被卡住。
SANE_STATUS_NO_DOCS:
文件进纸器中没有文件。
SANE_STATUS_COVER_OPEN:
扫描仪盖板打开。
SANE_STATUS_IO_ERROR:
与设备通信时发生错误。
SANE_STATUS_NO_MEM:
可用的内存量不足。
SANE_STATUS_ACCESS_DENIED:
由于身份验证不充分或无效,因此无法访问设备。
此功能用于立即或尽快取消由句柄h表示的设备的当前挂起的操作 。
无效sane_cancel(SANE_Handle h);
可以随时调用此函数(只要句柄h是有效的句柄),但通常只影响长时间运行的操作(例如图像获取)。异步调用此函数是安全的(例如,从信号处理程序中)。重要的是要注意,此操作的完成并不意味着当前挂起的操作已被取消。它仅保证取消已启动。取消仅在取消的呼叫返回时完成(通常状态值为SANE_STATUS_CANCELLED)。由于SANE API不需要重新输入任何其他操作,因此这意味着前端一定不能 调用任何其他操作,直到返回已取消的操作。
此功能用于设置手柄h的I / O模式。I / O模式可以是阻塞或非阻塞。如果参数m为 SANE_TRUE,则将模式设置为非阻塞模式,否则将其设置为阻塞模式。仅在对sane_start()的调用完成后才能调用此函数 。
SANE_Status sane_set_io_mode(SANE_Handle h,SANE_Bool m);
默认情况下,新打开的句柄以阻止模式运行。后端可以选择不支持非阻塞I / O模式。在这种情况下,将返回状态值SANE_STATUS_UNSUPPORTED。所有后端都必须支持阻塞I / O,因此可以确保将参数m设置为SANE_FALSE调用此函数。
此功能可能因以下状态代码之一而失败:
SANE_STATUS_INVAL:
没有图像采集正在等待。
SANE_STATUS_UNSUPPORTED:
后端不支持请求的I / O模式。
此函数用于获取句柄h的(特定于平台的)文件描述符,当且仅当图像数据可用时(即,对sane_read()的调用将返回至少一个字节的数据),该文件描述符才可读。如果调用成功完成,则在* fd中返回选择文件描述符。
SANE_Status sane_get_select_fd(SANE_Handle h,SANE_Int * fd);
仅在执行对sane_start()的调用 并且已保证返回的文件描述符在当前图像获取期间保持有效(即,直到再次调用sane_cancel()或sane_start()或直到sane_read()返回状态 SANE_STATUS_EOF)。实际上,后端必须保证在下一个sane_read()调用返回SANE_STATUS_EOF时关闭返回的选择 文件描述符。这是确保应用程序可以检测到何时发生这种情况而不必实际调用sane_read()所必需的。
后端可以选择不支持此操作。在这种情况下,该函数将返回状态码 SANE_STATUS_UNSUPPORTED。
请注意,返回的文件描述符支持的唯一操作是与主机操作系统相关的测试,以确定文件描述符是否可读(例如,可以在UNIX下使用select() 或poll()来实现此测试)。如果对文件描述符执行任何其他操作,则后端的行为将变得不可预测。一旦文件描述符发出``可读''状态的信号,它将保持该状态,直到执行对sane_read()的调用为止。由于许多输入设备非常慢,因此强烈建议支持此操作,因为它允许应用程序在进行图像采集时执行其他工作。
此功能可能因以下状态代码之一而失败:
SANE_STATUS_INVAL:
没有图像采集正在等待。
SANE_STATUS_UNSUPPORTED:
后端不支持此操作。
此功能可用于将SANE状态代码转换为可打印的字符串。返回的字符串是形成完整句子的单行文本,但没有结尾句号(句号)。该函数保证永远不会返回NULL。返回的指针至少在下一次调用此函数之前是有效的。
const SANE_String_Const sane_strstatus(SANE_Status status);
SANE API的代码流如图4 所示。函数sane_init()和 sane_exit()分别初始化和退出后端。所有其他调用必须在初始化之后和退出后端之前执行。
图4:代码流
可以在调用sane_init()之后的任何时间调用 函数sane_get_devices()。它返回呼叫时已知的设备列表。由于某些设备可能已打开或关闭,或者远程主机可能在不同的呼叫之间启动或关闭,因此该列表可能会随时间变化。应当注意,此操作可能相对较慢,因为它需要联系所有已配置的设备(其中一些可能在远程主机上)。因此,前端可能希望为用户提供直接选择所需设备的功能,而无需调用此功能。
选择设备后,可通过调用sane_open()将其打开 。可以在任何给定时间打开多个设备。SANE后端不得在任何给定时间对可以打开多少个设备施加人为约束。
可以使用功能sane_get_option_descriptor()和 sane_control_option()通过相应的设备句柄设置打开的设备。设置设备时,可以自由地混合使用选项描述符以及设置和读取选项值。前端通常会在开始时读出所有可用选项,然后建立一个对话框(图形或命令行选项列表),以控制可用选项。应当注意,对于给定的句柄,选项的数量是固定的。但是,随着选项的设置,其他选项可能会变为活动或非活动状态。因此,在设置选项之后,可能需要重新读取一些或所有选项描述符。设置设备时,也可以拨打电话 sane_get_parameters()以获取图像获取开始后图像参数的估算值。
通过调用sane_set_io_mode()可以将设备句柄置于阻塞或非阻塞模式。要求设备支持阻止模式(这是默认模式),但是对于诸如UNIX之类的操作系统,强烈建议支持非阻止I / O。
正确设置设备后,可以通过调用sane_start()来启动图像获取。后端此时会计算出确切的图像参数。因此,将来对sane_get_parameters()的调用 将返回确切的值,而不是估计值。SANE API未指定是在这一点上还是在第一次调用sane_read()时开始物理图像获取。如果需要无阻塞的I / O和/或选择样式的接口,则前端可能会在此时尝试调用 sane_set_io_mode()和/或sane_get_select_fd()。如果后端不支持请求的操作,则这些功能中的任何一个都可能失败。
通过重复调用sane_read()来收集图像数据。最终,此函数将返回文件结束状态(SANE_STATUS_EOF)。这指示当前帧的结束。如果前端需要其他帧(例如,红色/绿色/蓝色图像或多个图像中的各个通道),则可以再次调用sane_start()。一旦获取了所有所需的帧,就必须调用函数sane_cancel()。也可以在任何其他时间调用此操作以取消挂起的操作。请注意,即使最后一次读取操作返回了SANE_STATUS_EOF,也必须调用sane_cancel()。
使用设备完成操作后,应通过调用sane_close()关闭句柄 。最后,在退出应用程序之前,必须调用函数sane_exit()。重要的是不要忘记调用此函数,否则可能会导致某些资源(例如临时文件或锁)无人认领。
尽管大多数后端选项都是完全自描述的,但在某些情况下,用户界面可能希望对某些选项进行特殊处理。例如,扫描区域通常由四个选项定义,这些选项指定区域的左上角和右下角。使用图形用户界面,迫使用户键入这四个数字将很繁琐。相反,大多数此类界面都希望向用户呈现扫描仪表面的预览(低分辨率扫描),并让用户通过将矩形拖动到所需位置来选择扫描区域。因此,SANE API指定了少数具有明确定义含义的选项名称。
选项号0的名称为空字符串。此选项的值的类型为SANE_TYPE_INT,它指定给定设备可用的选项总数(计数包括选项号0)。这意味着有两种计算可用选项数量的方法:前端可以循环从一个选项开始的所有选项编号,直到 sane_get_option_descriptor()返回NULL,或者前端可以直接读出选项编号0的值。
选项分辨率用于选择应获取图像的分辨率。此选项的类型为 SANE_TYPE_INT或SANE_TYPE_FIXED。单位是 SANE_UNIT_DPI(点/英寸)。
此选项不是强制性的,但是如果后端确实支持它,则它必须以与上述定义一致的方式来实现。
此选项不是强制性的,但是如果后端确实支持它,则它必须以与上述定义一致的方式来实现。
四个最重要的众所周知的选项是定义扫描区域的选项。扫描区域由指定左上角和右下角的两个点(x / y坐标对)定义。这在图5中示出。请注意,坐标系的原点位于传感器所看到的扫描表面的左上角(通常是用户看到的扫描表面的镜像)。因此,左上角是横坐标和纵坐标值同时最小的角,右下角是横坐标和纵坐标值近似最大的角。如果此坐标系对于给定的设备而言不是自然的,则后端的工作就是执行必要的转换。
图5:扫描区域选项
下表列出了定义扫描区域的四个选项的名称:
名称 | 描述 |
tl-x |
左上角x坐标值 |
tl-y |
左上y坐标值 |
br-x |
右下x坐标值 |
br-y |
右下y坐标值 |
关于这些选项,前端和后端应遵循几个规则:
SANE接口的设计,方便图像采集设备的网络接入。特别是,大多数SANE实施都有望支持网络后端(网络客户端)和相应的网络守护程序(网络服务器),该网络后台程序允许通过网络连接访问图像采集设备。网络访问在以下几种情况下很有用:
即使在本地情况下,通过网络守护程序控制访问也会很有用:例如,某些后端可能需要root特权才能访问设备。系统管理员可以将SANE网络守护程序安装为setuid-root,而不是将每个前端都安装为setuid-root。这使普通用户可以通过SANE守护程序访问特权设备(该守护程序可能比简单的setuid方法支持更细粒度的访问控制机制)。这具有额外的好处,即系统管理员只需要信任SANE守护程序,而不是可能需要访问特权设备的每个前端。
在设计本章中描述的网络协议时,要牢记以下目标:
SANE协议可以在任何提供可靠数据传输的传输协议上运行。尽管SANE没有指定特定的传输协议,但是可以预期TCP / IP将成为最常用的协议之一。
注:以上内容来自SANE官网、Google翻译、以及本人整理