package libgofunc import ( /* #include */ "C" _ "image/png" "os" "strings" "bufio" "log" "net" "time" "errors" "github.com/kenshaw/escpos" ) import "io" //export PrintImg func PrintImg(printer *C.char, imagePath *C.char) *C.char { goPrinter := C.GoString(printer) goImagePath := C.GoString(imagePath) err := Print(goPrinter, goImagePath) if err != nil { return NewErr(err) } return NewOk(nil) } //export CheckPrinter func CheckPrinter(printer *C.char) *C.char { goPrinter := C.GoString(printer) err := Check(goPrinter) if err != nil { return NewErr(err) } return NewOk(nil) } func Print(printer, imagePath string) error { conn, err := connect(printer) if err != nil { return err } defer conn.Close() w := bufio.NewReadWriter(bufio.NewReader(conn), bufio.NewWriter(conn)) prt := escpos.New(w) prt.Init() prt.SetSmooth(1) prt.SetAlign("left") imgBytes, err := imgData(imagePath) if err != nil { return err } err = writeChunk(w, prt, imgBytes) if err != nil { return err } time.Sleep(500 * time.Millisecond) w.Flush() prt.WriteRaw([]byte{0x1B, 0x64, 0x03}) prt.Cut() prt.End() w.Flush() time.Sleep(1 * time.Second) return nil } func Check(printer string) error { conn, err := connect(printer) if err != nil { return err } defer conn.Close() var w *bufio.ReadWriter w = bufio.NewReadWriter(bufio.NewReader(conn), bufio.NewWriter(conn)) prt := escpos.New(w) prt.Init() prt.SetSmooth(1) prt.SetAlign("left") time.Sleep(100 * time.Millisecond) return w.Flush() } func connect(printer string) (io.ReadWriteCloser, error) { if strings.HasPrefix(printer, "tcp:") { location := strings.TrimLeft(printer, "tcp:") conn, err := net.Dial("tcp", location) if err != nil { log.Println("error net.Dial tcp:", err.Error()) return nil, err } return conn, nil } else if strings.HasPrefix(printer, "usb:") { location := strings.TrimLeft(printer, "usb:") f, err := os.OpenFile(location, os.O_WRONLY, 0666) if err != nil { log.Println("error os.OpenFile usb:", err.Error()) return nil, err } return f, nil } return nil, errors.New("invalid printer") } // writeChunk breaks the large byte array into smaller chunks func writeChunk(w *bufio.ReadWriter, prt *escpos.Escpos, data []byte) error { chunkSize := 1024 // 1 KB chunks work best for network printers for i := 0; i < len(data); i += chunkSize { end := min(i+chunkSize, len(data)) _, err := prt.WriteRaw(data[i:end]) if err != nil { log.Println("Error writing image chunk:", err) return err } if err := w.Flush(); err != nil { log.Println("Error flushing buffer:", err) return err } // Give the printer's network chip a microsecond to breathe time.Sleep(5 * time.Millisecond) } return nil }