Inserting bitmap

This commit is contained in:
ondro 2013-07-31 01:06:22 +02:00
parent 52917bc546
commit d4bb8dd23f
4 changed files with 237 additions and 136 deletions

View file

@ -24,7 +24,8 @@ class Gui:
self.mainWindow.title('Knitting pattern uploader')
self.mainWindow.geometry("600x400")
self.mainWindow.grid()
self.mainWindow.grid_columnconfigure(1,weight=1)
self.mainWindow.grid_columnconfigure(1,weight=10)
self.mainWindow.grid_columnconfigure(2,weight=1)
self.mainWindow.resizable(True,True)
def createDeviceWidgets(self):
@ -40,9 +41,12 @@ class Gui:
caption = Tkinter.StringVar()
self.emuButton = Tkinter.Button(self.mainWindow, textvariable = caption, command = self.mainWindow.emuButtonClicked)
self.emuButton.caption = caption
self.emuButton.grid(column=2,row=self._row)
self.emuButton.grid(column=2,row=self._row, columnspan=2, sticky='EW')
self.setEmuButtonStopped()
but = Tkinter.Button(self.mainWindow, text = u'Help...', command = self.mainWindow.helpButtonClicked)
but.grid(column=4,row=self._row, sticky='E')
def createDatFileWidgets(self):
label = Tkinter.Label(self.mainWindow, text=u"Dat file:")
label.grid(column=0, row=self._row, sticky='W')
@ -52,8 +56,11 @@ class Gui:
self.mainWindow.datFileEntry.grid(column=1,row=self._row,sticky='EW')
self.mainWindow.datFileEntry.entryText = entryText
self.chooseDatFileButton = Tkinter.Button(self.mainWindow, text=u"...", command = self.mainWindow.chooseDatFileButtonClicked)
self.chooseDatFileButton.grid(column=2,row=self._row,sticky='W')
self.reloadDatFileButton = Tkinter.Button(self.mainWindow, text=u"Reload file", command = self.mainWindow.reloadDatFileButtonClicked)
self.reloadDatFileButton.grid(column=2,row=self._row,sticky='EW')
self.reloadDatFileButton.grid(column=3,row=self._row,sticky='EW')
def createInfoMessagesLabel(self):
labelText = Tkinter.StringVar()
@ -87,8 +94,11 @@ class Gui:
label.caption = textvar
self.mainWindow.patternTitle = label
self.insertBitmapButton = Tkinter.Button(patternFrame, text=u"Insert bitmap...", command = self.mainWindow.insertBitmapButtonClicked)
self.insertBitmapButton.grid(column=2,row=0,sticky='EW')
pc = ExtendedCanvas(patternFrame, bg='white')
pc.grid(column=1, row=1, sticky='EWNS')
pc.grid(column=1, row=1, sticky='EWNS', columnspan=2)
self.mainWindow.patternCanvas = pc
def setEmuButtonStopped(self):
@ -97,7 +107,7 @@ class Gui:
def setEmuButtonStarted(self):
b = self.emuButton
b.caption.set(u"Stop emulator...")
b.caption.set(u"...stop emulator")
class ExtendedCanvas(Tkinter.Canvas):

View file

