class DrawingArea(QWidget): loadSignal = pyqtSignal() profileSignal = pyqtSignal(list) def __init__(self): super(DrawingArea, self).__init__() self.image_path = None self.loadImage() self.drawing = False self.last_point = QPoint() self.lines = [] self.profiles = [] self.setUpPen() # Main drawing functionalities def mousePressEvent(self, event): if event.button() == Qt.LeftButton: self.last_point = event.pos() self.drawing = True def mouseMoveEvent(self, event): if self.drawing and (event.buttons() & Qt.LeftButton): self.updateImage() self.drawLineOnImage(self.last_point, event.pos()) def mouseReleaseEvent(self, event): if event.button() == Qt.LeftButton and self.drawing: self.image_lastdrawn = self.image.copy() self.drawing = False self.lines.append((self.last_point, event.pos())) self.extractLine() emit_value = [self.profiles[-1], self.lines[-1]] self.profileSignal.emit(emit_value) # Auxilliary drawing functionalities def updateImage(self): self.image = self.image_lastdrawn.copy() self.update() def drawLineOnImage(self, start, end): # Setting canvas painter = QPainter(self.image) painter.drawImage(self.rect(), self.image) painter.setPen(self.pen) # Draw line painter.drawLine(start, end) self.update() def paintEvent(self, event): painter = QPainter(self) painter.drawImage(event.rect(), self.image) painter.setPen(self.pen) # for line in self.lines: # start, end = line # painter.drawLine(start, end) self.update() def setUpPen(self, width=5, color='orange'): self.pen = QPen(QColor(color), width, Qt.SolidLine, Qt.RoundCap, Qt.RoundJoin) # Line profile functionalities def extractLine(self): start, end = self.lines[-1] x0, y0 = max(start.x(), 0), max(start.y(), 0) x1, y1 = min(end.x(), self.image_grayscale.shape[1] - 1), min( end.y(), self.image_grayscale.shape[0] - 1) num = int(np.hypot(x1 - x0, y1 - y0)) rows, cols = np.linspace(y0, y1, num), np.linspace(x0, x1, num) profile = self.image_grayscale[rows.astype(np.int), cols.astype(np.int)] self.profiles.append(list(profile)) # Other functionalities def loadImage(self): # Unfix widget size self.setMaximumSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX) self.setMinimumSize(0, 0) # Load image # if self.image_path is None, create dummy image if self.image_path == None: self.image_grayscale = np.array(Image.new('L', (600, 400), 255)) self.image = ImageQt(Image.new('RGB', (600, 400), (255, 255, 255))) self.image_lastdrawn = self.image.copy() else: # Store grayscale image to self.image_grayscale self.image_grayscale = np.array( Image.open(self.image_path).convert('L')) image = QImage(self.image_path) if image.isGrayscale(): # Create RGB version using PIL image_rgb = Image.open(self.image_path).convert('RGB') # Store RGB version of image in self.image, self.image_original self.image = ImageQt(image_rgb) self.image_lastdrawn = self.image.copy() else: # Store original and drawn image as it is self.image = image self.image_lastdrawn = image.copy() # Refix widget size self.setFixedSize(self.image.width(), self.image.height()) # Flush lines self.lines = [] self.profiles = [] self.loadSignal.emit() self.update() def saveImage(self, file_name): self.image.save(file_name, 'PNG', -1) # def main(): # app = QApplication(sys.argv) # demo = DrawingArea() # demo.show() # sys.exit(app.exec_()) # main()
class CaptureWindow(QMainWindow): def __init__(self): super().__init__() captureImage = ImageGrab.grab(bbox=(0, 0, screenWidth, screenHeight)) self.captureImage = ImageQt(captureImage) # cv2.destroyAllWindows() # cv2.namedWindow('cvImage') # cv2.imshow('cvImage', cv2.cvtColor(np.array(captureImage), cv2.COLOR_BGR2RGB)) # 화면을 보여준다. self.sX = 0 self.sY = 0 self.eX = 0 self.eY = 0 self.drawing = False self.translatedText = "" self.translatedTextList = None self.drawingText = False self.initUI() def initUI(self): self.setWindowTitle('My First Application') # 투명 배경색 # self.setAttribute(QtCore.Qt.WA_TranslucentBackground) self.setWindowFlag(QtCore.Qt.FramelessWindowHint) # 프레임바 제거 self.setWindowFlag(QtCore.Qt.WindowStaysOnTopHint) # 항상 위에 뜨도록 self.setFocusPolicy(QtCore.Qt.StrongFocus) self.move(0, 0) self.resize(screenWidth, screenHeight) self.setFocus(True) self.activateWindow() self.raise_() self.show() def paintEvent(self, e): painter = QPainter(self) # window painter get painter.begin(self) painter.drawImage(self.rect(), self.captureImage, self.captureImage.rect()) # window painter에 전체 스크린샷찍은 image draw if self.sX != 0 and self.sY != 0 and self.eX != 0 and self.eY != 0 : painter.setPen(QPen(QColor(255, 0, 0, 255), 1)) painter.drawRect(self.sX < self.eX and self.sX or self.eX, self.sY < self.eY and self.sY or self.eY, abs(self.eX-self.sX), abs(self.eY-self.sY)) if self.drawingText: fontSize = 15 margin = 10 boxHeight = fontSize + (margin * 2) boxWidth = fontSize * len(self.translatedTextList[0]) length = len(self.translatedTextList) index = 0 for text in self.translatedTextList: boxWidth = boxWidth < fontSize * len(text) and boxWidth or fontSize * len(text) boxWidth = boxWidth * 2 for text in self.translatedTextList: painter.setPen(QColor(255,255,255)) painter.setBrush(QColor(255, 255, 255)) painter.drawRect(self.sX, (self.eY + (boxHeight*length) > screenHeight and self.sY - ((index+1)*boxHeight) or self.eY + (index*boxHeight)), boxWidth, fontSize + (margin * 2)) painter.setPen(QColor(0,0,0)) painter.setFont(QFont('나눔명조', fontSize)) painter.drawText(self.sX + margin, (self.eY + (boxHeight*length) > screenHeight and (self.sY - margin) - (index*boxHeight) or (self.eY + fontSize + margin) + (index*boxHeight)), text) index = index + 1 painter.end() def keyPressEvent(self, e): if e.key() == Qt.Key_Escape: # esc 종료 cv2.destroyAllWindows() self.close() def mousePressEvent(self, e): if e.button() == Qt.LeftButton: self.drawing = True self.drawingText = False self.sX = e.pos().x() self.sY = e.pos().y() self.eX = e.pos().x() self.eY = e.pos().y() def mouseMoveEvent(self, e): if (e.buttons() & Qt.LeftButton) & self.drawing: self.eX = e.pos().x() self.eY = e.pos().y() self.update() # paintEvent 호출 def mouseReleaseEvent(self, e): if e.button() == Qt.LeftButton: if (self.sX == self.eX) or (self.sY == self.eY) or (abs(self.eX - self.sX) < 10) or (abs(self.eY - self.sY) < 10): return self.eX = e.pos().x() self.eY = e.pos().y() # 테두리 1px 빼고 캡처 cvImage = self.captureImage.copy(self.sX < self.eX and self.sX or self.eX, self.sY < self.eY and self.sY or self.eY, abs(self.eX-self.sX), abs(self.eY-self.sY)).convertToFormat(4) cvW = cvImage.width() cvH = cvImage.height() ptr = cvImage.bits() ptr.setsize(cvImage.byteCount()) arr = np.array(ptr).reshape(cvH, cvW, 4) img = cv2.cvtColor(arr, cv2.COLOR_BGR2GRAY) cv2.imshow('gray img', img) # cv2.destroyAllWindows() # cv2.namedWindow('cvImage') # cv2.imshow('cvImage', img) # 화면을 보여준다. img = cv2.resize(img, None, fx=2, fy=2, interpolation=cv2.INTER_CUBIC) (thresh, img) = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU) cv2.imshow('OTSU img', img) out_img = cv2.GaussianBlur(img, (3, 3), 0) (thresh, out_img) = cv2.threshold(out_img, 127, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU) cv2.imshow('cvImage', out_img) self.translatedText = image_to_string(out_img, config='--tessdata-dir "tessdata" -l eng --oem 3 --psm 3') print("translatedText1: ", self.translatedText) self.translatedText = self.translatedText.replace("[^a-zA-Z\s]", "") # 영어, 공백 빼고 다 제거 if not self.translatedText.strip() == "" : # self.translatedText = papagoApi.translate(self.translatedText) # 번역 # self.translatedTextList = self.translatedText.split('\n') # 줄바꿈 split # print("translatedText2: ", self.translatedTextList) self.drawingText = True self.update() # paintEvent 호출 self.drawing = False
def pil_to_pixmap(im): QtImage1 = ImageQt(im) QtImage2 = QtImage1.copy() return QtGui.QPixmap.fromImage(QtImage2)