class ReaderController(NSWindowController): # IB Outlets cameraView = IBOutlet() codeView = IBOutlet() resetButton = IBOutlet() msgLabel = IBOutlet() def awakeFromNib(self): self.red_color = NSColor.colorWithCalibratedRed_green_blue_alpha_(0.8, 0.3, 0.3, 1.0) self.green_color = NSColor.colorWithCalibratedRed_green_blue_alpha_(0.2, 0.6, 0.2, 1.0) self.blue_color = NSColor.colorWithCalibratedRed_green_blue_alpha_(0.1, 0.3, 0.7, 1.0) self.white_color = NSColor.colorWithCalibratedRed_green_blue_alpha_(0.0, 0.0, 0.0, 1.0) self.reader = Reader() self.code = None self.scanning = True transform = NSAffineTransform.transform() transform.scaleXBy_yBy_(-1.0, 1.0) self.flipFilter = CIFilter.filterWithName_("CIAffineTransform") self.flipFilter.setValue_forKey_(transform, "inputTransform") self.isight = PySight.ISight.alloc().init() session = self.isight.start() self.cameraView.setCaptureSession_(session) self.cameraView.setDelegate_(self) self.codeView.setString_("Initializing...") self.codeView.setTextColor_(self.white_color) self.msgLabel.setHidden_(True) window = self.window() window.setAspectRatio_(window.frame().size) self.showWindow_(None) self.thread = NSThread.alloc().initWithTarget_selector_object_(self,self.updateLoop, None) self.thread.start() def copyCode(self, code): if code is not None: pb = NSPasteboard.generalPasteboard() types = [NSStringPboardType] pb.declareTypes_owner_(types, self) pb.setString_forType_(code, NSStringPboardType) def nsimage2pil(self, image): rep = image.representations().objectAtIndex_(0) data = rep.bitmapData() im = Image.fromstring("RGBA", (int(image.size().width), int(image.size().height)), data) return im # IB Action resetClicked: def resetClicked_(self, e): self.msgLabel.setHidden_(True) self.reader.reset() self.scanning = True def displayDoneState(self): strcode = str(self.code) self.codeView.setString_(strcode) self.codeView.setTextColor_(self.green_color) self.resetButton.setEnabled_(True) self.copyCode(strcode) self.msgLabel.setStringValue_("Code copied") self.msgLabel.setHidden_(False) def displayReadingState(self): code = self.code strcode = str(code) self.codeView.setString_(strcode) self.codeView.setTextColor_(self.white_color) self.resetButton.setEnabled_(True) pos = code.get_active_positions() i = 0 while i < len(strcode): l = 1 if i in pos: while i + l < len(strcode) and i + l in pos: l += 1 self.codeView.setTextColor_range_(self.blue_color, NSMakeRange(i, l)) elif strcode[i] == 'x': while i + l < len(strcode) and strcode[i + l] == 'x': l += 1 self.codeView.setTextColor_range_(self.red_color, NSMakeRange(i, l)) i += l def displayErrorState(self, message): strcode = str(self.code) self.codeView.setString_(strcode) self.codeView.setTextColor_(self.red_color) self.resetButton.setEnabled_(True) self.msgLabel.setStringValue_(message) self.msgLabel.setHidden_(False) def updateLoop(self): while True: loopPool = NSAutoreleasePool.alloc().init() if self.scanning: frame = self.isight.consumeFrame() reschedule = True if frame: frame.retain() self.code = self.reader.process(self.nsimage2pil(frame)) (result, message) = self.code.check() strcode = str(self.code) if result == 0: self.performSelectorOnMainThread_withObject_waitUntilDone_(self.displayDoneState, None, True) self.scanning = False elif result == 1: self.performSelectorOnMainThread_withObject_waitUntilDone_(self.displayReadingState, None, True) else: self.performSelectorOnMainThread_withObject_waitUntilDone_(self.displayErrorState, message, True) self.scanning = False frame.release() del loopPool NSThread.sleepForTimeInterval_(0.3) # QTCaptureView delegate def view_willDisplayImage_(self, view, image): self.flipFilter.setValue_forKey_(image, "inputImage") image.release() # why oh why? return self.flipFilter.valueForKey_("outputImage") # NSWindow delegate def windowWillClose_(self, notification): self.isight.stop()