@ -7,7 +7,9 @@ from app.gui.Gui import Gui
from PDDemulate import PDDemulator
from PDDemulate import PDDEmulatorListener
from dumppattern import PatternDumper
from insertpattern import PatternInserter
import Tkinter
import tkFileDialog
class KnittingApp(Tkinter.Tk):
@ -23,10 +25,10 @@ class KnittingApp(Tkinter.Tk):
self.pattern = None
self._cfg = None
self.currentDatFile = None
self.patternDumper = PatternDumper()
self.patternDumper.printInfoCallback = self.msg.showInfo
self.initializeUtilities()
self.gui = Gui()
self.gui.initializeMainWindow(self)
self.updatePatternCanvasLastSize()
self.patternListBox.bind('<<ListboxSelect>>', self.patternSelected)
self.after_idle(self.canvasConfigured)
self.deviceEntry.entryText.set(self.getConfig().device)
@ -34,6 +36,13 @@ class KnittingApp(Tkinter.Tk):
self.initEmulator()
self.after_idle(self.reloadPatternFile)
def initializeUtilities(self):
self.patternDumper = PatternDumper()
self.patternDumper.printInfoCallback = self.msg.showInfo
self.patternInserter = PatternInserter()
self.patternInserter.printInfoCallback = self.msg.showInfo
self.patternInserter.printErrorCallback = self.msg.showError
def initEmulator(self):
self.emu = PDDemulator(self.getConfig().imgdir)
self.emu.listeners.append(PDDListener(self))
@ -101,6 +110,9 @@ class KnittingApp(Tkinter.Tk):
def reloadPatternFile(self, pathToFile = None):
if not pathToFile:
pathToFile = self.datFileEntry.entryText.get()
else:
self.datFileEntry.entryText.set(pathToFile)
if not pathToFile:
return
self.currentDatFile = pathToFile
@ -120,14 +132,29 @@ class KnittingApp(Tkinter.Tk):
except IOError as e:
self.msg.showError('Could not open pattern file %s' % pathToFile + '\n' + str(e))
def helpButtonClicked(self):
helpMsg = '''Commands to execute on Knitting machine:
552: Download patterns from machine to computer
551: Upload patterns from computer to machine
'''
self.msg.showMoreInfo(helpMsg)
def reloadDatFileButtonClicked(self):
self.reloadPatternFile()
def chooseDatFileButtonClicked(self):
filePath = tkFileDialog.askopenfilename(filetypes=[('DAT file', '*.dat')], initialfile=self.datFileEntry.entryText.get(),
title='Choose dat file with patterns...')
if len(filePath) > 0:
self.msg.showInfo('Opened dat file ' + filePath)
self.reloadPatternFile(filePath)
def patternSelected(self, evt):
w = evt.widget
sel = w.curselection()
if len(sel) > 0:
index = int(w.curselection()[0])
index = int(sel[0])
pattern = self.patterns[index]
else:
pattern = None
@ -161,11 +188,34 @@ class KnittingApp(Tkinter.Tk):
if(pattern[row][stitch]) == 0:
self.patternCanvas.create_rectangle(stitch * bitWidth,row * bitHeight,(stitch+1) * bitWidth,(row+1) * bitHeight, width=0, fill='black')
def updatePatternCanvasLastSize(self):
self.patternCanvas.lastWidth = self.patternCanvas.getWidth()
self.patternCanvas.lastHeight = self.patternCanvas.getHeight()
def canvasConfigured(self):
self.msg.displayMessages = False
self.displayPattern()
self.msg.displayMessages = True
if self.patternCanvas.lastWidth != self.patternCanvas.getWidth() or self.patternCanvas.lastHeight != self.patternCanvas.getHeight():
self.msg.displayMessages = False
self.updatePatternCanvasLastSize()
self.displayPattern()
self.msg.displayMessages = True
self.after(100, self.canvasConfigured)
def insertBitmapButtonClicked(self):
sel = self.patternListBox.curselection()
if len(sel) == 0:
self.msg.showError('Target pattern for insertion must be selected!')
return
index = int(sel[0])
pattern = self.patterns[index]
filePath = tkFileDialog.askopenfilename(filetypes=[('2-color Bitmap', '*.bmp')],
title='Choose bitmap file to insert...')
if len(filePath) > 0:
self.insertBitmap(filePath, pattern["number"])
def insertBitmap(self, bitmapFile, patternNumber):
self.msg.showInfo('Inserting dat file %s to pattern number %d' % (bitmapFile, patternNumber))
oldBrotherFile = self.currentDatFile
self.patternInserter.insertPattern(oldBrotherFile, patternNumber, bitmapFile, 'myfile.dat')
class PDDListener(PDDEmulatorListener):
@ -173,7 +223,6 @@ class PDDListener(PDDEmulatorListener):
self.app = app
def dataReceived(self, fullFilePath):
self.app.datFileEntry.entryText.set(fullFilePath)
self.reloadPatternFile(fullFilePath)

View file

@ -11,6 +11,12 @@ class Messages:
self.clear()
sys.stderr.write('Error: ' + str(msg) + '\n')
mb.showerror('Error:', str(msg))
def showMoreInfo(self, msg):
if self.displayMessages:
self.clear()
print msg
mb.showinfo('Info:',str(msg))
def showInfo(self, msg):
if self.displayMessages:

View file

