Compare commits
3 Commits
3080194dc1
...
10380a7901
Author | SHA1 | Date |
---|---|---|
Přemysl Eric Janouch | 10380a7901 | |
Přemysl Eric Janouch | b287ba5500 | |
Přemysl Eric Janouch | fab0a52189 |
|
@ -4,9 +4,10 @@ import (
|
||||||
"image"
|
"image"
|
||||||
"image/draw"
|
"image/draw"
|
||||||
"image/png"
|
"image/png"
|
||||||
"janouch.name/sklad/bdf"
|
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
|
"janouch.name/sklad/bdf"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
|
|
@ -0,0 +1,57 @@
|
||||||
|
package imgutil
|
||||||
|
|
||||||
|
import (
|
||||||
|
"image"
|
||||||
|
"image/color"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Scale is a scaling image.Image wrapper.
|
||||||
|
type Scale struct {
|
||||||
|
Image image.Image
|
||||||
|
Scale int
|
||||||
|
}
|
||||||
|
|
||||||
|
// ColorModel implements image.Image.
|
||||||
|
func (s *Scale) ColorModel() color.Model {
|
||||||
|
return s.Image.ColorModel()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bounds implements image.Image.
|
||||||
|
func (s *Scale) Bounds() image.Rectangle {
|
||||||
|
r := s.Image.Bounds()
|
||||||
|
return image.Rect(r.Min.X*s.Scale, r.Min.Y*s.Scale,
|
||||||
|
r.Max.X*s.Scale, r.Max.Y*s.Scale)
|
||||||
|
}
|
||||||
|
|
||||||
|
// At implements image.Image.
|
||||||
|
func (s *Scale) At(x, y int) color.Color {
|
||||||
|
if x < 0 {
|
||||||
|
x = x - s.Scale + 1
|
||||||
|
}
|
||||||
|
if y < 0 {
|
||||||
|
y = y - s.Scale + 1
|
||||||
|
}
|
||||||
|
return s.Image.At(x/s.Scale, y/s.Scale)
|
||||||
|
}
|
||||||
|
|
||||||
|
// LeftRotate is a 90 degree rotating image.Image wrapper.
|
||||||
|
type LeftRotate struct {
|
||||||
|
Image image.Image
|
||||||
|
}
|
||||||
|
|
||||||
|
// ColorModel implements image.Image.
|
||||||
|
func (lr *LeftRotate) ColorModel() color.Model {
|
||||||
|
return lr.Image.ColorModel()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bounds implements image.Image.
|
||||||
|
func (lr *LeftRotate) Bounds() image.Rectangle {
|
||||||
|
r := lr.Image.Bounds()
|
||||||
|
// Min is inclusive, Max is exclusive.
|
||||||
|
return image.Rect(r.Min.Y, -(r.Max.X - 1), r.Max.Y, -(r.Min.X - 1))
|
||||||
|
}
|
||||||
|
|
||||||
|
// At implements image.Image.
|
||||||
|
func (lr *LeftRotate) At(x, y int) color.Color {
|
||||||
|
return lr.Image.At(-y, x)
|
||||||
|
}
|
|
@ -4,7 +4,6 @@ import (
|
||||||
"errors"
|
"errors"
|
||||||
"html/template"
|
"html/template"
|
||||||
"image"
|
"image"
|
||||||
"image/color"
|
|
||||||
"image/draw"
|
"image/draw"
|
||||||
"image/png"
|
"image/png"
|
||||||
"log"
|
"log"
|
||||||
|
@ -16,62 +15,10 @@ import (
|
||||||
"github.com/boombuler/barcode/qr"
|
"github.com/boombuler/barcode/qr"
|
||||||
|
|
||||||
"janouch.name/sklad/bdf"
|
"janouch.name/sklad/bdf"
|
||||||
|
"janouch.name/sklad/imgutil"
|
||||||
"janouch.name/sklad/ql"
|
"janouch.name/sklad/ql"
|
||||||
)
|
)
|
||||||
|
|
||||||
// scaler is a scaling image.Image wrapper.
|
|
||||||
type scaler struct {
|
|
||||||
image image.Image
|
|
||||||
scale int
|
|
||||||
}
|
|
||||||
|
|
||||||
// ColorModel implements image.Image.
|
|
||||||
func (s *scaler) ColorModel() color.Model {
|
|
||||||
return s.image.ColorModel()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Bounds implements image.Image.
|
|
||||||
func (s *scaler) Bounds() image.Rectangle {
|
|
||||||
r := s.image.Bounds()
|
|
||||||
return image.Rect(r.Min.X*s.scale, r.Min.Y*s.scale,
|
|
||||||
r.Max.X*s.scale, r.Max.Y*s.scale)
|
|
||||||
}
|
|
||||||
|
|
||||||
// At implements image.Image.
|
|
||||||
func (s *scaler) At(x, y int) color.Color {
|
|
||||||
if x < 0 {
|
|
||||||
x = x - s.scale + 1
|
|
||||||
}
|
|
||||||
if y < 0 {
|
|
||||||
y = y - s.scale + 1
|
|
||||||
}
|
|
||||||
return s.image.At(x/s.scale, y/s.scale)
|
|
||||||
}
|
|
||||||
|
|
||||||
// leftRotate is a 90 degree rotating image.Image wrapper.
|
|
||||||
type leftRotate struct {
|
|
||||||
image image.Image
|
|
||||||
}
|
|
||||||
|
|
||||||
// ColorModel implements image.Image.
|
|
||||||
func (lr *leftRotate) ColorModel() color.Model {
|
|
||||||
return lr.image.ColorModel()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Bounds implements image.Image.
|
|
||||||
func (lr *leftRotate) Bounds() image.Rectangle {
|
|
||||||
r := lr.image.Bounds()
|
|
||||||
// Min is inclusive, Max is exclusive.
|
|
||||||
return image.Rect(r.Min.Y, -(r.Max.X - 1), r.Max.Y, -(r.Min.X - 1))
|
|
||||||
}
|
|
||||||
|
|
||||||
// At implements image.Image.
|
|
||||||
func (lr *leftRotate) At(x, y int) color.Color {
|
|
||||||
return lr.image.At(-y, x)
|
|
||||||
}
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
var font *bdf.Font
|
var font *bdf.Font
|
||||||
|
|
||||||
func genLabelForHeight(text string, height, scale int) image.Image {
|
func genLabelForHeight(text string, height, scale int) image.Image {
|
||||||
|
@ -81,7 +28,7 @@ func genLabelForHeight(text string, height, scale int) image.Image {
|
||||||
draw.Draw(textImg, textRect, image.White, image.ZP, draw.Src)
|
draw.Draw(textImg, textRect, image.White, image.ZP, draw.Src)
|
||||||
font.DrawString(textImg, image.ZP, text)
|
font.DrawString(textImg, image.ZP, text)
|
||||||
|
|
||||||
scaledTextImg := scaler{image: textImg, scale: scale}
|
scaledTextImg := imgutil.Scale{Image: textImg, Scale: scale}
|
||||||
scaledTextRect := scaledTextImg.Bounds()
|
scaledTextRect := scaledTextImg.Bounds()
|
||||||
|
|
||||||
remains := height - scaledTextRect.Dy() - 20
|
remains := height - scaledTextRect.Dy() - 20
|
||||||
|
@ -238,7 +185,7 @@ func handle(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
var label image.Image
|
var label image.Image
|
||||||
if mediaInfo != nil {
|
if mediaInfo != nil {
|
||||||
label = &leftRotate{image: genLabelForHeight(
|
label = &imgutil.LeftRotate{Image: genLabelForHeight(
|
||||||
params.Text, mediaInfo.PrintAreaPins, params.Scale)}
|
params.Text, mediaInfo.PrintAreaPins, params.Scale)}
|
||||||
if r.FormValue("print") != "" {
|
if r.FormValue("print") != "" {
|
||||||
if err := printer.Print(label); err != nil {
|
if err := printer.Print(label); err != nil {
|
||||||
|
|
|
@ -0,0 +1,88 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"image"
|
||||||
|
_ "image/gif"
|
||||||
|
_ "image/jpeg"
|
||||||
|
_ "image/png"
|
||||||
|
|
||||||
|
"flag"
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"janouch.name/sklad/imgutil"
|
||||||
|
"janouch.name/sklad/ql"
|
||||||
|
)
|
||||||
|
|
||||||
|
var scale = flag.Int("scale", 1, "integer upscaling")
|
||||||
|
var rotate = flag.Bool("rotate", false, "print sideways")
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
flag.Usage = func() {
|
||||||
|
fmt.Fprintf(os.Stderr, "Usage: %s IMAGE\n", os.Args[0])
|
||||||
|
flag.PrintDefaults()
|
||||||
|
}
|
||||||
|
|
||||||
|
flag.Parse()
|
||||||
|
if flag.NArg() != 1 {
|
||||||
|
flag.Usage()
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Open the picture.
|
||||||
|
f, err := os.Open(flag.Arg(0))
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalln(err)
|
||||||
|
}
|
||||||
|
defer f.Close()
|
||||||
|
|
||||||
|
// Load and eventually transform the picture.
|
||||||
|
img, _, err := image.Decode(f)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalln(err)
|
||||||
|
}
|
||||||
|
if *scale > 1 {
|
||||||
|
img = &imgutil.Scale{Image: img, Scale: *scale}
|
||||||
|
}
|
||||||
|
if *rotate {
|
||||||
|
img = &imgutil.LeftRotate{Image: img}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Open and initialize the printer.
|
||||||
|
p, err := ql.Open()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalln(err)
|
||||||
|
}
|
||||||
|
if p == nil {
|
||||||
|
log.Fatalln("no suitable printer found")
|
||||||
|
}
|
||||||
|
if err := p.Initialize(); err != nil {
|
||||||
|
log.Fatalln(err)
|
||||||
|
}
|
||||||
|
if err := p.UpdateStatus(); err != nil {
|
||||||
|
log.Fatalln(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check the picture against the media in the printer.
|
||||||
|
mi := ql.GetMediaInfo(
|
||||||
|
p.LastStatus.MediaWidthMM(),
|
||||||
|
p.LastStatus.MediaLengthMM(),
|
||||||
|
)
|
||||||
|
if mi == nil {
|
||||||
|
log.Fatalln("unknown media")
|
||||||
|
}
|
||||||
|
|
||||||
|
bounds := img.Bounds()
|
||||||
|
dx, dy := bounds.Dx(), bounds.Dy()
|
||||||
|
if dx > mi.PrintAreaPins {
|
||||||
|
log.Fatalln("the image is too wide,", dx, ">", mi.PrintAreaPins, "pt")
|
||||||
|
}
|
||||||
|
if dy > mi.PrintAreaLength && mi.PrintAreaLength != 0 {
|
||||||
|
log.Fatalln("the image is too high,", dy, ">", mi.PrintAreaLength, "pt")
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := p.Print(img); err != nil {
|
||||||
|
log.Fatalln(err)
|
||||||
|
}
|
||||||
|
}
|
20
ql/status.go
20
ql/status.go
|
@ -151,28 +151,28 @@ func (s *Status) Dump(f io.Writer) {
|
||||||
fmt.Fprintln(f, "media length:", s[17], "mm")
|
fmt.Fprintln(f, "media length:", s[17], "mm")
|
||||||
|
|
||||||
// Status type.
|
// Status type.
|
||||||
switch t := s[18]; t {
|
switch t := s[18]; StatusType(t) {
|
||||||
case 0x00:
|
case StatusTypeReplyToRequest:
|
||||||
fmt.Fprintln(f, "status type: reply to status request")
|
fmt.Fprintln(f, "status type: reply to status request")
|
||||||
case 0x01:
|
case StatusTypePrintingCompleted:
|
||||||
fmt.Fprintln(f, "status type: printing completed")
|
fmt.Fprintln(f, "status type: printing completed")
|
||||||
case 0x02:
|
case StatusTypeErrorOccurred:
|
||||||
fmt.Fprintln(f, "status type: error occurred")
|
fmt.Fprintln(f, "status type: error occurred")
|
||||||
case 0x04:
|
case StatusTypeTurnedOff:
|
||||||
fmt.Fprintln(f, "status type: turned off")
|
fmt.Fprintln(f, "status type: turned off")
|
||||||
case 0x05:
|
case StatusTypeNotification:
|
||||||
fmt.Fprintln(f, "status type: notification")
|
fmt.Fprintln(f, "status type: notification")
|
||||||
case 0x06:
|
case StatusTypePhaseChange:
|
||||||
fmt.Fprintln(f, "status type: phase change")
|
fmt.Fprintln(f, "status type: phase change")
|
||||||
default:
|
default:
|
||||||
fmt.Fprintln(f, "status type:", t)
|
fmt.Fprintln(f, "status type:", t)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Phase type.
|
// Phase type.
|
||||||
switch t := s[19]; t {
|
switch t := s[19]; StatusPhase(t) {
|
||||||
case 0x00:
|
case StatusPhaseReceiving:
|
||||||
fmt.Fprintln(f, "phase state: receiving state")
|
fmt.Fprintln(f, "phase state: receiving state")
|
||||||
case 0x01:
|
case StatusPhasePrinting:
|
||||||
fmt.Fprintln(f, "phase state: printing state")
|
fmt.Fprintln(f, "phase state: printing state")
|
||||||
default:
|
default:
|
||||||
fmt.Fprintln(f, "phase state:", t)
|
fmt.Fprintln(f, "phase state:", t)
|
||||||
|
|
Loading…
Reference in New Issue