Получить координаты выделенной области через Python
У меня есть программа реализованная с помощью Qt Desinger, в ней находится картинка.
Мне нужно чтобы нажимая на кнопку можно было выделить определенную область на этой картинке и сохранить её, скажем так вырезать или скриншот.
Ну или как можно переписать код без использования Tkiner. Код ниже идеально работает, но он вызывает новое окно, а нужно в этом же, или как его впихнуть чтобы он включался по нажатию на кнопку.
import tkinter as tk
from PIL import Image, ImageTk, ImageGrab
WIDTH, HEIGHT = 900, 900
topx, topy, botx, boty = 0, 0, 0, 0
rect_id = None
path = "4.jpg"
def get_mouse_posn(event):
global topy, topx
topx, topy = event.x, event.y
def update_sel_rect(event):
global rect_id
global topy, topx, botx, boty
botx, boty = event.x, event.y
canvas.coords(rect_id, topx, topy, botx, boty) # Update selection rect.
image = Image.open('4.jpg')
cropped = image.crop((topx, topy, botx, boty))
cropped.save('cropped_jelly.png')
window = tk.Tk()
window.title("Select Area")
window.geometry('%sx%s' % (WIDTH, HEIGHT))
window.configure(background='grey')
img = ImageTk.PhotoImage(Image.open(path))
canvas = tk.Canvas(window, width=img.width(), height=img.height(),
borderwidth=0, highlightthickness=0)
canvas.pack(expand=True)
canvas.img = img # Keep reference in case this code is put into a function.
canvas.create_image(0, 0, image=img, anchor=tk.NW)
# Create selection rectangle (invisible since corner points are equal).
rect_id = canvas.create_rectangle(topx, topy, topx, topy,
dash=(2, 2), fill='', outline='black')
canvas.bind('<Button-1>', get_mouse_posn)
canvas.bind('<B1-Motion>', update_sel_rect)
window.mainloop()
Ответы (1 шт):
Автор решения: S. Nick
→ Ссылка
Попробуйте так:
import sys
from PyQt5.QtGui import QPainter, QPen, QImage, QPixmap
from PyQt5.QtWidgets import QMainWindow, QApplication, QAction, \
QFileDialog, QRubberBand, QLabel
from PyQt5.QtCore import Qt, QRectF, QPointF, QRect, QTimer, QSize
from PIL import ImageGrab
import numpy as np
import cv2
class Label(QLabel):
def __init__(self, img, parent=None):
super(Label, self).__init__(parent)
self.setCursor(Qt.PointingHandCursor)
self.pixmapImagen = QPixmap(img)
self.setPixmap(self.pixmapImagen)
self.setAlignment(Qt.AlignCenter)
def mousePressEvent(self, event):
self.origin = event.pos()
super().mousePressEvent(event)
def mouseMoveEvent(self, event):
if event.buttons() & Qt.LeftButton:
self.move(event.windowPos().toPoint() - self.origin)
super().mouseMoveEvent(event)
class Window(QMainWindow):
def __init__(self):
super().__init__()
mainMenu = self.menuBar()
instmenu = mainMenu.addMenu("Инстументы")
file = mainMenu.addMenu("Файл")
videlenie = QAction("Выделить для копирования", self)
instmenu.addAction(videlenie)
videlenie.triggered.connect(self.screenshot)
photo = QAction("Вставить фото", self)
file.addAction(photo)
photo.triggered.connect(self.getImage)
self.image_foreground = QImage(self.size(), QImage.Format_ARGB32_Premultiplied)
self.image_foreground.fill(Qt.transparent)
self.image_background = QImage(self.size(), QImage.Format_ARGB32_Premultiplied)
self.image_background.fill(Qt.white)
self.instrument = 'screenshot'
self.selection = QRubberBand(QRubberBand.Rectangle, self)
self.start = QPointF()
self.end = QPointF()
def getImage(self):
filename, _ = QFileDialog.getOpenFileName(
self,
"Выберите изображение",
"",
"PNG(*.png);;JPEG(*.jpg *.jpeg);;All Files(*.*)"
)
if not filename:
return
self.image_background.load(filename)
self.selection.hide()
def paintEvent(self, event):
painter = QPainter(self)
painter.drawImage(self.rect(), self.image_background, self.image_background.rect())
painter.drawImage(self.image_foreground.rect(), self.image_foreground)
def mousePressEvent(self, event):
if event.buttons() == Qt.LeftButton and self.instrument == 'screenshot':
self.start = event.pos()
self._start = event.globalPos()
def mouseMoveEvent(self, event):
if event.buttons() == Qt.LeftButton and self.instrument == 'screenshot':
self.end = event.pos()
self.selection.setGeometry(QRect(self.start, self.end).normalized())
self.selection.show()
def mouseReleaseEvent(self, event):
if self.instrument == 'screenshot':
self._end = event.globalPos()
self.selection.hide()
QTimer.singleShot(20, self.newLabel)
def newLabel(self):
self.selection.hide()
self.instrument = 'None'
img = ImageGrab.grab(bbox=(
self._start.x(),
self._start.y(),
self._end.x(),
self._end.y()
))
pathImage = 'new_image.png' # <--- тут будет обрезанное изображение
img.save(pathImage)
img = cv2.cvtColor(np.array(img), cv2.COLOR_BGR2RGB)
cv2.waitKey(0)
cv2.destroyAllWindows()
# vvv это для демонстрации полученного изображения
self.labelImagen = Label(pathImage, self)
self.labelImagen.resize(self.selection.size())
self.labelImagen.show()
# ^^^
def screenshot(self):
self.instrument = 'screenshot'
def sizeHint(self):
return QSize(500, 500)
def resizeEvent(self, event):
self.image_foreground = QImage(self.size(), QImage.Format_ARGB32_Premultiplied)
self.image_foreground.fill(Qt.transparent)
self.update()
super().resizeEvent(event)
if __name__ == '__main__':
app = QApplication(sys.argv)
wnd = Window()
wnd.show()
sys.exit(app.exec_())


