I scan pretty much everything — bills, old photos, mortgage documents, tax stuff, etc. It can be tedious, but it makes finding things much easier when you need to remember whether you filed in 83(b) election in 2006 or what exactly the previous owners disclosed about the condition of the roof.
Having a good scanner with a document feeder helps a lot, but the standard scanning UI in Mac OS X isn’t exactly efficient for quickly scanning a whole bunch of stuff into labeled directories. What I really wanted was a way that I could just type out something quickly on the command line to control the scanner, but I couldn’t find anything out there. So I wrote scanline, which I’m now making available as an MIT-licensed open source project.
Using scanline
The basic way to use scanline is to just invoke it on the command line with no arguments (or hit up-arrow if you just scanned something previously):
airica:~ klep$ scanline
This will scan the current document(s) in the document feeder of the default scanner into ~/Documents/Archive/[year]/scan_[hms].pdf
But there’s a whole lot more you can do. scanline uses directories as labels, so if the document you’re scanning is your auto registration, you can specify that scanline should put it in the “car” directory:
airica:~ klep$ scanline car
This puts the document into ~/Documents/Archive/car/[year]/scan_[hms].pdf
If you also want your registration to show up in your directory for taxes (so you remember to deduct the VLF), you can specify multiple labels:
airica:~ klep$ scanline car taxes
This creates an alias of the scanned document in ~/Documents/Archive/taxes/[year]/scan_[hms].pdf in addition to the original in the car directory.
If it’s a double-sided document (and your scanner supports it), use -duplex to scan both sides:
airica:~ klep$ scanline -duplex car taxes
Want to scan from the flatbed scanner instead of the document feeder?
airica:~ klep$ scanline -flatbed
Want to scan into a different root directory instead of ~/Documents/Archive?
airica:~ klep$ scanline -dir ~/Desktop
Here’s a good one — got lots of items to scan on the flatbed but want them all put together into a single PDF?
airica:~ klep$ scanline -batch -flatbed
Want to name the document something that isn’t generic?
airica:~ klep$ scanline -flatbed -name registration car
The above command will scan the item on the flatbed into ~/Documents/Archive/car/[year]/registration.pdf
If you have multiple scanners connected to your computer, you can select them by name:
airica:~ klep$ scanline -scanner "Epson 565655"
If you’re not sure what scanners are available, list them:
airica:~ klep$ scanline -list
Obtaining scanline
If you’d like to build scanline from source, enhance it, or tweak it for your needs, get it from:
https://github.com/klep/scanline
If you just want the binary (it’s a debug build but plenty fast and stable for real use), you can download it here.
How It Works
scanline was created using the ImageCaptureCore framework. It uses Lumberjack for logging and XCTest/OCMock for unit tests. It’s my first Mac app in quite some time, so go easy on me if you look at the source.
Dainius
Amazing app! Just what I was looking for. However, is there any way to control the resolution of the scan? I.e. “scan max dpi” or somesuch? Keep up the great work!
-D
klep
Thanks, Dainius. That’s on my short list of things to add. The only tricky part is that supported resolutions vary based on the device. So I could add something like -resolution X, but there’s no guarantee that your device supports X. Not a big problem, but just makes it a little more complicated.
klep
Just added a -minResolution option (also -res or -resolution will work). You can re-download the new binary or build from github. Enjoy!
Markus
This tool is great. It’s exactly the same resolution as with the GUI. I hope you keep adding new functions like color modes and support for TIFF files in the future.
Derick
Hi,
Sorry for the obvious question, but how do run this? command not found if I try your command in terminal and dropping your binary download onto Terminal brings up ‘Permission denied’.
But it sounds like exactly what I’ve been looking for
klep
Depends where you downloaded it to. It’s probably:
$ ~/Downloads/scanline
Derick
Thanks for the reply –
at first I had permission issues. took care of that, then I had ‘scanner not found’ message (due to scanner not supported in Mavericks) – again taken cared of: just finally got Mavericks to recognize the scanner again (and not just through VueScan). So I no longer get the ‘scanner not found’ message – though now when I try to run scanline it just hangs with no message but also no scanning either. Do you happen to know what I might be doing wrong?
Hein Bollo
Command line parameters for black/white scan would be perfect.
klep
Thanks for the suggestion! I just updated it with a -mono option to scan in monochrome. You can also use -bw.
klep
Not sure — try “scanline -verbose” and let me know if it outputs anything…
Hein Bollo
Thanks for adding the mono option! I just found one bug.If I scan documents with A4 size the scanned document is missing content at the bottom.
I think scanline uses the letter format?
A4 should have:
210 mm × 297 mm
While Letter has:
216mm × 279mm
So another option for the document scan size would be perfect!
Hein Bollo
Fixed my problem by adding the following to AppController.m after line 543(dfu.duplexScanningEnabled = [configuration isDuplex];):
dfu.documentType=ICScannerDocumentTypeA4;
But I don’t have enough Obj-C knowledge to make this configurable by a command line option.
Chris
Hi klep. I am having a similar issue to Derick in that scanline just hangs until I control-c it. When I run “scanline -verbose” I get the following output:
2014-10-18 08:00:49:271 scanline[443:513] setting functional unit
2014-10-18 08:00:49:271 scanline[443:513] current functional unit: 0
2014-10-18 08:00:49:271 scanline[443:513] doc feeder is 3
2014-10-18 08:00:49:271 scanline[443:513] flatbed is 0
2014-10-18 08:00:49:271 scanline[443:513] selected functionalUnitType: 0
2014-10-18 08:00:49:271 scanline[443:513] error: Error Domain=com.apple.ImageCaptureCore Code=-9922 “The operation couldn’t be completed. (com.apple.ImageCaptureCore error -9922.)”
This output repeated endlessly until I hit control-c. Your scanline tool sounds exactly like what I have been searching for and I’d love to use it. Any chance you can look at this error and fix? Thanks!
Chris
I should have added that I am using OS X Yosemite 10.10. Cheers.
Chris
Apologies – it works fine! I just needed to run it with the -flatbed argument. Great tool, thanks!
michael
Hi, Great idea with your tool. I’m trying to get it to work with my Brother MFC-8710DW. This is what I get so far. The tool detects my scanner when using the using the -list option. Nothing happens when I try to scan. Regardless if regular or with the flatbed option. When I try verbose it keeps looping an generating the same error that Chris reported.
Mine is the following error:
014-12-11 14:25:45:858 scanline[5798:507] setting functional unit
2014-12-11 14:25:45:858 scanline[5798:507] current functional unit: 0
2014-12-11 14:25:45:858 scanline[5798:507] doc feeder is 3
2014-12-11 14:25:45:858 scanline[5798:507] flatbed is 0
2014-12-11 14:25:45:858 scanline[5798:507] selected functionalUnitType: 0
2014-12-11 14:25:45:858 scanline[5798:507] error: Error Domain=com.apple.ImageCaptureCore Code=-9922 “The operation couldn’t be completed. (com.apple.ImageCaptureCore error -9922.)”
Any idea? I would appreciate if you could point me to the right information to get your tool working. Thanks.
Michael
klep
Hi Michael — That error tends to show up (repeatedly) when the scanner is warming up. But that shouldn’t take more than a few seconds. Are you able to scan using Preview.app?
Tom
This is not working for me. I try using the command and I get No such file or directory.
I know where it is even when I specify the path directly it does not work.
klep
You may need to set it to be executable:
% chmod a+x ./scanline
% ./scanline
Tom
Thanks so much. That got it working. If I could set DPI and feed a specified file name I can drop this right into daily use. Is there a way to do those things?
Tom
Caught the comment on resolution. What about filename? I suppose there is a way to get the file name in a round about way and then rename it.
Andreas K. Auen
Hey, I love this! It works perfectly on my computer with my scanner. However at my parents house, with Mavericks and a Canon MF8580CDW set up over network, I only get this output in verbose:
2015-03-03 20:08:52:775 scanline[33379:507] Looking for available scanners…
2015-03-03 20:08:52:811 scanline[33379:507] Found scanner: Canon MF8500C Series
2015-03-03 20:08:52:811 scanline[33379:507] All devices have been added.
The scanner works good with Preview.
Any ideas are very welcome!
Andreas
klep
Hmm… Not sure. I didn’t have any problems on Mavericks. Have you tried restarting the scanner and the Mac?
klep
You can set the filename with -name. For example:
./scanline -name phone_bill -dir ~/Desktop
Tom
Thank you. The naming works.
I am having trouble with OSX accessing the file right after it is created. I can navigate to the file in the Finder and see it but terminal cannot see it and the app I need to import the PDF into cannot see it either. If I view the file in Finder and click the file name and then the open folder space the terminal and the app can see it after that.
Is there something I need to do to solidify the new file in the index?
Tom
Page size was mentioned before, but I did not see a response. Can I set the page dimensions?
Tom
I also noticed when using the actual scan utility the B&W setting gives a grayscale PDF about 30% larger in file size and also a bit clearer for the given DPI. The info on both shows the same encoding.
Trevor W
Hello, When I run this program I am getting the follwoing Output:
2015-03-20 12:33:31:730 scanline[556:513] Starting scan…
2015-03-20 12:33:32:255 scanline[556:513] No document was scanned.
2015-03-20 12:33:32.256 scanline[556:79750] *** Terminating app due to uncaught exception ‘NSInvalidArgumentException’, reason: ‘*** -[NSFileManager copyItemAtURL:toURL:error:]: source URL is nil’
*** First throw call stack:
(
0 CoreFoundation 0x00007fff945f566c __exceptionPreprocess + 172
1 libobjc.A.dylib 0x00007fff89bd276e objc_exception_throw + 43
2 CoreFoundation 0x00007fff945f551d +[NSException raise:format:] + 205
3 Foundation 0x00007fff8d2672cf -[NSFileManager copyItemAtURL:toURL:error:] + 113
4 scanline 0x000000010002065f -[AppController outputAndTagFile:] + 3311
5 scanline 0x000000010001f8b3 -[AppController scannerDevice:didCompleteScanWithError:] + 1331
6 ImageCaptureCore 0x00007fff8a6fffd5 -[ICScannerDevice handleCommandCompletion:] + 5612
7 ImageCaptureCore 0x00007fff8a6cd2cb -[ICCommandCenter handleCompletionEvent:replyEvent:] + 341
8 ImageCaptureCore 0x00007fff8a6cde8b -[ICCommandCenter handleMachMessage:] + 342
9 Foundation 0x00007fff8d1d5ce1 __NSFireMachPort + 94
10 CoreFoundation 0x00007fff94513a2d __CFMachPortPerform + 285
11 CoreFoundation 0x00007fff945138f9 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 41
12 CoreFoundation 0x00007fff9451386b __CFRunLoopDoSource1 + 475
13 CoreFoundation 0x00007fff945053e7 __CFRunLoopRun + 2375
14 CoreFoundation 0x00007fff94504858 CFRunLoopRunSpecific + 296
15 CoreFoundation 0x00007fff945baef1 CFRunLoopRun + 97
16 scanline 0x0000000100015735 main + 165
17 scanline 0x0000000100001844 start + 52
)
libc++abi.dylib: terminating with uncaught exception of type NSException
Abort trap: 6
Any Help? Am I missing a library or something?
klep
Does it show any scanners if you do “scanline -list”?
Tom
@Trevor
Are you properly specifying the flatbed or doc feeder? I get something similar when there is no document in the feeder when it is run.
Tom
This has been a great utility. Will you ever add support for paper size? Do you take donations?
Jason WU
I am using Mac OS X 10.10 with the scanner EPSON Perfection V37/V370
the command line is like
scanline -flatbed -scanner “EPSON Perfection V37/V370” -verbose
The scanner did the scan action. But I got the same error as @Trevor. And finally get nothing. Any idea about it?
thanks
klep
@Jason – Does anything seem to happen on the scanner side? What if you specify -flatbed?
@Tom – Thanks for your comments! Sorry I didn’t see them earlier. No donations necessary. I’ll add paper size support to the feature list. Be sure to watch the project on GitHub:
https://github.com/klep/scanline
Art Westin
Seems scanline can only be run as admin. Is this true and intended?
klep
Should be able to run as any user. Might need to “chmod a+x scanline” first
Art Westin
Thanks for your quick reply.
This is the error (repeated 5 times) when I run as regular user:
$ ./scanline -list
2015-08-04 06:35:08:921 scanline[86042:513] Available scanners:
2015-08-04 06:35:08.934 scanline[86042:4877560] ERROR: [ICCommandCenter launchAgent] – Failed to launch agent[1], status: -10810, url: ‘file:///System/Library/Image%20Capture/Support/Image%20Capture%20Extension.app/’
2015-08-04 06:35:08.934 scanline[86042:4877560]
***** Failed to launch Image Capture Extension.
…
2015-08-04 06:35:28:956 scanline[86042:513] No scanners found.
$
scanline sits on the Desktop (not in /Applications) for the admin and regular user, and has the same chmods. It doesn’t matter who owns it, or if it’s setuid.
-r-xr-xr-x 1 user1 staff 329020 Aug 4 06:34 scanline
-r-xr-xr-x 1 admin wheel 329020 Jul 2 06:00 scanline
What do you think?
Conor
Thank you for this! It makes scanning wicked easy! Is there any documentation that lists its full range of options other than this blog?
I also wonder whether there is a way to scan as text, as opposed to an image? What kind of additional code would that require?
klep
Thanks for the kind words, Conor. I’m working on an update that will include help, and I’m also considering using the GitHub page as the central repository for downloading and using the app.
In terms of text, looks like there are some open source OCR libraries out there that I could use. Would be handy to maybe store the text alongside the images, so you could easily find the document you wanted then look at the original…
klep
Unfortunately, that’s a fairly generic error, so I’m not sure what’s going on. I assume a restart didn’t help? Based on your earlier question, perhaps this app (/System/Library/Image Capture/Support/Image Capture Extension.app) somehow has permissions that don’t allow normal users to start scanning?
Art Westin
Well I got it to work but I’m not exactly sure how. I did add the _lpadmin group to my user, but I don’t think that was it. When it failed, I trying running the UI app Image Capture and Quit gracefully. That often reset it so scanline could access the device again.
If I get any better insight, I’ll let you know.
Thanks for your active support.
Art Westin
More data:
Something changed in El Capitan. Now in order to run scanline, you have to be logged into the user’s GUI. This causes HPScanner to run in the background. Without that, scanline cannot find the scanner and fails.
So the questions are:
– Why did this change?
– Can HPScanner be run manually to support the command line invocation of scanline? With what arguments?
victor magiros
is there a way to choose a scanner by ip address or device address instead of name because my scanners are only giving out the default names for some reason and when i -list i get a list of all the names of the printers but when i try to scan from one it cannot find the scanner then when i -list again the name has changed to the default
here is the terminal exert
VictorIT:~ victor$ /Users/victor/Desktop/scanline -list
2015-11-18 11:36:31:312 scanline[11805:50f] Available scanners:
2015-11-18 11:36:31:633 scanline[11805:50f] * HP425dn-Loren
VictorIT:~ victor$ /Users/victor/Desktop/scanline -scanner “HP425dn-Loren”
2015-11-18 11:36:42:166 scanline[11818:50f] Starting scan…
2015-11-18 11:36:42:166 scanline[11818:50f] Unable to find scanner named “HP425dn-Loren”
VictorIT:~ victor$ /Users/victor/Desktop/scanline -list
2015-11-18 11:36:44:716 scanline[11834:50f] Available scanners:
2015-11-18 11:36:44:778 scanline[11834:50f] * HP LaserJet 400 MFP M425dn
VictorIT:~ victor$
Brian White
I am getting this too.
I have a “Samsung CLX-3170 Series”
Brians-Air:tsu bkw$ ./scanline -list
2016-01-06 02:35:56:245 scanline[17622:50f] Available scanners:
2016-01-06 02:35:56:290 scanline[17622:50f] * Samsung CLX-3170 Series
So I try:
Brians-Air:tsu bkw$ ./scanline -scanner “Samsung CLX-3170 Series” -verbose -letter -mono -resolution 200 -dir . aljex_tsu_0000
And I get:
2016-01-06 02:35:08:453 scanline[17603:50f] setting functional unit
2016-01-06 02:35:08:453 scanline[17603:50f] current functional unit: 0
2016-01-06 02:35:08:453 scanline[17603:50f] doc feeder is 3
2016-01-06 02:35:08:453 scanline[17603:50f] flatbed is 0
2016-01-06 02:35:08:453 scanline[17603:50f] selected functionalUnitType: 0
2016-01-06 02:35:08:454 scanline[17603:50f] error: Error Domain=com.apple.ImageCaptureCore Code=-9922 “(null)”
2016-01-06 02:35:08:454 scanline[17603:50f] setting functional unit
2016-01-06 02:35:08:454 scanline[17603:50f] current functional unit: 0
2016-01-06 02:35:08:454 scanline[17603:50f] doc feeder is 3
2016-01-06 02:35:08:454 scanline[17603:50f] flatbed is 0
2016-01-06 02:35:08:454 scanline[17603:50f] selected functionalUnitType: 0
2016-01-06 02:35:08:454 scanline[17603:50f] error: Error Domain=com.apple.ImageCaptureCore Code=-9922 “(null)”
2016-01-06 02:35:08:454 scanline[17603:50f] setting functional unit
2016-01-06 02:35:08:454 scanline[17603:50f] current functional unit: 0
2016-01-06 02:35:08:454 scanline[17603:50f] doc feeder is 3
2016-01-06 02:35:08:455 scanline[17603:50f] flatbed is 0
2016-01-06 02:35:08:455 scanline[17603:50f] selected functionalUnitType: 0
2016-01-06 02:35:08:455 scanline[17603:50f] error: Error Domain=com.apple.ImageCaptureCore Code=-9922 “(null)”
^C
The scanner has a sheet feeder and there is paper in the sheet feeder, and the scanner works from System Preferences…>Scanner & Printers>Scan>Open Scanner and then select all the same options. Document feeder, 200dpi, letter, mono (called “Text”).
Without even physically touching the scanner or the sheets that were in the feeder, just ^c scanline and try the system prefs util, and it scanned both sheets.
I’m on El Capitan
Brian White
Never mind, it’s working fine. 🙂
I think I just didn’t wait long enough for a one-time initial warm-up or something. But today the same scanner, connected the same way (lan, not usb), with the same scanline commandline options, and even the same papers in the feeder, is working fine.
Michel
This is exactly what we needed, but we do have one question, of course .. 🙂
We will call an AppleScript from within FileMaker. It will start scanning multiple pages into one pdf. Therefor we will use -batch. In the Terminal this works as we press enter for each new page. But we can’t do that in our flow. Isn’t there a possibility to keep this going until the last page, without the need for interaction with the user?
klep
Hi. The -batch option is only relevant if you’re scanning on the flatbed. If you have a stack of documents in the feeder, omit -batch and it will scan them all into a single PDF. If you don’t have a document feeder, and aren’t able to press RETURN on the command line, I could potentially have a -delay option that waits for you to change each page. Seems a little risky though — I wouldn’t want your scanner to fire up when you’re looking right at it.
dainius
Almost two years later, I’m still a proud scanline user 🙂 Another feature suggestion: manual duplex scanning (from tray).
Essentially, this would merge two batch scans: the first scan, odd numbers, would have the second scan, even numbers, placed appropriately between pages.
This would save all of us doing tray-scans the trouble of exporting to individual images, doing a batch rename, and then recombining the scans.
Thanks!
-Dainius
Gunnar
Error Domain=com.apple.ImageCaptureCore Code=-9922 “The operation couldn’t be completed. (com.apple.ImageCaptureCore error -9922.)”
This error is also solved by adding -flatbed (Scanner is an combined printer/scanner by brother). The message is in verbose mode looping until the scanner gets ready. Without -flatbed the Message ist looping infenite. (And therefore scanline uses up to 100% CPU until closing the terminal window.)
-> May this could be improved by an resonable timeout and automate quit of scanline?
Thanks for providing your app anyway!
-Gunnar
klep
Thanks for the note. Not sure when I’ll have time, but will try to fix it. I believe there is a timeout in there, but verbose mode might be triggering the CPU usage before it gets a chance to stop.
Gunnar
Hi Klep,
is it possible (for you) to add a functionality which adds the scan as a new last page to an existing .pdf file.
Like:
scanline -dir ~/Desktop -name “ExistingScan” -add
Special would be:
-addLast
-addFirst
This would be great, cause the -batch function is not working when the script is called by another script as there interaction of the user is needed.
Best, Gunnar