Skip to content

Commit

Permalink
Add aztec print via image
Browse files Browse the repository at this point in the history
  • Loading branch information
meyskens committed Jul 11, 2024
1 parent ff5f6d2 commit e6cdac0
Show file tree
Hide file tree
Showing 4 changed files with 171 additions and 1 deletion.
21 changes: 21 additions & 0 deletions epson.normal.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import (
"time"

"github.com/bjarneh/latinx"
"github.com/boombuler/barcode"
"github.com/boombuler/barcode/aztec"
)

var converter characterConverter = latinx.Get(latinx.ISO_8859_15)
Expand Down Expand Up @@ -54,3 +56,22 @@ func (p *Printer) write(cmd string) error {
_, err := p.s.Write([]byte(cmd))
return err
}

// AztecViaImage prints an Aztec code using the image system for longer data that is not possible to print directly
func (p *Printer) AztecViaImage(data string) error {
aztecCode, err := aztec.Encode([]byte(data), aztec.DEFAULT_EC_PERCENT, aztec.DEFAULT_LAYERS)
if err != nil {
return fmt.Errorf("failed to encode aztec code: %w", err)
}

// Scale the barcode to 200x200 pixels
aztecCode, err = barcode.Scale(aztecCode, 500, 500)
if err != nil {
return fmt.Errorf("failed to scale aztec code: %w", err)
}

xL, xH, yL, yH, imgData := printImage(aztecCode)
p.write("\x1dv\x30\x00" + string(append([]byte{xL, xH, yL, yH}, imgData...)))

return nil
}
5 changes: 4 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,7 @@ module github.com/mect/go-escpos

go 1.16

require github.com/bjarneh/latinx v0.0.0-20120329061922-4dfe9ba2a293
require (
github.com/bjarneh/latinx v0.0.0-20120329061922-4dfe9ba2a293
github.com/boombuler/barcode v1.0.2 // indirect
)
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
github.com/bjarneh/latinx v0.0.0-20120329061922-4dfe9ba2a293 h1:kQGfMtLkjk7aSGf4REldBRcip+25SRGmOWHHjGaZZXM=
github.com/bjarneh/latinx v0.0.0-20120329061922-4dfe9ba2a293/go.mod h1:HdstVrPoCN+CT+wHjeU6juUog6IM+EShcDoARBbc7cU=
github.com/boombuler/barcode v1.0.2 h1:79yrbttoZrLGkL/oOI8hBrUKucwOL0oOjUgEguGMcJ4=
github.com/boombuler/barcode v1.0.2/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8=
144 changes: 144 additions & 0 deletions image.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
package escpos

// big thanks for this hard work to https://github.com/hennedo/escpos/blob/master/bitimage.go

import (
"fmt"
"image"
)

func closestNDivisibleBy8(n int) int {
q := n / 8
n1 := q * 8

return n1
}

func printImage(img image.Image) (xL byte, xH byte, yL byte, yH byte, data []byte) {
width, height, pixels := getPixels(img)

removeTransparency(&pixels)
makeGrayscale(&pixels)

printWidth := closestNDivisibleBy8(width)
printHeight := closestNDivisibleBy8(height)
bytes, _ := rasterize(printWidth, printHeight, &pixels)

return byte((printWidth >> 3) & 0xff), byte(((printWidth >> 3) >> 8) & 0xff), byte(printHeight & 0xff), byte((printHeight >> 8) & 0xff), bytes
}

func makeGrayscale(pixels *[][]pixel) {
height := len(*pixels)
width := len((*pixels)[0])

for y := 0; y < height; y++ {
row := (*pixels)[y]
for x := 0; x < width; x++ {
pixel := row[x]

luminance := (float64(pixel.R) * 0.299) + (float64(pixel.G) * 0.587) + (float64(pixel.B) * 0.114)
var value int
if luminance < 128 {
value = 0
} else {
value = 255
}

pixel.R = value
pixel.G = value
pixel.B = value

row[x] = pixel
}
}
}

func removeTransparency(pixels *[][]pixel) {
height := len(*pixels)
width := len((*pixels)[0])

for y := 0; y < height; y++ {
row := (*pixels)[y]
for x := 0; x < width; x++ {
pixel := row[x]

alpha := pixel.A
invAlpha := 255 - alpha

pixel.R = (alpha*pixel.R + invAlpha*255) / 255
pixel.G = (alpha*pixel.G + invAlpha*255) / 255
pixel.B = (alpha*pixel.B + invAlpha*255) / 255
pixel.A = 255

row[x] = pixel
}
}
}

func rasterize(printWidth int, printHeight int, pixels *[][]pixel) ([]byte, error) {
if printWidth%8 != 0 {
return nil, fmt.Errorf("printWidth must be a multiple of 8")
}

if printHeight%8 != 0 {
return nil, fmt.Errorf("printHeight must be a multiple of 8")
}

bytes := make([]byte, (printWidth*printHeight)>>3)

for y := 0; y < printHeight; y++ {
for x := 0; x < printWidth; x = x + 8 {
i := y*(printWidth>>3) + (x >> 3)
bytes[i] =
byte((getPixelValue(x+0, y, pixels) << 7) |
(getPixelValue(x+1, y, pixels) << 6) |
(getPixelValue(x+2, y, pixels) << 5) |
(getPixelValue(x+3, y, pixels) << 4) |
(getPixelValue(x+4, y, pixels) << 3) |
(getPixelValue(x+5, y, pixels) << 2) |
(getPixelValue(x+6, y, pixels) << 1) |
getPixelValue(x+7, y, pixels))
}
}

return bytes, nil
}

func getPixelValue(x int, y int, pixels *[][]pixel) int {
row := (*pixels)[y]
pixel := row[x]

if pixel.R > 0 {
return 0
}

return 1
}

func rgbaToPixel(r uint32, g uint32, b uint32, a uint32) pixel {
return pixel{int(r >> 8), int(g >> 8), int(b >> 8), int(a >> 8)}
}

type pixel struct {
R int
G int
B int
A int
}

func getPixels(img image.Image) (int, int, [][]pixel) {

bounds := img.Bounds()
width, height := bounds.Max.X, bounds.Max.Y

var pixels [][]pixel
for y := 0; y < height; y++ {
var row []pixel
for x := 0; x < width; x++ {
row = append(row, rgbaToPixel(img.At(x, y).RGBA()))
}
pixels = append(pixels, row)
}

return width, height, pixels
}

0 comments on commit e6cdac0

Please sign in to comment.