Trying to print using ZPL to zebra printer - python

So im trying to print using ZPL language to a zebra printer, but when i run the below code all i get is blank labels, any idea why its not reading the ZPL variable "label". I have put the code into labelary and it looks correct but i cant get it to print the ZPL its just blank labels.
import os
from PIL import Image
import zpl
from zebra import Zebra
lines = []
with open(
r'C:\Users\matthew.vandruff\Downloads\Hard Drives (version '
r'1)-b0dd6970-7dfd-4bb7-b04d-fc9c3ff4bc8a-a54c9c76-f7e2-40b1-8ff4-6d7eec1c99bb.csv') as f:
for line in f.readlines():
l, name = line.strip().split(',')
lines.append((l, name))
list = lines
x = 1
while x < len(list):
HD_Serial, HD_Number = list[x]
# print(HD_Serial, HD_Number)
x += 1
l = zpl.Label(100, 60)
height = 0
height += 5
l.origin(30, height)
l.write_barcode(height=70, barcode_type='C', check_digit='Y')
l.write_text(f'{HD_Number}')
l.endorigin()
height += 0
image_width = 12
l.origin((l.width - image_width) / 3, height)
image_height = l.write_graphic(
Image.open(os.path.join(os.path.dirname(zpl.__file__), 'MTC_Logo.png')),
image_width)
l.endorigin()
height += image_height + 5
l.origin(15, height)
l.write_barcode(height=70, barcode_type='C', check_digit='Y')
l.write_text(f'{HD_Serial}')
l.endorigin()
print(l.dumpZPL())
z = Zebra()
Q = z.getqueues()
z.setqueue(Q[0])
z.setup()
z.autosense()
z.output(l)

So I'm guessing my issue was in the settings of the printer but this is my final working code for anyone that comes looking and is only getting blanks when trying to print.
import os
from PIL import Image
import zpl
from zebra import Zebra
lines = []
with open(
r'C:\Users\matthew.vandruff\Downloads\Hard Drives (version '
r'1)-b0dd6970-7dfd-4bb7-b04d-fc9c3ff4bc8a-a54c9c76-f7e2-40b1-8ff4-6d7eec1c99bb.csv') as f:
for line in f.readlines():
l, name = line.strip().split(',')
lines.append((l, name))
list = lines
x = 1
while x < len(list):
HD_Serial, HD_Number = list[x]
# print(HD_Serial, HD_Number)
x += 1
l = zpl.Label(100, 100)
height = 0
height += 15
l.origin(23, height)
l.write_barcode(height=80, barcode_type='C', check_digit='Y')
l.write_text(f'{HD_Number}')
l.endorigin()
height += 0
image_width = 12
l.origin((l.width - image_width) / 10, height)
image_height = l.write_graphic(
Image.open(os.path.join(os.path.dirname(zpl.__file__), 'MTC_Logo.bmp')),
image_width)
l.endorigin()
height += image_height + 5
l.origin(5, height)
l.write_barcode(height=80, barcode_type='C', check_digit='Y')
l.write_text(f'{HD_Serial}')
l.endorigin()
label = l.dumpZPL()
l.preview()
z = Zebra()
Q = z.getqueues()
z.setqueue(Q[0])
z.setup()
z.output(label)

Related

Get the coordinates of detected words using pytesseract

Am making a digital assistant as final year project and I want to automate the browser tab by getting title of tab including the location of the detected words and use the coordinates to click the tab. I tried this answers I found here but not what I needed.
from pytesseract import *
from PIL import ImageGrab
pytesseract.tesseract_cmd = 'C:\\Program Files\\Tesseract-OCR\\tesseract.exe'
while True:
cap = ImageGrab.grab(bbox=(0, 0, 1182, 34)) # bounding box of the browser tab bar
text = pytesseract.image_to_data(cap, output_type=Output.DICT)
print(text)
data = {}
for i in range(len(text['line_num'])):
txt = text['text'][i]
block_num = text['block_num'][i]
line_num = text['line_num'][i]
top, left = text['top'][i], text['left'][i]
width, height = text['width'][i], text['height'][i]
if not txt == '' or txt.isspace():
tup = (txt, left, top, width, height)
if block_num in data:
if line_num in data[block_num]:
data[block_num][line_num].append(tup)
else:
data[block_num][line_num] = [tup]
else:
data[block_num] = {}
data[block_num][line_num] = [tup]
linedata = {}
idx = 0
for _, b in data.items():
for _, i in b.items():
linedata[idx] = i
idx += 1
line_idx = 1
for _, line in linedata.items():
xmin, ymin = line[0][1], line[0][2]
xmax, ymax = (line[-1][1] + line[-1][3]), (line[-1][2] + line[-1][4])
print(f'line{line_idx}, {xmin}, {ymin}, {xmax}, {ymax}, {txt}')
line_idx += 1
I need the title of each tab and their coordinates. Am pretty confident that pytesseract.image_to_data() is what I need but don't know how to extract the information that need