@ -24,6 +24,8 @@ import array
TheImage = None
version = '1.0'
##################
def roundeven(val):
@ -57,149 +59,183 @@ def bytesForMemo(rows):
##############
class PatternInserter:
def __init__(self):
self.printInfoCallback = self.printInfo
self.printErrorCallback = self.printError
self.printPatternCallback = self.printPattern
def printInfo(self, printMsg):
print printMsg
version = '1.0'
def printError(self, printMsg):
print printMsg
if len(sys.argv) < 5:
print 'Usage: %s oldbrotherfile pattern# image.bmp newbrotherfile' % sys.argv[0]
sys.exit()
def printPattern(self, printMsg):
sys.stdout.write(printMsg)
def insertPattern(self, oldbrotherfile, pattnum, imgfile, newbrotherfile):
bf = brother.brotherFile(sys.argv[1])
pattnum = sys.argv[2]
imgfile = sys.argv[3]
bf = brother.brotherFile(oldbrotherfile)
pats = bf.getPatterns()
pats = bf.getPatterns()
# ok got a bank, now lets figure out how big this thing we want to insert is
TheImage = Image.open(imgfile)
TheImage.load()
# ok got a bank, now lets figure out how big this thing we want to insert is
TheImage = Image.open(imgfile)
TheImage.load()
im_size = TheImage.size
width = im_size[0]
print "width:",width
height = im_size[1]
print "height:", height
im_size = TheImage.size
width = im_size[0]
self.printInfoCallback( "width:" + str(width))
height = im_size[1]
self.printInfoCallback( "height:" + str(height))
# find the program entry
thePattern = None
# find the program entry
thePattern = None
for pat in pats:
if (int(pat["number"]) == int(pattnum)):
#print "found it!"
thePattern = pat
if (thePattern == None):
print "Pattern #",pattnum,"not found!"
exit(0)
for pat in pats:
if (int(pat["number"]) == int(pattnum)):
#print "found it!"
thePattern = pat
if (thePattern == None):
raise PatternNotFoundException(pattnum)
if (height != thePattern["rows"] or width != thePattern["stitches"]):
print "Pattern is the wrong size, the BMP is ",height,"x",width,"and the pattern is ",thePattern["rows"], "x", thePattern["stitches"]
exit(0)
if (height != thePattern["rows"] or width != thePattern["stitches"]):
raise InserterException("Pattern is the wrong size, the BMP is ",height,"x",width,"and the pattern is ",thePattern["rows"], "x", thePattern["stitches"])
# debugging stuff here
x = 0
y = 0
# debugging stuff here
x = 0
y = 0
x = width - 1
while x > 0:
value = TheImage.getpixel((x,y))
if value:
sys.stdout.write('* ')
else:
sys.stdout.write(' ')
#sys.stdout.write(str(value))
x = x-1
if x == 0: #did we hit the end of the line?
y = y+1
x = width - 1
print " "
if y == height:
break
# debugging stuff done
while x > 0:
value = TheImage.getpixel((x,y))
if value:
self.printPattern('* ')
else:
self.printPattern(' ')
#sys.stdout.write(str(value))
x = x-1
if x == 0: #did we hit the end of the line?
y = y+1
x = width - 1
print " "
if y == height:
break
# debugging stuff done
# now to make the actual, yknow memo+pattern data
# now to make the actual, yknow memo+pattern data
# the memo seems to be always blank. i have no idea really
memoentry = []
for i in range(bytesForMemo(height)):
memoentry.append(0x0)
# the memo seems to be always blank. i have no idea really
memoentry = []
for i in range(bytesForMemo(height)):
memoentry.append(0x0)
# now for actual real live pattern data!
pattmemnibs = []
for r in range(height):
row = [] # we'll chunk in bits and then put em into nibbles
for s in range(width):
value = TheImage.getpixel((width-s-1,height-r-1))
if (value != 0):
row.append(1)
else:
row.append(0)
#print row
# turn it into nibz
for s in range(roundfour(width) / 4):
n = 0
for nibs in range(4):
#print "row size = ", len(row), "index = ",s*4+nibs
# now for actual real live pattern data!
pattmemnibs = []
for r in range(height):
row = [] # we'll chunk in bits and then put em into nibbles
for s in range(width):
value = TheImage.getpixel((width-s-1,height-r-1))
if (value != 0):
row.append(1)
else:
row.append(0)
#print row
# turn it into nibz
for s in range(roundfour(width) / 4):
n = 0
for nibs in range(4):
#print "row size = ", len(row), "index = ",s*4+nibs
if (len(row) == (s*4+nibs)):
break # padding!
if (len(row) == (s*4+nibs)):
break # padding!
if (row[s*4 + nibs]):
n |= 1 << nibs
pattmemnibs.append(n)
#print hex(n),
if (len(pattmemnibs) % 2):
# odd nibbles, buffer to a byte
pattmemnibs.append(0x0)
#print len(pattmemnibs), "nibbles of data"
# turn into bytes
pattmem = []
for i in range (len(pattmemnibs) / 2):
pattmem.append( pattmemnibs[i*2] | (pattmemnibs[i*2 + 1] << 4))
#print map(hex, pattmem)
# whew.
# now to insert this data into the file
# now we have to figure out the -end- of the last pattern is
endaddr = 0x6df
beginaddr = thePattern["pattend"]
endaddr = beginaddr + bytesForMemo(height) + len(pattmem)
self.printInfoCallback("beginning will be at " + str(hex(beginaddr)) + ", end at " + str(hex(endaddr)))
# Note - It's note certain that in all cases this collision test is needed. What's happening
# when you write below this address (as the pattern grows downward in memory) in that you begin
# to overwrite the pattern index data that starts at low memory. Since you overwrite the info
# for highest memory numbers first, you may be able to get away with it as long as you don't
# attempt to use higher memories.
# Steve
if beginaddr <= 0x2B8:
self.printErrorCallback("Sorry, this will collide with the pattern entry data since %s is <= 0x2B8!" % hex(beginaddr))
#exit
# write the memo and pattern entry from the -end- to the -beginning- (up!)
for i in range(len(memoentry)):
bf.setIndexedByte(endaddr, 0)
endaddr -= 1
for i in range(len(pattmem)):
bf.setIndexedByte(endaddr, pattmem[i])
endaddr -= 1
# push the data to a file
outfile = open(newbrotherfile, 'wb')
d = bf.getFullData()
outfile.write(d)
outfile.close()
class InserterException(Exception):
def getMessage(self):
msg = ''
for arg in self.args:
if msg != '':
msg += ' '
msg += str(arg)
if (row[s*4 + nibs]):
n |= 1 << nibs
pattmemnibs.append(n)
#print hex(n),
return msg
class PatternNotFoundException(InserterException):
def __init__(self, patternNumber):
self.patternNumber = patternNumber
if (len(pattmemnibs) % 2):
# odd nibbles, buffer to a byte
pattmemnibs.append(0x0)
#print len(pattmemnibs), "nibbles of data"
# turn into bytes
pattmem = []
for i in range (len(pattmemnibs) / 2):
pattmem.append( pattmemnibs[i*2] | (pattmemnibs[i*2 + 1] << 4))
#print map(hex, pattmem)
# whew.
# now to insert this data into the file
# now we have to figure out the -end- of the last pattern is
endaddr = 0x6df
beginaddr = thePattern["pattend"]
endaddr = beginaddr + bytesForMemo(height) + len(pattmem)
print "beginning will be at ", hex(beginaddr), "end at", hex(endaddr)
# Note - It's note certain that in all cases this collision test is needed. What's happening
# when you write below this address (as the pattern grows downward in memory) in that you begin
# to overwrite the pattern index data that starts at low memory. Since you overwrite the info
# for highest memory numbers first, you may be able to get away with it as long as you don't
# attempt to use higher memories.
# Steve
if beginaddr <= 0x2B8:
print "sorry, this will collide with the pattern entry data since %s is <= 0x2B8!" % hex(beginaddr)
#exit
# write the memo and pattern entry from the -end- to the -beginning- (up!)
for i in range(len(memoentry)):
bf.setIndexedByte(endaddr, 0)
endaddr -= 1
for i in range(len(pattmem)):
bf.setIndexedByte(endaddr, pattmem[i])
endaddr -= 1
# push the data to a file
outfile = open(sys.argv[4], 'wb')
d = bf.getFullData()
outfile.write(d)
outfile.close()
if __name__ == "__main__":
if len(sys.argv) < 5:
print 'Usage: %s oldbrotherfile pattern# image.bmp newbrotherfile' % sys.argv[0]
sys.exit()
inserter = PatternInserter()
argv = sys.argv
try:
inserter.insertPattern(argv[1],argv[2],argv[3],argv[4])
except PatternNotFoundException as e:
print 'ERROR: Pattern %d not found' % e.patternNumber
sys.exit(1)
except InserterException as e:
print 'ERROR: ',e.getMessage()
sys.exit(1)