guest_worker/test_pen.py

132 lines
3.5 KiB
Python

from pyaxidraw import axidraw
import time
import subprocess
import io
from PIL import Image
import datetime
import tqdm
import colorsys
# TODO: argparse: skip_draw, skip_scan, loop [n times]
class Level(object):
def __init__(self, minv, maxv, gamma):
self.minv= minv/255.0
self.maxv= maxv/255.0
self._interval= self.maxv - self.minv
self._invgamma= 1.0/gamma
def new_level(self, value):
if value <= self.minv: return 0.0
if value >= self.maxv: return 1.0
return ((value - self.minv)/self._interval)**self._invgamma
def convert_and_level(self, band_values):
h, s, v= colorsys.rgb_to_hsv(*(i/255.0 for i in band_values))
new_v= self.new_level(v)
return tuple(int(255*i)
for i
in colorsys.hsv_to_rgb(h, s, new_v))
def level_image(image, minv=0, maxv=255, gamma=1.0):
"""Level the brightness of image (a PIL.Image instance)
All values ≤ minv will become 0
All values ≥ maxv will become 255
gamma controls the curve for all values between minv and maxv"""
if image.mode != "RGB":
raise ValueError("this works with RGB images only")
new_image= image.copy()
leveller= Level(minv, maxv, gamma)
levelled_data= [
leveller.convert_and_level(data)
for data in image.getdata()]
new_image.putdata(levelled_data)
return new_image
now = datetime.datetime.now().isoformat()
print(f"test plotter/scanner/pen at {now}")
absPlotWidth = 26.5/2.54
topLeft = absPlotWidth / (245/ 10 / 2.54)
parkX = (1/2.54)/absPlotWidth + topLeft
parkPos = [26.5/2.54,2,0]
print(parkPos)
ad = axidraw.AxiDraw()
ad.interactive()
ad.connect()
ad.pen_raise()
ad.disconnect()
ad = axidraw.AxiDraw()
ad.plot_setup('test_drawing.svg') # Load file & configure plot context
# Plotting options can be set, here after plot_setup().
ad.plot_run()
ad.disconnect()
ad = axidraw.AxiDraw()
# park
ad.interactive()
ad.connect()
ad.pen_raise()
ad.moveto(parkPos[0], parkPos[1])
try:
sleeptime = 2
print(f"plotted, now wait for the ink to dry {sleeptime}s")
for i in tqdm.tqdm(range(sleeptime)):
time.sleep(1)
cmd = [
'sudo', 'scanimage', '-d', 'epkowa', '--format', 'tiff',
'--resolution=100', # lower res, faster (more powerful) scan & wipe
'-l','25' #y axis, margin from top of the scanner, hence increasing this, moves the scanned image upwards
,'-t','22', # x axis, margin from left side scanner (seen from the outside)
'-x',str(181),
'-y',str(245)
]
proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
# opens connection to scanner, but only starts scanning when output becomes ready:
o, e = proc.communicate(80)
print('scanned')
f = io.BytesIO(o)
img = Image.open(f)
img = img.transpose(Image.ROTATE_90).transpose(Image.FLIP_TOP_BOTTOM)
img.save(f'test-{now}.png')
print(f'\tsaved to test-{now}.png')
print('effects:')
leveldImg = level_image(img, 0, 125, 0.95)
leveldImg.save(f'test-{now}-leveled.png')
print(f'\tsaved to test-{now}-leveled.png')
except Exception as e:
print(e)
finally:
time.sleep(5) # scanner says its done before it slides back
print('reset pen')
ad.moveto(0,0)
ad.disconnect()
print('disable motors')
# disable motors
ad = axidraw.AxiDraw()
ad.plot_setup()
ad.options.mode = "manual"
ad.options.manual_cmd = "disable_xy"
ad.plot_run()