Join extracted/splitted patches to reconstruct an image

i used this code below to extract patches from a image.
extract code:
import os
import glob
from PIL import Image
Image.MAX_IMAGE_PIXELS = None # to avoid image size warning
imgdir = "/path/to/image/folder"
filelist = [f for f in glob.glob(imgdir + "**/*.png", recursive=True)]
savedir = "/path/to/image/folder/output"
start_pos = start_x, start_y = (0, 0)
cropped_image_size = w, h = (256, 256)
for file in filelist:
img = Image.open(file)
width, height = img.size
frame_num = 1
for col_i in range(0, width, w):
for row_i in range(0, height, h):
crop = img.crop((col_i, row_i, col_i + w, row_i + h))
name = os.path.basename(file)
name = os.path.splitext(name)[0]
save_to= os.path.join(savedir, name+"_{:03}.png")
crop.save(save_to.format(frame_num))
frame_num += 1
Now i want to reconstruct this imagem from all those patches extracted before, i've tried 2 diffenret codes
so my DB is 120x256x256x3 extracted patches, theres 120 patches to fit in 3840x2048 shape..:
patches = []
for directory_path in glob.glob('D:\join_exemplo'):
for img_path in glob.glob(os.path.join(directory_path, "*.png")):
img = cv2.imread(img_path,1)
patches.append(img)
input_patches = np.array(patches)
first i've tried sklearn.feature_extraction.image importing reconstruct_from_patches_2d, but got a black image:
reconstruct = reconstruct_from_patches_2d(input_patches, input_image)
reconstruct = reconstruct.astype(np.uint8)
Image.fromarray(reconstruct, 'RGB').save(r'D:\join_exemplo\re\re3.png')
also tried, this below but got a grayscale tone pattern image
input_image = (3840,2048,3)
reconstructed_arr = np.zeros(shape=(3840,2048,3))
#%%
>>> step = 256
>>> for x in range(img.shape[0]):
for y in range(img.shape[1]):
x_pos, y_pos = x * step, y * step
reconstructed_arr[x_pos:x_pos + 512, y_pos:y_pos + 512] = img[x, y, 0, ...]
>>> (input_image == reconstructed_arr).all()
True
cv2.imwrite(r'D:\join_exemplo\re\re.png',reconstructed_arr)
Can someone see whats wrong? sorry about my bad english

Weird ordering of bytes from one pixel to the next in simple PIL bitmap. What is likely wrong?

