class Editor: def __init__(self, pixbuf, ocr_engines, reviewer): self.configuration_manager = ConfigurationManager() self.pixbuf = pixbuf self.data_box = None self.box = None self.__connected_signal_handles_list = [] self.box_editor = BoxEditor(pixbuf.get_width(), pixbuf.get_height()) self.box_editor.connect('text-edited-by-user', self.checkHasText) self.reviewer = reviewer self.ocr_engines = ocr_engines self.updateOcrEngines(self.ocr_engines) self.box_editor.x_spin_button.connect('value-changed', self.__updateBoxX) self.box_editor.y_spin_button.connect('value-changed', self.__updateBoxY) self.box_editor.width_spin_button.connect('value-changed', self.__updateBoxWidth) self.box_editor.height_spin_button.connect('value-changed', self.__updateBoxHeight) self.box_editor.make_text_button.connect('toggled', self.__pressedTextContextButton) self.box_editor.make_image_button.connect('toggled', self.__pressedImageContextButton) self.box_editor.perform_ocr_button.connect('clicked', self.__pressedPerformOcrButton) self.box_editor.detect_angle_button.connect('clicked', self.__pressedAngleDetectionButton) self.box_editor.font_button.connect('font-set', self.__setDataBoxFont) self.box_editor.align_left_button.connect('toggled', self.__setDataBoxAlign, ALIGN_LEFT) self.box_editor.align_right_button.connect('toggled', self.__setDataBoxAlign, ALIGN_RIGHT) self.box_editor.align_center_button.connect('toggled', self.__setDataBoxAlign, ALIGN_CENTER) self.box_editor.align_fill_button.connect('toggled', self.__setDataBoxAlign, ALIGN_FILL) self.box_editor.letter_spacing_spin.connect('value-changed', self.__setDataBoxLetterSpacing) self.box_editor.line_spacing_spin.connect('value-changed', self.__setDataBoxLineSpacing) self.box_editor.ocr_combo_box.connect('changed', self._onOCREngineChanged) self.box_editor.languages_combo.connect('changed', self._onLanguageChanged) self.box_editor.hide() def __updateBoxX(self, spin_button): if self.__updating_data_box: return self.box.set_property('x', self.box_editor.getX()) if spin_button.is_focus(): self.update(self.box) def __updateBoxY(self, spin_button): if self.__updating_data_box: return self.box.set_property('y', self.box_editor.getY()) if spin_button.is_focus(): self.update(self.box) def __updateBoxWidth(self, spin_button): if self.__updating_data_box: return self.box.set_property('width', self.box_editor.getWidth()) if spin_button.is_focus(): self.update(self.box) def __updateBoxHeight(self, spin_button): if self.__updating_data_box: return self.box.set_property('height', self.box_editor.getHeight()) if spin_button.is_focus(): self.update(self.box) def __updateEditorX(self, widget, new_x): self.box_editor.setXRange() self.box_editor.setX(new_x) def __updateEditorY(self, widget, new_y): self.box_editor.setY(new_y) def __updateEditorWidth(self, widget, new_width): self.box_editor.setWidth(new_width) def __updateEditorHeight(self, widget, new_height): self.box_editor.setHeight(new_height) def __updateEditorImage(self, widget, new_image): self.box_editor.displayImage(new_image) def __updateBoxColor(self, widget, type): self.updateBoxColor(type) def updateBoxColor(self, type = None): if not self.box: return type = type or self.data_box.getType() fill_color = graphics.rgbaToInteger(self.reviewer.image_box_fill_color) if type == TEXT_TYPE: fill_color = graphics.rgbaToInteger(self.reviewer.text_box_fill_color) self.box.set_property('fill-color-rgba', fill_color) def __setDataBoxFont(self, font_button = None): font_button = font_button or self.box_editor.font_button font_description = Pango.FontDescription(font_button.get_font_name()) self.data_box.setFontFace(font_description.get_family()) self.data_box.setFontSize(font_description.get_size() / Pango.SCALE) self.data_box.setFontStyle(font_description.get_style()) self.data_box.setFontWeight(font_description.get_weight()) def __setDataBoxAlign(self, align_button, align_option): if align_button.get_active(): self.data_box.setTextAlign(align_option) def __setDataBoxLetterSpacing(self, letter_spacing_button = None): letter_spacing_button = letter_spacing_button or self.box_editor.letter_spacing_spin self.data_box.setLetterSpacing(letter_spacing_button.get_value()) def __setDataBoxLineSpacing(self, line_spacing_button = None): line_spacing_button = line_spacing_button or self.box_editor.line_spacing_spin self.data_box.setLineSpacing(line_spacing_button.get_value()) def __setDataBoxLanguage(self, language = ''): language = language or self.box_editor.getLanguage() self.data_box.setLanguage(language) def _resetLanguages(self): index = self.box_editor.getSelectedOcrEngine() if index == -1: return engine = self.ocr_engines[index][0] self.box_editor.setAvailableLanguages(engine.getLanguages().keys()) def _onOCREngineChanged(self, combobox): self._resetLanguages() def _onLanguageChanged(self, combobox): if self.data_box: self.data_box.setLanguage(self.box_editor.getLanguage()) def update(self, box): self.data_box.updateBoundsFromBox(self.box) self.data_box.updateImage(self.pixbuf) def updateOcrEngines(self, engines_list): engines_names = [engine.name for engine, path in engines_list] self.box_editor.setOcrEngines(engines_names) self._resetLanguages() def __pressedImageContextButton(self, toggle_button): self.data_box.setType(IMAGE_TYPE) self.box_editor.setOcrPropertiesSensibility(False) def __pressedTextContextButton(self, toggle_button): self.data_box.setType(TEXT_TYPE) self.box_editor.setOcrPropertiesSensibility(True) def __pressedPerformOcrButton(self, button): self.performOcr() def performOcr(self, engine_name = None): selected_engine_index = self.box_editor.getSelectedOcrEngine() if engine_name: for i in xrange(len(self.ocr_engines)): if self.ocr_engines[i][0].name == engine_name: selected_engine_index = i break self.box_editor.selectOcrEngine(selected_engine_index) image = graphics.convertPixbufToImage(self.box_editor.getImage()) angle = self.box_editor.getAngle() if angle: image = graphics.getImageRotated(image, angle) engine = None if selected_engine_index != -1: engine = self.ocr_engines[selected_engine_index][0] self.reviewer.performOcrForDataBox(self.data_box, engine) self.updateDataBox(self.data_box) def performClassification(self, engine_name = None): selected_engine_index = self.box_editor.getSelectedOcrEngine() if engine_name: for i in xrange(len(self.ocr_engines)): if self.ocr_engines[i][0].name == engine_name: selected_engine_index = i break if selected_engine_index != None: engine = self.ocr_engines[selected_engine_index][0] type = engine.classify(self.box_editor.getText()) self.box_editor.setType(type) def __pressedAngleDetectionButton(self, widget): image = graphics.convertPixbufToImage(self.box_editor.getImage()) angle = graphics.getHorizontalAngleForText(image) debug('ANGLE: ', angle) self.box_editor.setAngle(angle) def saveDataBox(self): if not self.data_box: return text = self.box_editor.getText() self.data_box.setText(text) angle = self.box_editor.getAngle() self.data_box.setAngle(angle) self.__setDataBoxFont() self.__setDataBoxLetterSpacing() self.__setDataBoxLineSpacing() self.__setDataBoxLanguage() def updateDataBox(self, data_box): self.__updating_data_box = True self.__disconnectDataBoxSignals() self.data_box = data_box if data_box is None: self.box_editor.hide() return self.box_editor.setX(self.data_box.x) self.box_editor.setY(self.data_box.y) self.box_editor.setWidth(self.data_box.width) self.box_editor.setHeight(self.data_box.height) self.box_editor.setType(self.data_box.type) self.box_editor.setText(self.data_box.text) self.box_editor.setFontSize(self.data_box.text_data.size) self.box_editor.setLineSpacing(self.data_box.getLineSpacing()) self.box_editor.setLetterSpacing(self.data_box.getLetterSpacing()) self.box_editor.setLanguage(self.data_box.getLanguage()) self.__updating_data_box = False self.__connectDataBoxSignals() self.__updateBoxColor(None, self.data_box.type) def __connectDataBoxSignals(self): handler_id = self.data_box.connect('changed_x', self.__updateEditorX) self.__connected_signal_handles_list.append(handler_id) handler_id = self.data_box.connect('changed_y', self.__updateEditorY) self.__connected_signal_handles_list.append(handler_id) handler_id = self.data_box.connect('changed_width', self.__updateEditorWidth) self.__connected_signal_handles_list.append(handler_id) handler_id = self.data_box.connect('changed_height', self.__updateEditorHeight) self.__connected_signal_handles_list.append(handler_id) handler_id = self.data_box.connect('changed_image', self.__updateEditorImage) self.__connected_signal_handles_list.append(handler_id) handler_id = self.data_box.connect('changed_type', self.__updateBoxColor) def setBoxes(self, box, data_box): self.saveDataBox() self.box = box self.updateDataBox(data_box) self.update(box) self.box_editor.show() def __disconnectDataBoxSignals(self): if not self.data_box: return for handle_id in self.__connected_signal_handles_list: self.data_box.disconnect(handle_id) self.__connected_signal_handles_list = [] def checkHasText(self, widget, text): if not text: self.reviewer.main_window.copy_to_clipboard_menu.set_sensitive(False) self.reviewer.main_window.spellchecker_menu.set_sensitive(False) else: self.reviewer.main_window.copy_to_clipboard_menu.set_sensitive(True) self.reviewer.main_window.spellchecker_menu.set_sensitive(True)
class Editor: def __init__(self, pixbuf, ocr_engines, reviewer): self.configuration_manager = ConfigurationManager() self.pixbuf = pixbuf self.data_box = None self.box = None self.__connected_signal_handles_list = [] self.box_editor = BoxEditor(pixbuf.get_width(), pixbuf.get_height()) self.box_editor.connect('text-edited-by-user', self.checkHasText) self.reviewer = reviewer self.ocr_engines = ocr_engines self.updateOcrEngines(self.ocr_engines) self.box_editor.x_spin_button.connect('value-changed', self.__updateBoxX) self.box_editor.y_spin_button.connect('value-changed', self.__updateBoxY) self.box_editor.width_spin_button.connect('value-changed', self.__updateBoxWidth) self.box_editor.height_spin_button.connect('value-changed', self.__updateBoxHeight) self.box_editor.make_text_button.connect( 'toggled', self.__pressedTextContextButton) self.box_editor.make_image_button.connect( 'toggled', self.__pressedImageContextButton) self.box_editor.perform_ocr_button.connect( 'clicked', self.__pressedPerformOcrButton) self.box_editor.detect_angle_button.connect( 'clicked', self.__pressedAngleDetectionButton) self.box_editor.font_button.connect('font-set', self.__setDataBoxFont) self.box_editor.align_left_button.connect('toggled', self.__setDataBoxAlign, ALIGN_LEFT) self.box_editor.align_right_button.connect('toggled', self.__setDataBoxAlign, ALIGN_RIGHT) self.box_editor.align_center_button.connect('toggled', self.__setDataBoxAlign, ALIGN_CENTER) self.box_editor.align_fill_button.connect('toggled', self.__setDataBoxAlign, ALIGN_FILL) self.box_editor.letter_spacing_spin.connect( 'value-changed', self.__setDataBoxLetterSpacing) self.box_editor.line_spacing_spin.connect('value-changed', self.__setDataBoxLineSpacing) self.box_editor.hide() def __updateBoxX(self, spin_button): if self.__updating_data_box: return self.box.set_property('x', self.box_editor.getX()) if spin_button.is_focus(): self.update(self.box) def __updateBoxY(self, spin_button): if self.__updating_data_box: return self.box.set_property('y', self.box_editor.getY()) if spin_button.is_focus(): self.update(self.box) def __updateBoxWidth(self, spin_button): if self.__updating_data_box: return self.box.set_property('width', self.box_editor.getWidth()) if spin_button.is_focus(): self.update(self.box) def __updateBoxHeight(self, spin_button): if self.__updating_data_box: return self.box.set_property('height', self.box_editor.getHeight()) if spin_button.is_focus(): self.update(self.box) def __updateEditorX(self, widget, new_x): self.box_editor.setXRange() self.box_editor.setX(new_x) def __updateEditorY(self, widget, new_y): self.box_editor.setY(new_y) def __updateEditorWidth(self, widget, new_width): self.box_editor.setWidth(new_width) def __updateEditorHeight(self, widget, new_height): self.box_editor.setHeight(new_height) def __updateEditorImage(self, widget, new_image): self.box_editor.displayImage(new_image) def __updateBoxColor(self, widget, type): self.updateBoxColor(type) def updateBoxColor(self, type=None): if not self.box: return type = type or self.data_box.getType() fill_color = graphics.rgbaToInteger(self.reviewer.image_box_fill_color) if type == TEXT_TYPE: fill_color = graphics.rgbaToInteger( self.reviewer.text_box_fill_color) self.box.set_property('fill-color-rgba', fill_color) def __setDataBoxFont(self, font_button=None): font_button = font_button or self.box_editor.font_button font_description = FontDescription(font_button.get_font_name()) self.data_box.setFontFace(font_description.get_family()) self.data_box.setFontSize(font_description.get_size() / SCALE) self.data_box.setFontStyle(font_description.get_style()) self.data_box.setFontWeight(font_description.get_weight()) def __setDataBoxAlign(self, align_button, align_option): if align_button.get_active(): self.data_box.setTextAlign(align_option) def __setDataBoxLetterSpacing(self, letter_spacing_button=None): letter_spacing_button = letter_spacing_button or self.box_editor.letter_spacing_spin self.data_box.setLetterSpacing(letter_spacing_button.get_value()) def __setDataBoxLineSpacing(self, line_spacing_button=None): line_spacing_button = line_spacing_button or self.box_editor.line_spacing_spin self.data_box.setLineSpacing(line_spacing_button.get_value()) def update(self, box): self.box = box x, y, width, height = self.data_box.updateBoundsFromBox(self.box) pixbuf_width = self.pixbuf.get_width() pixbuf_height = self.pixbuf.get_height() sub_pixbuf = self.pixbuf.subpixbuf(x, y, min(width, pixbuf_width), min(height, pixbuf_height)) self.data_box.setImage(sub_pixbuf) def updateOcrEngines(self, engines_list): engines_names = [engine.name for engine, path in engines_list] self.box_editor.setOcrEngines(engines_names) def __pressedImageContextButton(self, toggle_button): self.data_box.setType(IMAGE_TYPE) self.box_editor.setOcrPropertiesSensibility(False) def __pressedTextContextButton(self, toggle_button): self.data_box.setType(TEXT_TYPE) self.box_editor.setOcrPropertiesSensibility(True) def __pressedPerformOcrButton(self, button): self.performOcr() def performOcr(self, engine_name=None): selected_engine_index = self.box_editor.getSelectedOcrEngine() if engine_name: for i in xrange(len(self.ocr_engines)): if self.ocr_engines[i][0].name == engine_name: selected_engine_index = i break self.box_editor.selectOcrEngine(selected_engine_index) image = graphics.convertPixbufToImage(self.box_editor.getImage()) angle = self.box_editor.getAngle() if angle: image = graphics.getImageRotated(image, angle) engine = None if selected_engine_index != -1: engine = self.ocr_engines[selected_engine_index][0] self.reviewer.performOcrForDataBox(self.data_box, engine) self.updateDataBox(self.data_box) def performClassification(self, engine_name=None): selected_engine_index = self.box_editor.getSelectedOcrEngine() if engine_name: for i in xrange(len(self.ocr_engines)): if self.ocr_engines[i][0].name == engine_name: selected_engine_index = i break if selected_engine_index != None: engine = self.ocr_engines[selected_engine_index][0] type = engine.classify(self.box_editor.getText()) self.box_editor.setType(type) def __pressedAngleDetectionButton(self, widget): image = graphics.convertPixbufToImage(self.box_editor.getImage()) angle = graphics.getHorizontalAngleForText(image) debug('ANGLE: ', angle) self.box_editor.setAngle(angle) def saveDataBox(self): if not self.data_box: return text = self.box_editor.getText() self.data_box.setText(text) angle = self.box_editor.getAngle() self.data_box.setAngle(angle) self.__setDataBoxFont() self.__setDataBoxLetterSpacing() self.__setDataBoxLineSpacing() def updateDataBox(self, data_box): self.__updating_data_box = True self.__disconnectDataBoxSignals() self.data_box = data_box if data_box is None: self.box_editor.hide() return self.box_editor.setX(self.data_box.x) self.box_editor.setY(self.data_box.y) self.box_editor.setWidth(self.data_box.width) self.box_editor.setHeight(self.data_box.height) self.box_editor.setType(self.data_box.type) self.box_editor.setText(self.data_box.text) self.box_editor.setFontSize(self.data_box.text_data.size) self.box_editor.setLineSpacing(self.data_box.getLineSpacing()) self.box_editor.setLetterSpacing(self.data_box.getLetterSpacing()) self.__updating_data_box = False self.__connectDataBoxSignals() self.__updateBoxColor(None, self.data_box.type) def __connectDataBoxSignals(self): handler_id = self.data_box.connect('changed_x', self.__updateEditorX) self.__connected_signal_handles_list.append(handler_id) handler_id = self.data_box.connect('changed_y', self.__updateEditorY) self.__connected_signal_handles_list.append(handler_id) handler_id = self.data_box.connect('changed_width', self.__updateEditorWidth) self.__connected_signal_handles_list.append(handler_id) handler_id = self.data_box.connect('changed_height', self.__updateEditorHeight) self.__connected_signal_handles_list.append(handler_id) handler_id = self.data_box.connect('changed_image', self.__updateEditorImage) self.__connected_signal_handles_list.append(handler_id) handler_id = self.data_box.connect('changed_type', self.__updateBoxColor) def setBoxes(self, box, data_box): self.saveDataBox() self.box = box self.updateDataBox(data_box) self.update(box) self.box_editor.show() def __disconnectDataBoxSignals(self): if not self.data_box: return for handle_id in self.__connected_signal_handles_list: self.data_box.disconnect(handle_id) self.__connected_signal_handles_list = [] def checkHasText(self, widget, text): if not text: self.reviewer.main_window.copy_to_clipboard_menu.set_sensitive( False) self.reviewer.main_window.spellchecker_menu.set_sensitive(False) else: self.reviewer.main_window.copy_to_clipboard_menu.set_sensitive( True) self.reviewer.main_window.spellchecker_menu.set_sensitive(True)
class Editor: def __init__(self, box, pixbuf, ocr_engines, reviewer): self.pixbuf = pixbuf self.data_box = DataBox() self.box_editor = BoxEditor(pixbuf.get_width(), pixbuf.get_height()) self.reviewer = reviewer self.ocr_engines = ocr_engines self.updateOcrEngines(self.ocr_engines) self.box_editor.x_spin_button.connect('value-changed', self.__updateBoxX) self.box_editor.y_spin_button.connect('value-changed', self.__updateBoxY) self.box_editor.width_spin_button.connect('value-changed', self.__updateBoxWidth) self.box_editor.height_spin_button.connect('value-changed', self.__updateBoxHeight) self.box_editor.make_text_button.connect( 'toggled', self.__pressedTextContextButton) self.box_editor.make_image_button.connect( 'toggled', self.__pressedImageContextButton) self.box_editor.perform_ocr_button.connect( 'clicked', self.__pressedPerformOcrButton) self.box_editor.detect_angle_button.connect( 'clicked', self.__pressedAngleDetectionButton) self.box_editor.font_button.connect('font-set', self.__setDataBoxFont) self.box_editor.align_left_button.connect('toggled', self.__setDataBoxAlign, ALIGN_LEFT) self.box_editor.align_right_button.connect('toggled', self.__setDataBoxAlign, ALIGN_RIGHT) self.box_editor.align_center_button.connect('toggled', self.__setDataBoxAlign, ALIGN_CENTER) self.box_editor.align_fill_button.connect('toggled', self.__setDataBoxAlign, ALIGN_FILL) self.box_editor.letter_spacing_spin.connect( 'value-changed', self.__setDataBoxLetterSpacing) self.box_editor.line_spacing_spin.connect('value-changed', self.__setDataBoxLineSpacing) self.__connectDataBoxSignals() self.update(box) def __updateBoxX(self, spin_button): self.box.set_property('x', self.box_editor.getX()) if spin_button.is_focus(): self.update(self.box) def __updateBoxY(self, spin_button): self.box.set_property('y', self.box_editor.getY()) if spin_button.is_focus(): self.update(self.box) def __updateBoxWidth(self, spin_button): self.box.set_property('width', self.box_editor.getWidth()) if spin_button.is_focus(): self.update(self.box) def __updateBoxHeight(self, spin_button): self.box.set_property('height', self.box_editor.getHeight()) if spin_button.is_focus(): self.update(self.box) def __updateEditorX(self, widget, new_x): self.box_editor.setXRange() self.box_editor.setX(new_x) def __updateEditorY(self, widget, new_y): self.box_editor.setY(new_y) def __updateEditorWidth(self, widget, new_width): self.box_editor.setWidth(new_width) def __updateEditorHeight(self, widget, new_height): self.box_editor.setHeight(new_height) def __updateEditorImage(self, widget, new_image): self.box_editor.displayImage(new_image) def __updateBoxColor(self, widget, type): self.updateBoxColor(type) def updateBoxColor(self, type=None): type = type or self.data_box.getType() fill_color = graphics.rgbaToInteger(self.reviewer.image_box_fill_color) stroke_color = graphics.rgbaToInteger( self.reviewer.image_box_stroke_color) if type == TEXT_TYPE: fill_color = graphics.rgbaToInteger( self.reviewer.text_box_fill_color) stroke_color = graphics.rgbaToInteger( self.reviewer.text_box_stroke_color) self.box.set_property('fill-color-rgba', fill_color) self.box.set_property('stroke-color-rgba', stroke_color) def __setDataBoxFont(self, font_button=None): font_button = font_button or self.box_editor.font_button font_description = FontDescription(font_button.get_font_name()) self.data_box.setFontFace(font_description.get_family()) self.data_box.setFontSize(font_description.get_size() / SCALE) self.data_box.setFontStyle(font_description.get_style()) self.data_box.setFontWeight(font_description.get_weight()) def __setDataBoxAlign(self, align_button, align_option): if align_button.get_active(): self.data_box.setTextAlign(align_option) def __setDataBoxLetterSpacing(self, letter_spacing_button=None): letter_spacing_button = letter_spacing_button or self.box_editor.letter_spacing_spin self.data_box.setLetterSpacing(letter_spacing_button.get_value()) def __setDataBoxLineSpacing(self, line_spacing_button=None): line_spacing_button = line_spacing_button or self.box_editor.line_spacing_spin self.data_box.setLineSpacing(line_spacing_button.get_value()) def update(self, box): self.box = box x, y, width, height = self.updateBounds(box) pixbuf_width = self.pixbuf.get_width() pixbuf_height = self.pixbuf.get_height() sub_pixbuf = self.pixbuf.subpixbuf(x, y, min(width, pixbuf_width), min(height, pixbuf_height)) self.data_box.setImage(sub_pixbuf) def updateBounds(self, box): self.box = box x, y, width, height = int(self.box.props.x), int(self.box.props.y), \ int(self.box.props.width), int(self.box.props.height) self.data_box.setX(x) self.data_box.setY(y) self.data_box.setWidth(width) self.data_box.setHeight(height) return (x, y, width, height) def updateOcrEngines(self, engines_list): engines_names = [engine.name for engine, path in engines_list] self.box_editor.setOcrEngines(engines_names) def __pressedImageContextButton(self, toggle_button): self.data_box.setType(IMAGE_TYPE) self.box_editor.setOcrPropertiesSensibility(False) def __pressedTextContextButton(self, toggle_button): self.data_box.setType(TEXT_TYPE) self.box_editor.setOcrPropertiesSensibility(True) def __pressedPerformOcrButton(self, button): self.performOcr() def performOcr(self, engine_name=None): selected_engine_index = self.box_editor.getSelectedOcrEngine() if engine_name: for i in xrange(len(self.ocr_engines)): if self.ocr_engines[i][0].name == engine_name: selected_engine_index = i break self.box_editor.selectOcrEngine(selected_engine_index) image = graphics.convertPixbufToImage(self.box_editor.getImage()) angle = self.box_editor.getAngle() if angle: image = graphics.getImageRotated(image, angle) if selected_engine_index != None: engine = self.ocr_engines[selected_engine_index][0] engine.setImage(image) text = engine.read() self.box_editor.setText(text) debug('Finished reading') text_size = graphics.getTextSizeFromImage(image) if text_size: y_resolution = float(self.reviewer.page.resolution[1]) text_size /= y_resolution text_size *= 72.0 self.box_editor.setFontSize(math.floor(text_size)) def performClassification(self, engine_name=None): selected_engine_index = self.box_editor.getSelectedOcrEngine() if engine_name: for i in xrange(len(self.ocr_engines)): if self.ocr_engines[i][0].name == engine_name: selected_engine_index = i break if selected_engine_index != None: engine = self.ocr_engines[selected_engine_index][0] type = engine.classify(self.box_editor.getText()) self.box_editor.setType(type) def __pressedAngleDetectionButton(self, widget): image = graphics.convertPixbufToImage(self.box_editor.getImage()) angle = graphics.getHorizontalAngleForText(image) debug('ANGLE: ', angle) self.box_editor.setAngle(angle) def setDataBox(self): text = self.box_editor.getText() self.data_box.setText(text) angle = self.box_editor.getAngle() self.data_box.setAngle(angle) self.__setDataBoxFont() self.__setDataBoxLetterSpacing() self.__setDataBoxLineSpacing() def updateDataBox(self, data_box): self.data_box = data_box self.box_editor.setX(self.data_box.x) self.box_editor.setY(self.data_box.y) self.box_editor.setWidth(self.data_box.width) self.box_editor.setHeight(self.data_box.height) self.box_editor.setType(self.data_box.type) self.box_editor.setText(self.data_box.text) self.__connectDataBoxSignals() self.__updateBoxColor(None, self.data_box.type) def __connectDataBoxSignals(self): self.data_box.connect('changed_x', self.__updateEditorX) self.data_box.connect('changed_y', self.__updateEditorY) self.data_box.connect('changed_width', self.__updateEditorWidth) self.data_box.connect('changed_height', self.__updateEditorHeight) self.data_box.connect('changed_image', self.__updateEditorImage) self.data_box.connect('changed_type', self.__updateBoxColor)
class Editor: def __init__(self, box, pixbuf, ocr_engines, reviewer): self.pixbuf = pixbuf self.data_box = DataBox() self.box_editor = BoxEditor(pixbuf.get_width(), pixbuf.get_height()) self.reviewer = reviewer self.ocr_engines = ocr_engines self.updateOcrEngines(self.ocr_engines) self.box_editor.x_spin_button.connect('value-changed', self.__updateBoxX) self.box_editor.y_spin_button.connect('value-changed', self.__updateBoxY) self.box_editor.width_spin_button.connect('value-changed', self.__updateBoxWidth) self.box_editor.height_spin_button.connect('value-changed', self.__updateBoxHeight) self.box_editor.make_text_button.connect('toggled', self.__pressedTextContextButton) self.box_editor.make_image_button.connect('toggled', self.__pressedImageContextButton) self.box_editor.perform_ocr_button.connect('clicked', self.__pressedPerformOcrButton) self.box_editor.detect_angle_button.connect('clicked', self.__pressedAngleDetectionButton) self.box_editor.font_button.connect('font-set', self.__setDataBoxFont) self.box_editor.align_left_button.connect('toggled', self.__setDataBoxAlign, ALIGN_LEFT) self.box_editor.align_right_button.connect('toggled', self.__setDataBoxAlign, ALIGN_RIGHT) self.box_editor.align_center_button.connect('toggled', self.__setDataBoxAlign, ALIGN_CENTER) self.box_editor.align_fill_button.connect('toggled', self.__setDataBoxAlign, ALIGN_FILL) self.box_editor.letter_spacing_spin.connect('value-changed', self.__setDataBoxLetterSpacing) self.box_editor.line_spacing_spin.connect('value-changed', self.__setDataBoxLineSpacing) self.__connectDataBoxSignals() self.update(box) def __updateBoxX(self, spin_button): self.box.set_property('x', self.box_editor.getX()) if spin_button.is_focus(): self.update(self.box) def __updateBoxY(self, spin_button): self.box.set_property('y', self.box_editor.getY()) if spin_button.is_focus(): self.update(self.box) def __updateBoxWidth(self, spin_button): self.box.set_property('width', self.box_editor.getWidth()) if spin_button.is_focus(): self.update(self.box) def __updateBoxHeight(self, spin_button): self.box.set_property('height', self.box_editor.getHeight()) if spin_button.is_focus(): self.update(self.box) def __updateEditorX(self, widget, new_x): self.box_editor.setXRange() self.box_editor.setX(new_x) def __updateEditorY(self, widget, new_y): self.box_editor.setY(new_y) def __updateEditorWidth(self, widget, new_width): self.box_editor.setWidth(new_width) def __updateEditorHeight(self, widget, new_height): self.box_editor.setHeight(new_height) def __updateEditorImage(self, widget, new_image): self.box_editor.displayImage(new_image) def __updateBoxColor(self, widget, type): self.updateBoxColor(type) def updateBoxColor(self, type = None): type = type or self.data_box.getType() fill_color = graphics.rgbaToInteger(self.reviewer.image_box_fill_color) stroke_color = graphics.rgbaToInteger(self.reviewer.image_box_stroke_color) if type == TEXT_TYPE: fill_color = graphics.rgbaToInteger(self.reviewer.text_box_fill_color) stroke_color = graphics.rgbaToInteger(self.reviewer.text_box_stroke_color) self.box.set_property('fill-color-rgba', fill_color) self.box.set_property('stroke-color-rgba', stroke_color) def __setDataBoxFont(self, font_button = None): font_button = font_button or self.box_editor.font_button font_description = FontDescription(font_button.get_font_name()) self.data_box.setFontFace(font_description.get_family()) self.data_box.setFontSize(font_description.get_size() / SCALE) self.data_box.setFontStyle(font_description.get_style()) self.data_box.setFontWeight(font_description.get_weight()) def __setDataBoxAlign(self, align_button, align_option): if align_button.get_active(): self.data_box.setTextAlign(align_option) def __setDataBoxLetterSpacing(self, letter_spacing_button = None): letter_spacing_button = letter_spacing_button or self.box_editor.letter_spacing_spin self.data_box.setLetterSpacing(letter_spacing_button.get_value()) def __setDataBoxLineSpacing(self, line_spacing_button = None): line_spacing_button = line_spacing_button or self.box_editor.line_spacing_spin self.data_box.setLineSpacing(line_spacing_button.get_value()) def update(self, box): self.box = box x, y, width, height = self.updateBounds(box) pixbuf_width = self.pixbuf.get_width() pixbuf_height = self.pixbuf.get_height() sub_pixbuf = self.pixbuf.subpixbuf(x, y, min(width, pixbuf_width), min(height, pixbuf_height)) self.data_box.setImage(sub_pixbuf) def updateBounds(self, box): self.box = box x, y, width, height = int(self.box.props.x), int(self.box.props.y), \ int(self.box.props.width), int(self.box.props.height) self.data_box.setX(x) self.data_box.setY(y) self.data_box.setWidth(width) self.data_box.setHeight(height) return (x, y, width, height) def updateOcrEngines(self, engines_list): engines_names = [engine.name for engine, path in engines_list] self.box_editor.setOcrEngines(engines_names) def __pressedImageContextButton(self, toggle_button): self.data_box.setType(IMAGE_TYPE) self.box_editor.setOcrPropertiesSensibility(False) def __pressedTextContextButton(self, toggle_button): self.data_box.setType(TEXT_TYPE) self.box_editor.setOcrPropertiesSensibility(True) def __pressedPerformOcrButton(self, button): self.performOcr() def performOcr(self, engine_name = None): selected_engine_index = self.box_editor.getSelectedOcrEngine() if engine_name: for i in xrange(len(self.ocr_engines)): if self.ocr_engines[i][0].name == engine_name: selected_engine_index = i break self.box_editor.selectOcrEngine(selected_engine_index) image = graphics.convertPixbufToImage(self.box_editor.getImage()) angle = self.box_editor.getAngle() if angle: image = graphics.getImageRotated(image, angle) if selected_engine_index != None: engine = self.ocr_engines[selected_engine_index][0] engine.setImage(image) text = engine.read() self.box_editor.setText(text) debug('Finished reading') text_size = graphics.getTextSizeFromImage(image) if text_size: y_resolution = float(self.reviewer.page.resolution[1]) text_size /= y_resolution text_size *= 72.0 self.box_editor.setFontSize(math.floor(text_size)) def performClassification(self, engine_name = None): selected_engine_index = self.box_editor.getSelectedOcrEngine() if engine_name: for i in xrange(len(self.ocr_engines)): if self.ocr_engines[i][0].name == engine_name: selected_engine_index = i break if selected_engine_index != None: engine = self.ocr_engines[selected_engine_index][0] type = engine.classify(self.box_editor.getText()) self.box_editor.setType(type) def __pressedAngleDetectionButton(self, widget): image = graphics.convertPixbufToImage(self.box_editor.getImage()) angle = graphics.getHorizontalAngleForText(image) debug('ANGLE: ', angle) self.box_editor.setAngle(angle) def setDataBox(self): text = self.box_editor.getText() self.data_box.setText(text) angle = self.box_editor.getAngle() self.data_box.setAngle(angle) self.__setDataBoxFont() self.__setDataBoxLetterSpacing() self.__setDataBoxLineSpacing() def updateDataBox(self, data_box): self.data_box = data_box self.box_editor.setX(self.data_box.x) self.box_editor.setY(self.data_box.y) self.box_editor.setWidth(self.data_box.width) self.box_editor.setHeight(self.data_box.height) self.box_editor.setType(self.data_box.type) self.box_editor.setText(self.data_box.text) self.__connectDataBoxSignals() self.__updateBoxColor(None, self.data_box.type) def __connectDataBoxSignals(self): self.data_box.connect('changed_x', self.__updateEditorX) self.data_box.connect('changed_y', self.__updateEditorY) self.data_box.connect('changed_width', self.__updateEditorWidth) self.data_box.connect('changed_height', self.__updateEditorHeight) self.data_box.connect('changed_image', self.__updateEditorImage) self.data_box.connect('changed_type', self.__updateBoxColor)