Inserting bitmap
This commit is contained in:
parent
52917bc546
commit
d4bb8dd23f
4 changed files with 237 additions and 136 deletions
|
|
@ -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):
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
284
insertpattern.py
284
insertpattern.py
|
|
@ -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)
|
||||
|
|
|
|||
Loading…
Reference in a new issue