Here is the code.
import os
import io
import PIL
#import pyximport; pyximport.install()
#from pixel_tools import PixelsBMP
from PIL import Image, ImageGrab
# TODO convert to Cython
class PixelsBMP:
def __init__(self, img):
if isinstance(img, str):
img = Image.open(img)
with io.BytesIO() as bytes_io:
img.save(bytes_io, 'BMP')
data = bytes_io.getvalue()
offset = int.from_bytes(data[10:14], byteorder='little', signed=False)
data = data[offset:] # pixels start here
self.data = data
self.width = img.width
self.height = img.height
self.bands = 3 if img.mode == 'RGB' else 4
def debugPrintPixels(self):
import sys
d = self.data
print('width:', self.width)
print('height:', self.height)
print('bands (alpha=>4):', self.bands)
for y in range(0, self.height):
for x in range(0, self.width):
offs = self.width * self.bands * y + x
sys.stdout.write('(' + str(d[offs]) + ',' + str(d[offs + 1]) + ',' + str(d[offs + 2]) + ((',' + str(d[offs + 3])) if self.bands == 4 else '') + ')')
print()
if __name__ == '__main__':
subpx = PixelsBMP('images/PixelsBMP_test_subImage.png')
subpx.debugPrintPixels()
##pixels = PixelsBMP('images/PixelsBMP_test_superImage.png')
##point = pixels.exactSubpixelSearch(subpx)
#print(point)
print('test done')
What it prints is:
width: 7
height: 3
bands (alpha=>4): 4
(100,50,25,255)(50,25,255,100)(25,255,100,50)(255,100,50,25)(100,50,25,255)(50,25,255,100)(25,255,100,50)
(100,50,25,255)(50,25,255,100)(25,255,100,50)(255,100,50,25)(100,50,25,255)(50,25,255,100)(25,255,100,50)
(100,50,25,255)(50,25,255,100)(25,255,100,50)(255,100,50,25)(100,50,25,255)(50,25,255,100)(25,255,100,50)
None
test done
For this 7x3 navy blue bitmap. Pixels are: (25, 50, 100) solid RGB.
(It's small, right after this line):
So, the BGR ordering isn't shocking or significant here, but the fact that the order changes from the first pixel to the second:
(100,50,25,255)(50,25,255,100).
I'm lazy tonight. What am I doing wrong?
Found the issue:
offs = self.width * self.bands * y + x
in the debugPrint routine should be:
offs = self.width * self.bands * y + x * self.bands
as clearly each pixel is bands wide.
Output of the printer is correct now.

Creating print job in gtk3/python

I have some information (a list of participants to an event) which I want to print out easily. No need for fancy layout, just a table with several columns, and if possible a drawn line in between the lines of text for better readability. Will need to print landscape to make it all fit (can be done via a GtkPageSetup).
I'm using Python, and I'm on Linux so will have to use the GtkPrintUnixDialog interface. I've been searching on Internet but can't find any example on how this could possibly be achieved.
To simplify the problem: it's for my own use only, so known paper size (A4).
The problem that I have is basically two-fold: 1) create a properly formatted text, suitable for printing, and 2) send this to the printer.
Any suggestions on where to start? Or better, complete examples?
I search for my old print examples, but for a start:
You could write to pdf surface, and print pdf, or
put the drawing code on on_print function. Note, it does not print what you see, but what you draw on print surface. Draw the context like a regular cairo context, but a few methods are not available(don't fit in print context) while others, like new page, are added. If I find the example, I will come with a answer more self-explanatory.
Edit: find an ex:
def on_button_clicked(self, widget):
ps = Gtk.PaperSize.new_custom("cc", "cc", 210, 297, Gtk.Unit.MM)
st = Gtk.PrintSettings()
s = Gtk.PageSetup()
s.set_paper_size(ps)
s.set_bottom_margin(4.3, Gtk.Unit.MM)
s.set_left_margin(4.3, Gtk.Unit.MM)
s.set_right_margin(4.3, Gtk.Unit.MM)
s.set_top_margin(4.3, Gtk.Unit.MM)
s.set_orientation(Gtk.PageOrientation.LANDSCAPE)
# ret = Gtk.print_run_page_setup_dialog(self, s, st)
pd = Gtk.PrintOperation()
pd.set_n_pages(1)
pd.set_default_page_setup(s)
pd.connect("begin_print", self.bg)
pd.connect("draw_page", self.draw_page)
# print(ret, s, st)
pd.set_export_filename("test.pdf")
result = pd.run(Gtk.PrintOperationAction.EXPORT, None) #play with action, but for test export first; if it's ok, then action.PRINT
print (result) # handle errors etc.
# Gtk.PaperSize.free(ps) - not needed in py
the above may be on button press or whatever
def draw_page (self, operation, context, page_number):
end = self.layout.get_line_count()
cr = context.get_cairo_context()
cr.set_source_rgb(0, 0, 0)
i = 0
start = 0
start_pos = 0
iter = self.layout.get_iter()
while 1:
if i >= start:
line = iter.get_line()
print(line)
_, logical_rect = iter.get_line_extents()
# x_bearing, y_bearing, lwidth, lheight = logical_rect
baseline = iter.get_baseline()
if i == start:
start_pos = 12000 / 1024.0 # 1024.0 is float(pango.SCALE)
cr.move_to(0 / 1024.0, baseline / 1024.0 - start_pos)
PangoCairo.show_layout_line(cr, line)
i += 1
if not (i < end and iter.next_line()):
break
That's just a basic example. Note that layout is a pango layout:
self.layout = cx.create_pango_layout()
self.layout.set_width(int(w / 4 * Pango.SCALE))
self.layout.set_text(text, len(text))
num_lines = self.layout.get_line_count()
page_height = 0
self.layout.set_font_description(Pango.FontDescription("Georgia Bold 12"))
k = 0
for line in range(num_lines):
if k == 4:
self.layout.set_font_description(Pango.FontDescription("Georgia 10"))
layout_line = self.layout.get_line(line)
ink_rect, logical_rect = layout_line.get_extents()
lheight = 1200
line_height = lheight / 1024.0 # 1024.0 is float(pango.SCALE)
page_height += line_height
k += 1
print ("page_height ", page_height)
copy/paste functional example:
#!/usr/bin/python
from gi.repository import Gtk, Pango, PangoCairo
import cairo
text = '''
Text.
I have some information (a list of participants to an event) which I
want to print out easily.
No need for fancy layout,
just a table with several columns,
and if possible a drawn line in between the lines of
text for better readability.
'''
class MyWindow(Gtk.Window):
def __init__(self):
Gtk.Window.__init__(self, title="Hello World Printing")
self.button = Gtk.Button(label="Print A Rectangle")
self.button.connect("clicked", self.on_button_clicked)
self.add(self.button)
def on_button_clicked(self, widget):
ps = Gtk.PaperSize.new_custom("cc", "cc", 210, 297, Gtk.Unit.MM)
st = Gtk.PrintSettings()
s = Gtk.PageSetup()
s.set_paper_size(ps)
s.set_bottom_margin(4.3, Gtk.Unit.MM)
s.set_left_margin(4.3, Gtk.Unit.MM)
s.set_right_margin(4.3, Gtk.Unit.MM)
s.set_top_margin(4.3, Gtk.Unit.MM)
s.set_orientation(Gtk.PageOrientation.LANDSCAPE)
# ret = Gtk.print_run_page_setup_dialog(self, s, st)
pd = Gtk.PrintOperation()
pd.set_n_pages(1)
pd.set_default_page_setup(s)
pd.connect("begin_print", self.bg)
pd.connect("draw_page", self.draw_page)
# print(ret, s, st)
pd.set_export_filename("test.pdf")
result = pd.run(Gtk.PrintOperationAction.EXPORT, None)
print (result) # handle errors etc.
# Gtk.PaperSize.free(ps)
def bg(self, op, cx):
w = cx.get_width()
h = cx.get_height()
self.layout = cx.create_pango_layout()
self.layout.set_width(int(w / 4 * Pango.SCALE))
self.layout.set_text(text, len(text))
num_lines = self.layout.get_line_count()
page_height = 0
self.layout.set_font_description(Pango.FontDescription("Georgia Bold 12"))
k = 0
for line in range(num_lines):
if k == 4:
self.layout.set_font_description(Pango.FontDescription("Georgia 10"))
layout_line = self.layout.get_line(line)
ink_rect, logical_rect = layout_line.get_extents()
# print(logical_rect, ink_rect)
# x_bearing, y_bearing, lwidth, lheight = logical_rect
lheight = 1200
line_height = lheight / 1024.0 # 1024.0 is float(pango.SCALE)
page_height += line_height
# page_height is the current location on a page.
# It adds the the line height on each pass through the loop
# Once it is greater then the height supplied by context.get_height
# it marks the line and sets the current page height back to 0
k += 1
print ("page_height ", page_height)
def box(self, w, h, x, y, cx):
w, h = int(w), int(h)
cx.set_font_size(100)
cx.set_source_rgb(0, 0, 0)
cx.rectangle(x, y, w, h)
cx.stroke()
yy = 120
cx.select_font_face("Times", 0, 1)
ex = cx.text_extents("TEGOLA ROMÂNIA SRL")[2]
cx.move_to(w / 2 - ex / 2 + x, 105 + y)
cx.show_text("TEGOLA ROMÂNIA SRL")
ex = cx.text_extents("Str. Plevnei, nr. 5, Buzău")[2]
cx.move_to(w / 2 - ex / 2 + x, 210 + y)
cx.show_text("Str. Plevnei, nr. 5, Buzău")
ex = cx.text_extents("Tel.: 0238/710.280")[2]
cx.move_to(w / 2 - ex / 2 + x, 320 + y)
cx.show_text("Tel.: 0238/710.280")
ex = cx.text_extents("Fax : 0238/710021")[2]
cx.move_to(w / 2 - ex / 2 + x, 415 + y)
cx.show_text("Fax : 0238/710021")
cx.set_font_size(90)
cx.move_to(x + 120, 520 + y)
ex = cx.text_extents("Compoziție:")[2]
cx.show_text("Compoziție:")
cx.select_font_face("Times", 0, 0)
cx.move_to(x + 125 + ex, 520 + y)
cx.show_text("Polimer bituminos, liant și")
cx.move_to(x + 5, 620 + y)
cx.show_text("material de umplutură de înaltă calitate.")
cx.move_to(x + 5, 720 + y)
cx.show_text("Nu conține gudron.")
cx.move_to(x + 5, 800 + y)
cx.select_font_face("Times", 0, 1)
ex = cx.text_extents("Instrucțiuni de utilizare:")[2]
cx.show_text("Instrucțiuni de utilizare:")
cx.select_font_face("Times", 0, 0)
cx.move_to(x + 10 + ex, 800 + y)
cx.show_text("Suprafețele se")
def draw_page1(self, operation, context, page_nr=None):
ctx = context.get_cairo_context()
w = context.get_width()
h = context.get_height()
ww, hh = int(w / 4), int(h / 2)
self.k = 0
for x in range(2):
for y in range(4):
self.box(ww, hh, y * ww, x * hh, ctx)
self.k += 1
print(ctx.get_font_matrix())
def draw_page (self, operation, context, page_number):
end = self.layout.get_line_count()
cr = context.get_cairo_context()
cr.set_source_rgb(0, 0, 0)
i = 0
start = 0
start_pos = 0
iter = self.layout.get_iter()
while 1:
if i >= start:
line = iter.get_line()
print(line)
_, logical_rect = iter.get_line_extents()
# x_bearing, y_bearing, lwidth, lheight = logical_rect
baseline = iter.get_baseline()
if i == start:
start_pos = 12000 / 1024.0 # 1024.0 is float(pango.SCALE)
cr.move_to(0 / 1024.0, baseline / 1024.0 - start_pos)
PangoCairo.show_layout_line(cr, line)
i += 1
if not (i < end and iter.next_line()):
break
win = MyWindow()
win.connect("delete-event", Gtk.main_quit)
win.show_all()
Gtk.main()
Don't forget to change action to Gtk.PrintOperationAction.PRINT for real printing.

Creating a tiled map with blender

I'm looking at creating map tiles based on a 3D model made in blender,
The map is 16 x 16 in blender.
I've got 4 different zoom levels and each tile is 100 x 100 pixels. The entire map at the most zoomed out level is 4 x 4 tiles constructing an image of 400 x 400.
The most zoomed in level is 256 x 256 obviously constructing an image of 25600 x 25600
What I need is a script for blender that can create the tiles from the model.
I've never written in python before so I've been trying to adapt a couple of the scripts which are already there.
So far I've come up with a script, but it doesn't work very well. I'm having real difficulties getting the tiles to line up seamlessly. I'm not too concerned about changing the height of the camera as I can always create the same zoomed out tiles at 6400 x 6400 images and split the resulting images into the correct tiles.
Here is what I've got so far...
#!BPY
"""
Name: 'Export Map Tiles'
Blender: '242'
Group: 'Export'
Tip: 'Export to Map'
"""
import Blender
from Blender import Scene,sys
from Blender.Scene import Render
def init():
thumbsize = 200
CameraHeight = 4.4
YStart = -8
YMove = 4
XStart = -8
XMove = 4
ZoomLevel = 1
Path = "/Images/Map/"
Blender.drawmap = [thumbsize,CameraHeight,YStart,YMove,XStart,XMove,ZoomLevel,Path]
def show_prefs():
buttonthumbsize = Blender.Draw.Create(Blender.drawmap[0]);
buttonCameraHeight = Blender.Draw.Create(Blender.drawmap[1])
buttonYStart = Blender.Draw.Create(Blender.drawmap[2])
buttonYMove = Blender.Draw.Create(Blender.drawmap[3])
buttonXStart = Blender.Draw.Create(Blender.drawmap[4])
buttonXMove = Blender.Draw.Create(Blender.drawmap[5])
buttonZoomLevel = Blender.Draw.Create(Blender.drawmap[6])
buttonPath = Blender.Draw.Create(Blender.drawmap[7])
block = []
block.append(("Image Size", buttonthumbsize, 0, 500))
block.append(("Camera Height", buttonCameraHeight, -0, 10))
block.append(("Y Start", buttonYStart, -10, 10))
block.append(("Y Move", buttonYMove, 0, 5))
block.append(("X Start", buttonXStart,-10, 10))
block.append(("X Move", buttonXMove, 0, 5))
block.append(("Zoom Level", buttonZoomLevel, 1, 10))
block.append(("Export Path", buttonPath,0,200,"The Path to save the tiles"))
retval = Blender.Draw.PupBlock("Draw Map: Preferences" , block)
if retval:
Blender.drawmap[0] = buttonthumbsize.val
Blender.drawmap[1] = buttonCameraHeight.val
Blender.drawmap[2] = buttonYStart.val
Blender.drawmap[3] = buttonYMove.val
Blender.drawmap[4] = buttonXStart.val
Blender.drawmap[5] = buttonXMove.val
Blender.drawmap[6] = buttonZoomLevel.val
Blender.drawmap[7] = buttonPath.val
Export()
def Export():
scn = Scene.GetCurrent()
context = scn.getRenderingContext()
def cutStr(str): #cut off path leaving name
c = str.find("\\")
while c != -1:
c = c + 1
str = str[c:]
c = str.find("\\")
str = str[:-6]
return str
#variables from gui:
thumbsize,CameraHeight,YStart,YMove,XStart,XMove,ZoomLevel,Path = Blender.drawmap
XMove = XMove / ZoomLevel
YMove = YMove / ZoomLevel
Camera = Scene.GetCurrent().getCurrentCamera()
Camera.LocZ = CameraHeight / ZoomLevel
YStart = YStart + (YMove / 2)
XStart = XStart + (XMove / 2)
#Point it straight down
Camera.RotX = 0
Camera.RotY = 0
Camera.RotZ = 0
TileCount = 4**ZoomLevel
#Because the first thing we do is move the camera, start it off the map
Camera.LocY = YStart - YMove
for i in range(0,TileCount):
Camera.LocY = Camera.LocY + YMove
Camera.LocX = XStart - XMove
for j in range(0,TileCount):
Camera.LocX = Camera.LocX + XMove
Render.EnableDispWin()
context.extensions = True
context.renderPath = Path
#setting thumbsize
context.imageSizeX(thumbsize)
context.imageSizeY(thumbsize)
#could be put into a gui.
context.imageType = Render.PNG
context.enableOversampling(0)
#render
context.render()
#save image
ZasString = '%s' %(int(ZoomLevel))
XasString = '%s' %(int(j+1))
YasString = '%s' %(int((3-i)+1))
context.saveRenderedImage("Z" + ZasString + "X" + XasString + "Y" + YasString)
#close the windows
Render.CloseRenderWindow()
try:
type(Blender.drawmap)
except:
#print 'initialize extern variables'
init()
show_prefs()
This was relatively simple in the end.
I scaled up the model so that 1 tile on the map was 1 grid in blender.
Set the camera to be orthographic.
Set the scale on the camera to 1 for the highest zoom, 4 for the next one, 16 for the next one and so on.
Updated the start coordinates and move values accordingly.

Categories

Resources