escpos icon indicating copy to clipboard operation
escpos copied to clipboard

XPrinter 48mm POS-5890K

Open zbykovskyi opened this issue 1 year ago • 0 comments

For everyone who will be faced with printing gibberish on such model of printer.

During debugging the issue we experimentally figured out that it started printing gibberish when we send command GS v 0 with image height multiple of 48 only : i.e. 240, 192, 144, 96 . We handled this case with spliting whole image into chunks of multiple of 256 and then if smaller chunk is multiple of 48 then increase image height on 8 and just fill that addition with 255 brightness pixels. Finally send chunks of GS v 0 one by one to the printer.

So it seems a bug with printer`s firmware rather than library issue

if someone needs a fix for such printer here one of the possible solutions

const (
	xPrinterBuggyImageDivisor = 48
)

type Image struct {
	Width  int
	Height int
	Pixels [][]pixel
}

func closestNDivisibleBy8(n int) int {
	q := n / 8
	n1 := q * 8
	if n1%xPrinterBuggyImageDivisor == 0 {
		n1 += 8
	}
	return n1
}

func getPixels(reader io.Reader) ([]Image, error) {

	img, _, err := image.Decode(reader)

	if err != nil {
		return []Image{}, err
	}

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

	imageDivisor := 256
	imagesCount := printHeight / imageDivisor
	if printHeight%imageDivisor != 0 {
		imagesCount++
	}

	restTailHeight := printHeight - (imagesCount-1)*imageDivisor
	if restTailHeight%xPrinterBuggyImageDivisor == 0 {
		printHeight += 8
	}

	images := make([]Image, imagesCount)

	previous := 0
	for i := imagesCount; i > 0; i-- {
		localHeight := printHeight - (i-1)*imageDivisor - previous
		pixels := make([][]pixel, localHeight)

		for y := 0; y < localHeight; y++ {
			pixels[y] = make([]pixel, printWidth)
			for x := 0; x < printWidth; x++ {
				if x >= width || y+previous >= height {
					pixels[y][x] = pixel{0xff, 0xff, 0xff, 0x01}
				} else {
					pixels[y][x] = rgbaToPixel(img.At(x, y+previous).RGBA())
				}
			}
		}
		previous += localHeight
		images[imagesCount-i] = Image{printWidth, localHeight, pixels}
	}
	return images, nil
}

zbykovskyi avatar Feb 12 '24 17:02 zbykovskyi