-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
d68d02d
commit 3065788
Showing
9 changed files
with
342 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
GoZBar | ||
--- | ||
ZBar bindings for golang. Only scanner supported. | ||
|
||
Read the ZBar documentations for explanations on constants and arguments. | ||
|
||
The ZBar library must be installed for this to compile. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
// Package gozbar config bindings for golang. | ||
// Read the ZBar documents for details | ||
package gozbar | ||
|
||
// #cgo LDFLAGS: -lzbar | ||
// #include <zbar.h> | ||
import "C" | ||
|
||
// Symbol types (Scanner.SetConfig() argument symbology) | ||
const ( | ||
NONE = C.ZBAR_NONE | ||
PARTIAL = C.ZBAR_PARTIAL | ||
EAN8 = C.ZBAR_EAN8 | ||
UPCE = C.ZBAR_UPCE | ||
ISBN10 = C.ZBAR_ISBN10 | ||
UPCA = C.ZBAR_UPCA | ||
EAN13 = C.ZBAR_EAN13 | ||
ISBN13 = C.ZBAR_ISBN13 | ||
I25 = C.ZBAR_I25 | ||
CODE39 = C.ZBAR_CODE39 | ||
PDF417 = C.ZBAR_PDF417 | ||
QRCODE = C.ZBAR_QRCODE | ||
CODE128 = C.ZBAR_CODE128 | ||
SYMBOL = C.ZBAR_SYMBOL | ||
ADDON = C.ZBAR_ADDON | ||
ADDON2 = C.ZBAR_ADDON2 | ||
ADDON5 = C.ZBAR_ADDON5 | ||
) | ||
|
||
// Configuration keys | ||
const ( | ||
CFG_ENABLE = C.ZBAR_CFG_ENABLE | ||
CFG_ADD_CHECK = C.ZBAR_CFG_ADD_CHECK | ||
CFG_EMIT_CHECK = C.ZBAR_CFG_EMIT_CHECK | ||
CFG_ASCII = C.ZBAR_CFG_ASCII | ||
CFG_NUM = C.ZBAR_CFG_NUM | ||
CFG_MIN_LEN = C.ZBAR_CFG_MIN_LEN | ||
CFG_MAX_LEN = C.ZBAR_CFG_MAX_LEN | ||
CFG_POSITION = C.ZBAR_CFG_POSITION | ||
CFG_X_DENSITY = C.ZBAR_CFG_X_DENSITY | ||
CFG_Y_DENSITY = C.ZBAR_CFG_Y_DENSITY | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
// Package gozbar image bindings for golang. | ||
// Read the ZBar documents for details | ||
package gozbar | ||
|
||
// #cgo LDFLAGS: -lzbar | ||
// #include <zbar.h> | ||
import "C" | ||
|
||
import ( | ||
"image" | ||
"runtime" | ||
"unsafe" | ||
) | ||
|
||
// Image contains a zbar image and the grayscale values. | ||
type Image struct { | ||
image *C.zbar_image_t | ||
gray *image.Gray | ||
} | ||
|
||
// FromImage will create an ZBar image object from an image.Image. | ||
// To scan the image, call a Scanner. | ||
func FromImage(img image.Image) *Image { | ||
// allocate the image wrapper | ||
ret := &Image{ | ||
image: C.zbar_image_create(), | ||
} | ||
|
||
// get the height and width of the given image | ||
bounds := img.Bounds() | ||
w := bounds.Max.X - bounds.Min.X | ||
h := bounds.Max.Y - bounds.Min.Y | ||
|
||
// Create a grayscale image | ||
ret.gray = image.NewGray(bounds) | ||
|
||
// populate all the pixels in the gray image faster than draw.Draw() | ||
for y := bounds.Min.Y; y < bounds.Max.Y; y++ { | ||
for x := bounds.Min.X; x < bounds.Max.X; x++ { | ||
ret.gray.Set(x, y, img.At(x, y)) | ||
} | ||
} | ||
|
||
C.zbar_image_set_format(ret.image, C.ulong(0x30303859)) // Y800 (grayscale) | ||
C.zbar_image_set_size(ret.image, C.uint(w), C.uint(h)) | ||
C.zbar_image_set_data(ret.image, unsafe.Pointer(&ret.gray.Pix[0]), C.ulong(len(ret.gray.Pix)), nil) | ||
|
||
// finalizer | ||
runtime.SetFinalizer(ret, (*Image).Destroy) | ||
|
||
return ret | ||
} | ||
|
||
// First will return the first scanned symbol of this image. | ||
// To iterate over the symbols, use Symbol.Each() function | ||
func (i *Image) First() *Symbol { | ||
s := C.zbar_image_first_symbol(i.image) | ||
|
||
if s == nil { | ||
return nil | ||
} | ||
|
||
return &Symbol{ | ||
symbol: s, | ||
} | ||
} | ||
|
||
// Destroy this object | ||
func (i *Image) Destroy() { | ||
C.zbar_image_destroy(i.image) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
// Package gozbar scanner bindings for golang. | ||
// Read the ZBar documents for details | ||
package gozbar | ||
|
||
// #cgo LDFLAGS: -lzbar | ||
// #include <zbar.h> | ||
import "C" | ||
|
||
import ( | ||
"errors" | ||
"fmt" | ||
) | ||
|
||
// Scanner contains a reference to zbar scanner. | ||
type Scanner struct { | ||
scanner *C.zbar_image_scanner_t | ||
} | ||
|
||
// NewScanner returns a new instance of Scanner. | ||
func NewScanner() *Scanner { | ||
return &Scanner{ | ||
scanner: C.zbar_image_scanner_create(), | ||
} | ||
} | ||
|
||
// SetConfig gives the zbar scanner the configuration to run.. | ||
// Read the ZBar docs for details. | ||
func (s *Scanner) SetConfig(symbology C.zbar_symbol_type_t, config C.zbar_config_t, value int) error { | ||
// returns 0 for success, non-0 for failure | ||
resp := int(C.zbar_image_scanner_set_config(s.scanner, symbology, config, C.int(value))) | ||
if resp != 0 { | ||
return fmt.Errorf("error encountered when setting config status: %d", resp) | ||
} | ||
|
||
return nil | ||
} | ||
|
||
// Scan parses the given image and loads the scanner. | ||
func (s *Scanner) Scan(img *Image) error { | ||
status := int(C.zbar_scan_image(s.scanner, img.image)) | ||
switch status { | ||
// no symbols were found | ||
case 0: | ||
return errors.New("no symbols found") | ||
// an error occurred | ||
case -1: | ||
return errors.New("an error was encountered during scan") | ||
default: | ||
return nil | ||
} | ||
} | ||
|
||
// Destroy destroys the scanner. | ||
func (s *Scanner) Destroy() { | ||
C.zbar_image_scanner_destroy(s.scanner) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
package gozbar | ||
|
||
import ( | ||
"image/jpeg" | ||
"image/png" | ||
"os" | ||
"testing" | ||
) | ||
|
||
func TestBarcode(t *testing.T) { | ||
const expectedVal = "9876543210128" | ||
|
||
f, err := os.Open("testdata/barcode.png") | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
|
||
i, err := png.Decode(f) | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
|
||
img := FromImage(i) | ||
|
||
s := NewScanner() | ||
err = s.SetConfig(0, CFG_ENABLE, 1) | ||
if err != nil { | ||
t.Fatal("error setting config", err) | ||
} | ||
|
||
err = s.Scan(img) | ||
if err != nil { | ||
t.Fatal("error scanning", err) | ||
} | ||
defer s.Destroy() | ||
|
||
img.First().Each(func(str string) { | ||
if str != expectedVal { | ||
t.Fatalf("expected [%s] got [%s]", expectedVal, str) | ||
} | ||
}) | ||
} | ||
|
||
func TestQRCode(t *testing.T) { | ||
const expectedVal = "ZBar big law good! ZBar螟ァ豕募・ス!" | ||
|
||
f, err := os.Open("testdata/qr.jpg") | ||
if err != nil { | ||
t.Fail() | ||
return | ||
} | ||
|
||
i, _ := jpeg.Decode(f) | ||
img := FromImage(i) | ||
|
||
s := NewScanner() | ||
err = s.SetConfig(0, CFG_ENABLE, 1) | ||
if err != nil { | ||
t.Fatal("error setting config", err) | ||
} | ||
|
||
err = s.Scan(img) | ||
if err != nil { | ||
t.Fatal("error scanning", err) | ||
} | ||
defer s.Destroy() | ||
|
||
img.First().Each(func(str string) { | ||
if str != expectedVal { | ||
t.Fatalf("expected [%s] got [%s]", expectedVal, str) | ||
} | ||
}) | ||
} | ||
|
||
func TestPhoto(t *testing.T) { | ||
const expectedStr = "http://www.searchenginestrategies.com/sanfrancisco/share.html" | ||
|
||
f, err := os.Open("./testdata/photo.jpg") | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
|
||
i, err := jpeg.Decode(f) | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
|
||
img := FromImage(i) | ||
|
||
s := NewScanner() | ||
err = s.SetConfig(0, CFG_ENABLE, 1) | ||
if err != nil { | ||
t.Fatal("error setting config", err) | ||
} | ||
|
||
err = s.Scan(img) | ||
if err != nil { | ||
t.Fatal("error scanning", err) | ||
} | ||
|
||
defer s.Destroy() | ||
|
||
img.First().Each(func(str string) { | ||
if str != expectedStr { | ||
t.Fatalf("expected [%s] got [%s]", expectedStr, str) | ||
} | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
// Package gozbar symbol bindings. | ||
// Read the ZBar documents for details | ||
package gozbar | ||
|
||
// #cgo LDFLAGS: -lzbar | ||
// #include <zbar.h> | ||
import "C" | ||
|
||
// Symbol is a wrapper around a zbar symbol. | ||
type Symbol struct { | ||
symbol *C.zbar_symbol_t | ||
} | ||
|
||
// Next returns the next symbol or nil if there is none. | ||
func (s *Symbol) Next() *Symbol { | ||
n := C.zbar_symbol_next(s.symbol) | ||
|
||
if n == nil { | ||
return nil | ||
} | ||
|
||
return &Symbol{ | ||
symbol: n, | ||
} | ||
} | ||
|
||
// Data returns the scanned data for this symbol. | ||
func (s *Symbol) Data() string { | ||
sym := C.zbar_symbol_get_data(s.symbol) | ||
|
||
if sym == nil { | ||
return "" | ||
} | ||
|
||
return C.GoString(sym) | ||
} | ||
|
||
// Type returns the symbol type. | ||
// Compare it with types in constants to get the accurate symbol type. | ||
func (s *Symbol) Type() C.zbar_symbol_type_t { | ||
return C.zbar_symbol_get_type(s.symbol) | ||
} | ||
|
||
// Each will iterate over all symbols after this symbol. | ||
// passing them into the provided callback | ||
func (s *Symbol) Each(f func(string)) { | ||
t := s | ||
|
||
for { | ||
f(t.Data()) | ||
|
||
t = t.Next() | ||
|
||
if t == nil { | ||
break | ||
} | ||
} | ||
} |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.