Documentation
¶
Overview ¶
Package airscan can be used to scan paper documents from a scanner via the network, using the Apple AirScan (eSCL) protocol.
Index ¶
Examples ¶
Constants ¶
const ServiceName = "_uscan._tcp.local."
ServiceName is the AirScan DNSSD service name.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Client ¶
type Client struct {
// HTTPClient is used for all requests made by this Client and can be
// overridden for testing or to integrate custom behavior. The default
// amounts to http.DefaultClient.
HTTPClient interface {
Do(*http.Request) (*http.Response, error)
}
// contains filtered or unexported fields
}
A Client allows scanning documents via AirScan, which is also known as eSCL.
func NewClient ¶
NewClient returns a ready-to-use Client. It is safe to update its struct fields before first using the returned Client.
When using DNSSD service discovery to locate the scanner (the most common choice), prefer NewClientForService instead.
func NewClientForService ¶
func NewClientForService(service *dnssd.BrowseEntry) *Client
NewClientForService is like NewClient, but constructs a net.Dialer that attempts to connect to the specified DNSSD service using its host or IP address(es) directly, gracefully falling back between connection methods.
This maximizes the chance of a successful connection, even when local networks do not offer DHCP-based DNS, and when Avahi is not available.
func (*Client) Scan ¶
func (c *Client) Scan(settings *ScanSettings) (*ScanState, error)
Scan starts a new scan job using the specified settings.
When scanning from an Automatic Document Feeder (ADF), the Scan method verifies a document is inserted before creating a scan job (which would otherwise fail with a less clear error message).
Example ¶
package main
import (
"io"
"github.com/brutella/dnssd"
"github.com/stapelberg/airscan"
"github.com/stapelberg/airscan/preset"
)
var discoveredService *dnssd.BrowseEntry
func main() {
// For a full example using DNSSD service discovery, see:
// https://github.com/stapelberg/airscan/blob/master/cmd/airscan1/airscan1.go
cl := airscan.NewClientForService(discoveredService)
// Set up scan job:
grayscaleA4Platen := preset.GrayscaleA4ADF()
grayscaleA4Platen.InputSource = "Platen"
job, err := cl.Scan(grayscaleA4Platen)
if err != nil {
panic(err)
}
defer job.Close()
// Scan one individual page at a time:
for job.ScanPage() {
// Read and discard scan data. This is where you would typically save
// the data to a file, send it via the net, display or process it, etc.:
if _, err := io.Copy(io.Discard, job.CurrentPage()); err != nil {
panic(err)
}
}
if err := job.Err(); err != nil {
panic(err)
}
// Scan succeeded!
}
func (*Client) ScannerCapabilities ¶
func (*Client) ScannerStatus ¶
func (c *Client) ScannerStatus() (*ScannerStatus, error)
ScannerStatus queries the device for its status. This can be used for example to find out whether a document has been inserted into the Automatic Document Feeder (ADF). The Scan method verifies this, too.
type ScanRegion ¶
type ScanRegions ¶
type ScanRegions struct {
MustHonor bool `xml:"pwg:MustHonor,attr"`
Regions []*ScanRegion
}
type ScanSettings ¶
type ScanSettings struct {
XMLName xml.Name `xml:"scan:ScanSettings"`
XmlnsScan string `xml:"xmlns:scan,attr"`
XmlnsPWG string `xml:"xmlns:pwg,attr"`
Version string `xml:"pwg:Version"`
ScanRegions ScanRegions `xml:"pwg:ScanRegions"`
DocumentFormat string `xml:"pwg:DocumentFormat"`
InputSource string `xml:"pwg:InputSource"`
ColorMode string `xml:"scan:ColorMode"`
XResolution int `xml:"scan:XResolution"`
YResolution int `xml:"scan:YResolution"`
Duplex bool `xml:"scan:Duplex"`
}
ScanSettings instruct the device how to scan.
It is recommended to use the https://pkg.go.dev/github.com/stapelberg/airscan/preset package to start with a known-good configuration.
func (*ScanSettings) Marshal ¶
func (s *ScanSettings) Marshal() (string, error)
type ScanState ¶
type ScanState struct {
// contains filtered or unexported fields
}
ScanState represents an in-progress scan job.
func (*ScanState) Close ¶
Close deletes the scan job on the device.
Some devices work just fine if you never call Close. To maximize compatibility, it is recommended to call Close. This mirrors what Apple’s scan program does, which might be required for certain scanners (speculation only).
func (*ScanState) CurrentPage ¶
CurrentPage returns an io.Reader containing the scan data.
CurrentPage must only be called after ScanPage() returned true, and will return nil otherwise.
Note: package airscan never interprets scan data, the package only provides the data as-is. If you want to decode scan data, you will need to import e.g. image/jpeg (depending on scan settings) yourself.
func (*ScanState) Err ¶
Err returns the first error that occurred. If it returns non-nil, the ScanState must no longer be used, except for the Close method.
func (*ScanState) ScanPage ¶
ScanPage requests the next page of this scan job. It returns true if a new page is available, or false when all pages were exhausted or an error occurred. Errors are available via the Err() method.
Note that some scanners return 503 for NextDocument but will eventually return an accurate code when given more chances. See also https://github.com/alexpevzner/sane-airscan-ipp/blob/master/airscan-escl.c#L11.
type ScannerStatus ¶
Directories
¶
| Path | Synopsis |
|---|---|
|
cmd
|
|
|
airscan1
command
Program airscan1 is a utility program that scans documents from one AirScan-compatible scanner at a time.
|
Program airscan1 is a utility program that scans documents from one AirScan-compatible scanner at a time. |
|
Package preset contains settings that have been verified to match, character-by-character, the requests that Apple’s AirScanScanner library produces.
|
Package preset contains settings that have been verified to match, character-by-character, the requests that Apple’s AirScanScanner library produces. |