4a0a055234
git-subtree-dir: faxmachine git-subtree-split: d23200bcfdedb9f8cc57e6a3c65b5ef93fcbfd19
189 lines
5.3 KiB
Go
189 lines
5.3 KiB
Go
// This file was origionally from:
|
|
// https://github.com/mugli/png2escpos/blob/56fca745daa0149280e04b5155cb59f1796e8842/escpos/raster.go
|
|
//
|
|
// Copyright (c) 2019, Mehdi Hasan Khan
|
|
//
|
|
// Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
// this software and associated documentation files (the "Software"), to deal in
|
|
// the Software without restriction, including without limitation the rights to
|
|
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
|
// the Software, and to permit persons to whom the Software is furnished to do so,
|
|
// subject to the following conditions:
|
|
//
|
|
// The above copyright notice and this permission notice shall be included in all
|
|
// copies or substantial portions of the Software.
|
|
//
|
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
|
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
|
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
|
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
//
|
|
// And adapted at:
|
|
// https://github.com/hennedo/escpos/blob/475ba147a030cd572bd9137e62a55185238738aa/bitimage.go
|
|
//
|
|
// MIT License
|
|
//
|
|
// Copyright (c) 2021 Hendrik Fellerhoff
|
|
//
|
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
// of this software and associated documentation files (the "Software"), to deal
|
|
// in the Software without restriction, including without limitation the rights
|
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
// copies of the Software, and to permit persons to whom the Software is
|
|
// furnished to do so, subject to the following conditions
|
|
//
|
|
// The above copyright notice and this permission notice shall be included in all
|
|
// copies or substantial portions of the Software.
|
|
//
|
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
// SOFTWARE.
|
|
|
|
package escpos
|
|
|
|
import (
|
|
"fmt"
|
|
"image"
|
|
)
|
|
|
|
func closestNDivisibleBy8(n int) int {
|
|
q := n / 8
|
|
n1 := q * 8
|
|
|
|
return n1
|
|
}
|
|
|
|
func getPrintImageData(img image.Image) (x int, y int, data []byte) {
|
|
width, height, pixels := getPixels(img)
|
|
|
|
removeTransparency(&pixels)
|
|
makeGrayscale(&pixels)
|
|
|
|
printWidth := closestNDivisibleBy8(width)
|
|
printHeight := closestNDivisibleBy8(height)
|
|
bytes, _ := rasterize(printWidth, printHeight, &pixels)
|
|
|
|
return printWidth, printHeight, 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
|
|
}
|