How to make a small "scan server" using Raspberry Pi

Daniel Marschall, March 2020

In this small project we are going to make a small web-scan-server with Raspberry Pi. You will get an online interface where you can start scans. These scans will be placed in a directory and can be downloaded later, e.g. from another computer.

In this example I am using Raspberry Pi 4, and CanoScan LiDE 300. Attention: With Canon LiDE 300, you need an active powered USB HUB, since this scanner gets powered from USB! Please see here a list of supported devices of SANE.

Step 1:

Install prerequisites

aptitude install sane sane-utils libsane-extras xsane libjpeg-dev

Step 2:

Raspberry currently only has sane-backends-1.0.27, which is not compatible with CanoScan LiDE 300. Therefore you need to install sane-backends-1.0.29

        untargz sane-backends-1.0.29.tar.gz
        cd sane-backends-1.0.29
        make install

You need to prepend "LD_LIBRARY_PATH=/usr/local/lib" in front of your commands, e.g. verwenden anstelle "LD_LIBRARY_PATH=/usr/local/lib scanimage ..."

Step 3:

Check if the scanner is found:

"LD_LIBRARY_PATH=/usr/local/lib scanimage -L"

Step 4:

To scan using the web user www-data, you need to do following:

Step 4a:

Run "lsusb" and read the bus identifier, e.g. 001:049

Step 4b:

udevadm info --query=all --attribute-walk --name=/dev/bus/usb/001/049
now you can see attributes of the device.

Step 4c:

Create /etc/udev/rules.d/55-libsane.rules with following content:
SUBSYSTEM=="usb", ACTION=="add", ATTR{idVendor}=="04a9", SYMLINK+="scanner-%k", OWNER="root", GROU$
replace "04a9" with the vendor ID of your device.

Step 4d:

/etc/group: Add user "www-data" to the group "scanner"

Step 4e:

udevadm control --reload-rules

Step 4f:

Reconnect the scanner

Step 5:

Create directories:

	mkdir /....../htdocs/web_scanner
	mkdir /....../htdocs/web_scanner/scans
	chmod 0777 /....../htdocs/web_scanner/scans

Create /......./htdocs/web_scanner/index.html with following contents :


	<meta name=viewport content="width=device-width, initial-scale=1">

<body bgcolor="#11110C" text="#EBEBEB" link="#8C9D6A" vlink="#6C7D4A" alink="#CF694B">


<h2><a href="scan.php">Scan image</a></h2>

<h2><a href="scans/">View scanned images</a></h2>


Create /......./htdocs/web_scanner/scan.php :

for ($lfd=1; $lfd<99999; $lfd++) {
	$lfd = str_pad($lfd, 5, "0", STR_PAD_LEFT);
	$filename = "scan$lfd.jpg";

	if (!file_exists(__DIR__ . '/scans/' . $filename)) break;

exec("LD_LIBRARY_PATH=/usr/local/lib scanimage --format=jpeg --resolution=300dpi > ".dirname($_SERVER['SCRIPT_FILENAME'])."/scans/$filename", $out, $ec);

if ($ec != 0) {
	unlink(__DIR__ . '/scans/' . $filename);

if (!file_exists(__DIR__ . '/scans/' . $filename)) {
	echo '<h1>Scan failed!</h1>';
	echo '<h2><a href="./">Go back</a></h2>';
} else {


Have fun!