SANE (Scanner Access Now Easy)是Linux平臺用於訪問掃描儀的接口。這裏分享下如何用C語言來編寫一個最簡單的掃描應用。html
安裝SANE:linux
sudo apt-get update sudo apt-get install sane
下載源碼。git
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文件。