简单的Linux扫描仪应用:C语言实现

SANE (Scanner Access Now Easy)是Linux平台用于访问扫描仪的接口。这里分享下如何用C语言来编写一个最简单的扫描应用。

SANE下载

安装SANE:

sudo apt-get update
sudo apt-get install sane

下载源码

在Ubuntu和树莓派上扫描文档

准备工作

SANE工作流程

Linux SANE document scanning flowchart

代码实现

SANE初始化:

void init()
{
    SANE_Int version_code = 0;
    sane_init (&version_code, auth_callback);
    printf("SANE version code: %d\n", version_code);
}

查询所有连接设备。这里会比较耗时:

SANE_Status get_devices(const SANE_Device ***device_list)
{
    printf("Get all devices...\n");
    SANE_Status sane_status = 0;
    if (sane_status = sane_get_devices (device_list, SANE_FALSE))
    {
        printf("sane_get_devices status: %s\n", sane_strstatus(sane_status));
    }   
    return sane_status;
}

使用设备名字打开设备:

SANE_Status open_device(SANE_Device *device, SANE_Handle *sane_handle)
{
    SANE_Status sane_status = 0;
    printf("Name: %s, vendor: %s, model: %s, type: %s\n", device->name, device->model, device->vendor, device->type);
    if (sane_status = sane_open(device->name, sane_handle))
    {
        printf("sane_open status: %s\n", sane_strstatus(sane_status));
    }
 
    return sane_status;
}

扫描文档:

SANE_Status start_scan(SANE_Handle sane_handle, SANE_String_Const fileName)
{
    SANE_Status sane_status = 0;
    device = sane_handle;
    return do_scan(fileName);
}

扫描之后保存为pnm格式的文件。先写文件头:

static void write_pnm_header (SANE_Frame format, int width, int height, int depth, FILE *ofp)
{
    switch (format)
    {
        case SANE_FRAME_RED:
        case SANE_FRAME_GREEN:
        case SANE_FRAME_BLUE:
        case SANE_FRAME_RGB:
            fprintf (ofp, "P6\n# SANE data follows\n%d %d\n%d\n", width, height, (depth <= 8) ? 255 : 65535);
            break;
        default:
            if (depth == 1)
                fprintf (ofp, "P4\n# SANE data follows\n%d %d\n", width, height);
            else
                fprintf (ofp, "P5\n# SANE data follows\n%d %d\n%d\n", width, height,(depth <= 8) ? 255 : 65535);
            break;
    }
}

不断的读取数据写入到文件中:

while (1)
        {
            double progr;
            status = sane_read (device, buffer, buffer_size, &len);
            total_bytes += (SANE_Word) len;
            progr = ((total_bytes * 100.) / (double) hundred_percent);
            if (progr > 100.)
                progr = 100.;
 
            if (status != SANE_STATUS_GOOD)
            {
                if (status != SANE_STATUS_EOF)
                {
                    return status;
                }
                break;
            }
 
            if ((parm.depth != 16)) 
                    fwrite (buffer, 1, len, ofp);
                else
                {
#if !defined(WORDS_BIGENDIAN)
                    int i, start = 0;
                    /* check if we have saved one byte from the last sane_read */
                    if (hang_over > -1)
                    {
                        if (len > 0)
                        {
                            fwrite (buffer, 1, 1, ofp);
                            buffer[0] = (SANE_Byte) hang_over;
                            hang_over = -1;
                            start = 1;
                        }
                    }
                    /* now do the byte-swapping */
                    for (i = start; i < (len - 1); i += 2)
                    {
                        unsigned char LSB;
                        LSB = buffer[i];
                        buffer[i] = buffer[i + 1];
                        buffer[i + 1] = LSB;
                    }
                    /* check if we have an odd number of bytes */
                    if (((len - start) % 2) != 0)
                    {
                        hang_over = buffer[len - 1];
                        len--;
                    }
#endif
                    fwrite (buffer, 1, len, ofp);
                }

关闭设备:

void close_device(SANE_Handle sane_handle)
{
    sane_close(sane_handle);
}

释放所有资源:

void exit()
{
    sane_exit();
}

编译工程

Ubuntu上生成SANE动态链接库的符号链接:

sudo ln –s /usr/lib/x86_64-linux-gnu/libsane.so.1 /usr/lib/libsane.so

树莓派上:

sudo ln –s /usr/lib/arm-linux-gnueabihf/libsane.so.1 /usr/lib/libsane.so

makefile中修改头文件路径:

SANE_INCLUDE=<Your SANE Package Path>/include

编译工程:

make

执行程序:

sudo ./hellosane

最后用GIMP打开pnm文件。

源码

https://github.com/yushulx/linux-document-scanning

 

转载于:https://my.oschina.net/yushulx/blog/779207

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值