簡單的Linux掃描儀應用:C語言實現

SANE (Scanner Access Now Easy)是Linux平臺用於訪問掃描儀的接口。這裏分享下如何用C語言來編寫一個最簡單的掃描應用。html

SANE下載

安裝SANE:linux

sudo apt-get update
sudo apt-get install sane

下載源碼git

在Ubuntu和樹莓派上掃描文檔

準備工做

SANE工做流程

Linux SANE document scanning flowchart

代碼實現

SANE初始化:github

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

查詢全部鏈接設備。這裏會比較耗時:bash

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;
}

使用設備名字打開設備:app

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格式的文件。先寫文件頭:spa

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;
    }
}

不斷的讀取數據寫入到文件中:code

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);
                }

關閉設備:orm

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

相關文章
相關標籤/搜索