コード例 #1
0
ファイル: fridgemagnets.py プロジェクト: Magdno1/Arianrhod
    def __init__(self, text, parent):
        super(DragLabel, self).__init__(parent)

        metric = QFontMetrics(self.font())
        size = metric.size(Qt.TextSingleLine, text)

        image = QImage(size.width() + 12, size.height() + 12, QImage.Format_ARGB32_Premultiplied)
        image.fill(qRgba(0, 0, 0, 0))

        font = QFont()
        font.setStyleStrategy(QFont.ForceOutline)

        painter = QPainter()
        painter.begin(image)
        painter.setRenderHint(QPainter.Antialiasing)
        painter.setBrush(Qt.white)
        painter.drawRoundedRect(QRectF(0.5, 0.5, image.width() - 1, image.height() - 1), 25, 25, Qt.RelativeSize)

        painter.setFont(font)
        painter.setBrush(Qt.black)
        painter.drawText(QRect(QPoint(6, 6), size), Qt.AlignCenter, text)
        painter.end()

        self.setPixmap(QPixmap.fromImage(image))
        self.labelText = text
コード例 #2
0
ファイル: __init__.py プロジェクト: AlexSchr/frescobaldi
def pixmap(name, size, mode, state):
    """Returns a (possibly cached) pixmap of the name and size with the default text color.
    
    The state argument is ignored for now.
    
    """
    if mode == QIcon.Selected:
        color = QApplication.palette().highlightedText().color()
    else:
        color = QApplication.palette().text().color()
    key = (name, size.width(), size.height(), color.rgb(), mode)
    try:
        return _pixmaps[key]
    except KeyError:
        i = QImage(size, QImage.Format_ARGB32_Premultiplied)
        i.fill(0)
        painter = QPainter(i)
        # render SVG symbol
        QSvgRenderer(os.path.join(__path__[0], name + ".svg")).render(painter)
        # recolor to text color
        painter.setCompositionMode(QPainter.CompositionMode_SourceIn)
        painter.fillRect(i.rect(), color)
        painter.end()
        # let style alter the drawing based on mode, and create QPixmap
        pixmap = QApplication.style().generatedIconPixmap(mode, QPixmap.fromImage(i), QStyleOption())
        _pixmaps[key] = pixmap
        return pixmap
コード例 #3
0
ファイル: letteritem.py プロジェクト: Axel-Erfurt/pyqt5
    def createImage(self, transform):
        scaledRect = transform.mapRect(QRect(0, 0, 25, 25))
        image = QImage(scaledRect.width(), scaledRect.height(),
                QImage.Format_ARGB32_Premultiplied)
        image.fill(0)
        painter = QPainter(image)
        painter.scale(transform.m11(), transform.m22())
        painter.setRenderHints(QPainter.TextAntialiasing | QPainter.Antialiasing | QPainter.SmoothPixmapTransform)
        painter.setPen(Qt.NoPen)

        if Colors.useEightBitPalette:
            painter.setBrush(QColor(102, 175, 54))
            painter.drawEllipse(0, 0, 25, 25)
            painter.setFont(Colors.tickerFont())
            painter.setPen(QColor(255, 255, 255))
            painter.drawText(10, 15, self.letter)
        else:
            brush = QLinearGradient(0, 0, 0, 25)
            brush.setSpread(QLinearGradient.PadSpread)
            brush.setColorAt(0.0, QColor(102, 175, 54, 200))
            brush.setColorAt(1.0, QColor(102, 175, 54, 60))
            painter.setBrush(brush)
            painter.drawEllipse(0, 0, 25, 25)
            painter.setFont(Colors.tickerFont())
            painter.setPen(QColor(255, 255, 255, 255))
            painter.drawText(10, 15, self.letter)

        return image
コード例 #4
0
ファイル: qtrender_image.py プロジェクト: oldtimestj/splash
 def _render_qwebpage_full(self, web_rect, render_rect, canvas_size):
     """Render web page in one step."""
     if self._qpainter_needs_tiling(render_rect, canvas_size):
         # If this condition is true, this function may get stuck.
         raise ValueError("Rendering region is too large to be drawn"
                          " in one step, use tile-by-tile renderer instead")
     canvas = QImage(canvas_size, self.qt_image_format)
     if self.is_jpeg():
         # White background for JPEG images, same as we have in all browsers.
         canvas.fill(Qt.white)
     else:
         # Preserve old behaviour for PNG format.
         canvas.fill(0)
     painter = QPainter(canvas)
     try:
         painter.setRenderHint(QPainter.Antialiasing, True)
         painter.setRenderHint(QPainter.TextAntialiasing, True)
         painter.setRenderHint(QPainter.SmoothPixmapTransform, True)
         painter.setWindow(web_rect)
         painter.setViewport(render_rect)
         painter.setClipRect(web_rect)
         self.web_page.mainFrame().render(painter)
     finally:
         painter.end()
     return WrappedQImage(canvas)
コード例 #5
0
ファイル: demotextitem.py プロジェクト: death-finger/Scripts
    def createImage(self, transform):
        if self.type == DemoTextItem.DYNAMIC_TEXT:
            return None

        sx = min(transform.m11(), transform.m22())
        sy = max(transform.m22(), sx)

        textItem = QGraphicsTextItem()
        textItem.setHtml(self.text)
        textItem.setTextWidth(self.textWidth)
        textItem.setFont(self.font)
        textItem.setDefaultTextColor(self.textColor)
        textItem.document().setDocumentMargin(2)

        w = textItem.boundingRect().width()
        h = textItem.boundingRect().height()
        image = QImage(int(w * sx), int(h * sy),
                QImage.Format_ARGB32_Premultiplied)
        image.fill(QColor(0, 0, 0, 0).rgba())
        painter = QPainter(image)
        painter.scale(sx, sy)
        style = QStyleOptionGraphicsItem()
        textItem.paint(painter, style, None)

        return image
コード例 #6
0
ファイル: parse_dash_results.py プロジェクト: spono/QGIS
    def create_mask(self, control_image, rendered_image, mask_image, overload=1):
        max_width = min(rendered_image.width(), control_image.width())
        max_height = min(rendered_image.height(), control_image.height())

        new_mask_image = QImage(control_image.width(), control_image.height(), QImage.Format_ARGB32)
        new_mask_image.fill(QColor(0, 0, 0))

        # loop through pixels in rendered image and compare
        mismatch_count = 0
        linebytes = max_width * 4
        for y in range(max_height):
            control_scanline = control_image.constScanLine(y).asstring(linebytes)
            rendered_scanline = rendered_image.constScanLine(y).asstring(linebytes)
            mask_scanline = mask_image.scanLine(y).asstring(linebytes)

            for x in range(max_width):
                currentTolerance = qRed(struct.unpack("I", mask_scanline[x * 4 : x * 4 + 4])[0])

                if currentTolerance == 255:
                    # ignore pixel
                    new_mask_image.setPixel(x, y, qRgb(currentTolerance, currentTolerance, currentTolerance))
                    continue

                expected_rgb = struct.unpack("I", control_scanline[x * 4 : x * 4 + 4])[0]
                rendered_rgb = struct.unpack("I", rendered_scanline[x * 4 : x * 4 + 4])[0]
                difference = min(255, colorDiff(expected_rgb, rendered_rgb) * overload)

                if difference > currentTolerance:
                    # update mask image
                    new_mask_image.setPixel(x, y, qRgb(difference, difference, difference))
                    mismatch_count += 1
                else:
                    new_mask_image.setPixel(x, y, qRgb(currentTolerance, currentTolerance, currentTolerance))
        return new_mask_image
コード例 #7
0
ファイル: qt.py プロジェクト: vialectrum/vialectrum
    def paintQR(self, data):
        if not data:
            return
        qr = qrcode.QRCode()
        qr.add_data(data)
        matrix = qr.get_matrix()
        k = len(matrix)
        border_color = Qt.white
        base_img = QImage(k * 5, k * 5, QImage.Format_ARGB32)
        base_img.fill(border_color)
        qrpainter = QPainter()
        qrpainter.begin(base_img)
        boxsize = 5
        size = k * boxsize
        left = (base_img.width() - size)/2
        top = (base_img.height() - size)/2
        qrpainter.setBrush(Qt.black)
        qrpainter.setPen(Qt.black)

        for r in range(k):
            for c in range(k):
                if matrix[r][c]:
                    qrpainter.drawRect(left+c*boxsize, top+r*boxsize, boxsize - 1, boxsize - 1)
        qrpainter.end()
        return base_img
コード例 #8
0
ファイル: imageitem.py プロジェクト: death-finger/Scripts
    def createImage(self, transform):
        original = QImage(self.image)
        if original.isNull():
            return original

        size = transform.map(QPoint(self.maxWidth, self.maxHeight))
        w = size.x()
        h = size.y()

        # Optimization: if image is smaller than maximum allowed size, just
        # return the loaded image.
        if original.size().height() <= h and original.size().width() <= w and not self.adjustSize and self.scale == 1:
            return original

        # Calculate what the size of the final image will be.
        w = min(w, float(original.size().width()) * self.scale)
        h = min(h, float(original.size().height()) * self.scale)

        adjustx = 1.0
        adjusty = 1.0
        if self.adjustSize:
            adjustx = min(transform.m11(), transform.m22())
            adjusty = max(transform.m22(), adjustx)
            w *= adjustx
            h *= adjusty

        # Create a new image with correct size, and draw original on it.
        image = QImage(int(w + 2), int(h + 2),
                QImage.Format_ARGB32_Premultiplied)
        image.fill(QColor(0, 0, 0, 0).rgba())
        painter = QPainter(image)
        painter.setRenderHints(QPainter.Antialiasing | QPainter.SmoothPixmapTransform)
        if self.adjustSize:
            painter.scale(adjustx, adjusty)
        if self.scale != 1:
            painter.scale(self.scale, self.scale)
        painter.drawImage(0, 0, original)

        if not self.adjustSize:
            # Blur out edges.
            blur = 30

            if h < original.height():
                brush1 = QLinearGradient(0, h - blur, 0, h)
                brush1.setSpread(QLinearGradient.PadSpread)
                brush1.setColorAt(0.0, QColor(0, 0, 0, 0))
                brush1.setColorAt(1.0, Colors.sceneBg1)
                painter.fillRect(0, int(h) - blur, original.width(), int(h),
                        brush1)

            if w < original.width():
                brush2 = QLinearGradient(w - blur, 0, w, 0)
                brush2.setSpread(QLinearGradient.PadSpread)
                brush2.setColorAt(0.0, QColor(0, 0, 0, 0))
                brush2.setColorAt(1.0, Colors.sceneBg1)
                painter.fillRect(int(w) - blur, 0, int(w), original.height(),
                        brush2)

        return image
コード例 #9
0
ファイル: img.py プロジェクト: JimmXinu/calibre
def overlay_image(img, canvas=None, left=0, top=0):
    ' Overlay the `img` onto the canvas at the specified position '
    if canvas is None:
        canvas = QImage(img.size(), QImage.Format_RGB32)
        canvas.fill(Qt.white)
    left, top = int(left), int(top)
    imageops.overlay(img, canvas, left, top)
    return canvas
コード例 #10
0
ファイル: img.py プロジェクト: JimmXinu/calibre
def add_borders_to_image(img, left=0, top=0, right=0, bottom=0, border_color='#ffffff'):
    img = image_from_data(img)
    if not (left > 0 or right > 0 or top > 0 or bottom > 0):
        return img
    canvas = QImage(img.width() + left + right, img.height() + top + bottom, QImage.Format_RGB32)
    canvas.fill(QColor(border_color))
    overlay_image(img, canvas, left, top)
    return canvas
コード例 #11
0
ファイル: textbutton.py プロジェクト: death-finger/Scripts
    def createRoundButtonBackground(self, transform):
        scaledRect = transform.mapRect(QRect(0, 0,
                self.logicalSize.width(), self.logicalSize.height()))

        image = QImage(scaledRect.width(), scaledRect.height(),
                QImage.Format_ARGB32_Premultiplied)
        image.fill(QColor(0, 0, 0, 0).rgba())
        painter = QPainter(image)
        painter.setRenderHint(QPainter.SmoothPixmapTransform)
        painter.setRenderHint(QPainter.Antialiasing)
        painter.setPen(Qt.NoPen)

        if Colors.useEightBitPalette:
            painter.setPen(QColor(120, 120, 120))
            if self.pressed:
                painter.setBrush(QColor(60, 60, 60))
            elif self.highlighted:
                painter.setBrush(QColor(100, 100, 100))
            else:
                painter.setBrush(QColor(80, 80, 80))
        else:
            outlinebrush = QLinearGradient(0, 0, 0, scaledRect.height())
            brush = QLinearGradient(0, 0, 0, scaledRect.height())

            brush.setSpread(QLinearGradient.PadSpread)
            highlight = QColor(255, 255, 255, 70)
            shadow = QColor(0, 0, 0, 70)
            sunken = QColor(220, 220, 220, 30)

            if self.type == TextButton.PANEL:
                normal1 = QColor(200, 170, 160, 50)
                normal2 = QColor(50, 10, 0, 50)
            else:
                normal1 = QColor(255, 255, 245, 60)
                normal2 = QColor(255, 255, 235, 10)

            if self.pressed:
                outlinebrush.setColorAt(0, shadow)
                outlinebrush.setColorAt(1, highlight)
                brush.setColorAt(0, sunken)
                painter.setPen(Qt.NoPen)
            else:
                outlinebrush.setColorAt(1, shadow)
                outlinebrush.setColorAt(0, highlight)
                brush.setColorAt(0, normal1)
                if not self.highlighted:
                    brush.setColorAt(1, normal2)
                painter.setPen(QPen(outlinebrush, 1))

            painter.setBrush(brush)

        if self.type == TextButton.PANEL:
            painter.drawRect(0, 0, scaledRect.width(), scaledRect.height())
        else:
            painter.drawRoundedRect(0, 0, scaledRect.width(),
                    scaledRect.height(), 10, 90, Qt.RelativeSize)

        return image
コード例 #12
0
ファイル: dmx.py プロジェクト: Tinkerforge/brickv
class DMXOverview(QWidget):
    def __init__(self, parent=None):
        super().__init__(parent)

        self.setAttribute(Qt.WA_StaticContents)

        self.parent = parent
        self.width = 512
        self.height = 32
        self.pen_width = 1
        self.image = QImage(QSize(self.width, self.height), QImage.Format_RGB32)

        self.setMaximumSize(self.width, self.height)
        self.setMinimumSize(self.width, self.height)

        self.last_point = QPoint()
        self.clear_image()

        self.white_pen = QPen(Qt.white, 1)
        self.black_pen = QPen(Qt.black, 1)

    def draw_frame(self, frame):
        painter = QPainter(self.image)

        for line, value in enumerate(frame):
            self.draw_line(line, value, painter)

        self.update()

    def draw_line(self, line, value, painter=None, update=False):
        if painter == None:
            painter = QPainter(self.image)

        painter.setPen(Qt.black)
        painter.drawLine(QPoint(line, 31 - value // 8), QPoint(line, 31))
        painter.setPen(Qt.white)
        painter.drawLine(QPoint(line, 0), QPoint(line, 31 - value // 8))

        if update:
            self.update()

    def fill_image(self, color):
        self.image.fill(color)
        self.update()

    def clear_image(self):
        self.image.fill(Qt.white)
        self.update()

    def mousePressEvent(self, event):
        if event.button() == Qt.LeftButton:
            line = event.pos().x()
            self.parent.address_table.verticalScrollBar().setSliderPosition(line)

    def paintEvent(self, event):
        painter = QPainter(self)
        painter.drawImage(event.rect(), self.image)
コード例 #13
0
def updateMask(control_image_path, rendered_image_path, mask_image_path):
    control_image = imageFromPath(control_image_path)
    if not control_image:
        error("Could not read control image {}".format(control_image_path))

    rendered_image = imageFromPath(rendered_image_path)
    if not rendered_image:
        error("Could not read rendered image {}".format(rendered_image_path))
    if not rendered_image.width() == control_image.width() or not rendered_image.height() == control_image.height():
        print(
            (
                "Size mismatch - control image is {}x{}, rendered image is {}x{}".format(
                    control_image.width(), control_image.height(), rendered_image.width(), rendered_image.height()
                )
            )
        )

    max_width = min(rendered_image.width(), control_image.width())
    max_height = min(rendered_image.height(), control_image.height())

    # read current mask, if it exist
    mask_image = imageFromPath(mask_image_path)
    if mask_image.isNull():
        print("Mask image does not exist, creating {}".format(mask_image_path))
        mask_image = QImage(control_image.width(), control_image.height(), QImage.Format_ARGB32)
        mask_image.fill(QColor(0, 0, 0))

    # loop through pixels in rendered image and compare
    mismatch_count = 0
    linebytes = max_width * 4
    for y in range(max_height):
        control_scanline = control_image.constScanLine(y).asstring(linebytes)
        rendered_scanline = rendered_image.constScanLine(y).asstring(linebytes)
        mask_scanline = mask_image.scanLine(y).asstring(linebytes)

        for x in range(max_width):
            currentTolerance = qRed(struct.unpack("I", mask_scanline[x * 4 : x * 4 + 4])[0])

            if currentTolerance == 255:
                # ignore pixel
                continue

            expected_rgb = struct.unpack("I", control_scanline[x * 4 : x * 4 + 4])[0]
            rendered_rgb = struct.unpack("I", rendered_scanline[x * 4 : x * 4 + 4])[0]
            difference = colorDiff(expected_rgb, rendered_rgb)

            if difference > currentTolerance:
                # update mask image
                mask_image.setPixel(x, y, qRgb(difference, difference, difference))
                mismatch_count += 1

    if mismatch_count:
        # update mask
        mask_image.save(mask_image_path, "png")
        print("Updated {} pixels in {}".format(mismatch_count, mask_image_path))
    else:
        print("No mismatches in {}".format(mask_image_path))
コード例 #14
0
ファイル: scribble2.py プロジェクト: specpose/stopeight
    def resizeImage(self, image, newSize):
        if image.size() == newSize:
            return

        newImage = QImage(newSize, QImage.Format_RGB32)
        newImage.fill(qRgb(255, 255, 255))
        painter = QPainter(newImage)
        painter.drawImage(QPoint(0, 0), image)
        self.image = newImage
コード例 #15
0
ファイル: editwidget.py プロジェクト: LeftRadio/ngl_utils
    def addY(bitmap):
        nbmp = QImage( bitmap.width(), bitmap.height() + 1, bitmap.format() )
        nbmp.fill(0)

        for y in range( bitmap.height() ):
            for x in range( bitmap.width() ):
                data = qGray( bitmap.pixel( x, y ) )
                if data:
                    nbmp.setPixel( x, y, 1 )
        return nbmp
コード例 #16
0
ファイル: Gantt.py プロジェクト: MaximeCheramy/simso-gui
 def create_qimage(self):
     total_width = 0
     images = []
     while total_width < self._width:
         w = min(self._width - total_width, 2 ** 15)
         image = QImage(w, self._height, QImage.Format_ARGB32)
         image.fill(QColor(235, 235, 235, 255))
         total_width += w
         images.append(image)
     return images
コード例 #17
0
ファイル: img.py プロジェクト: JimmXinu/calibre
def blend_on_canvas(img, width, height, bgcolor='#ffffff'):
    ' Blend the `img` onto a canvas with the specified background color and size '
    w, h = img.width(), img.height()
    scaled, nw, nh = fit_image(w, h, width, height)
    if scaled:
        img = img.scaled(nw, nh, Qt.IgnoreAspectRatio, Qt.SmoothTransformation)
        w, h = nw, nh
    canvas = QImage(width, height, QImage.Format_RGB32)
    canvas.fill(QColor(bgcolor))
    overlay_image(img, canvas, (width - w)//2, (height - h)//2)
    return canvas
コード例 #18
0
ファイル: brushingmodel.py プロジェクト: ilastik/volumina
    def endDrawing(self, pos):
        has_moved = self._hasMoved  # _hasMoved will change after calling moveTo
        if has_moved:
            self.moveTo(pos)
        else:
            assert self.pos == pos
            self.moveTo(QPointF(pos.x() + 0.0001, pos.y() + 0.0001))  # move a little

        # Qt seems to use strange rules for determining which pixels to set when rendering a brush stroke to a QImage.
        # We seem to get better results if we do the following:
        # 1) Slightly offset the source window because apparently there is a small shift in the data
        # 2) Render the scene to an image that is MUCH larger than the scene resolution (4x by 4x)
        # 3) Downsample each 4x4 patch from the large image back to a single pixel in the final image,
        #     applying some threshold to determine if the final pixel is on or off.

        tempi = QImage(
            QSize(4 * self.bb.width(), 4 * self.bb.height()), QImage.Format_ARGB32_Premultiplied
        )  # TODO: format
        tempi.fill(0)
        painter = QPainter(tempi)
        # Offset the source window.  At first I thought the right offset was 0.5, because
        #  that would seem to make sure points are rounded to pixel CENTERS, but
        #  experimentation indicates that 0.25 is slightly better for some reason...
        source_rect = QRectF(QPointF(self.bb.x() + 0.25, self.bb.y() + 0.25), QSizeF(self.bb.width(), self.bb.height()))
        target_rect = QRectF(QPointF(0, 0), QSizeF(4 * self.bb.width(), 4 * self.bb.height()))
        self.scene.render(painter, target=target_rect, source=source_rect)
        painter.end()

        # Now downsample: convert each 4x4 patch into a single pixel by summing and dividing
        ndarr = qimage2ndarray.rgb_view(tempi)[:, :, 0].astype(int)
        ndarr = ndarr.reshape((ndarr.shape[0],) + (ndarr.shape[1] // 4,) + (4,))
        ndarr = ndarr.sum(axis=-1)
        ndarr = ndarr.transpose()
        ndarr = ndarr.reshape((ndarr.shape[0],) + (ndarr.shape[1] // 4,) + (4,))
        ndarr = ndarr.sum(axis=-1)
        ndarr = ndarr.transpose()
        ndarr //= 4 * 4

        downsample_threshold = (7.0 / 16) * 255
        labels = numpy.where(ndarr >= downsample_threshold, numpy.uint8(self.drawnNumber), numpy.uint8(0))
        labels = labels.swapaxes(0, 1)
        assert labels.shape[0] == self.bb.width()
        assert labels.shape[1] == self.bb.height()

        ##
        ## ensure that at least one pixel is label when the brush size is 1
        ##
        ## this happens when the user just clicked without moving
        ## in that case the lineitem will be so tiny, that it won't be rendered
        ## into a single pixel by the code above
        if not has_moved and self.brushSize <= 1 and numpy.count_nonzero(labels) == 0:
            labels[labels.shape[0] // 2, labels.shape[1] // 2] = self.drawnNumber

        self.brushStrokeAvailable.emit(QPointF(self.bb.x(), self.bb.y()), labels)
コード例 #19
0
ファイル: tiling.py プロジェクト: ilastik/volumina
    def _blendTile(self, stack_id, tile_nr):
        """
        Blend all of the QImage layers of the patch
        specified by (stack_id, tile_nr) into a single QImage.
        """
        qimg = None
        p = None
        for i, (visible, layerOpacity, layerImageSource) in enumerate(reversed(self._sims)):
            image_type = layerImageSource.image_type()
            if issubclass(image_type, QGraphicsItem):
                with self._cache:
                    patch = self._cache.layer(stack_id, layerImageSource, tile_nr)
                if patch is not None:
                    assert isinstance(
                        patch, image_type
                    ), "This ImageSource is producing a type of image that is not consistent with it's declared image_type()"
                    # This is a QGraphicsItem, so we don't blend it into the final tile.
                    # (The ImageScene will just draw it on top of everything.)
                    # But this is a convenient place to update the opacity/visible state.
                    if patch.opacity() != layerOpacity or patch.isVisible() != visible:
                        patch.setOpacity(layerOpacity)
                        patch.setVisible(visible)
                    patch.setZValue(i)  # The sims ("stacked image sources") are ordered from
                    # top-to-bottom (see imagepump.py), but in Qt,
                    # higher Z-values are shown on top.
                    # Note that the current loop is iterating in reverse order.
                continue

            # No need to fetch non-visible image tiles.
            if not visible or layerOpacity == 0.0:
                continue

            with self._cache:
                patch = self._cache.layer(stack_id, layerImageSource, tile_nr)

            # patch might be a QGraphicsItem instead of QImage,
            # in which case it is handled separately,
            # not composited into the tile.

            if patch is not None:
                assert isinstance(
                    patch, QImage
                ), "Unknown tile layer type: {}. Expected QImage or QGraphicsItem".format(type(patch))
                if qimg is None:
                    qimg = QImage(self.tiling.imageRects[tile_nr].size(), QImage.Format_ARGB32_Premultiplied)
                    qimg.fill(0xFFFFFFFF)  # Use a hex constant instead.
                    p = QPainter(qimg)
                p.setOpacity(layerOpacity)
                p.drawImage(0, 0, patch)

        if p is not None:
            p.end()

        return qimg
コード例 #20
0
ファイル: main.py プロジェクト: Manko10/WekaVisualizer
 def saveImage(self):
     fileName = QFileDialog.getSaveFileName(self, self.tr("Select save location"),
                                            "", self.tr("Images (*.png *.jpg *.bmp *.xpm)"))
     if "" != fileName[0] and os.path.isdir(os.path.dirname(fileName[0])):
         imgSize = QSize(self.plot.scene().width() * 4, self.plot.scene().height() * 4)
         img = QImage(imgSize, QImage.Format_ARGB32)
         img.fill(Qt.transparent)
         painter = QPainter(img)
         self.plot.render(painter)
         img.save(fileName[0])
         del painter
         QDesktopServices.openUrl(QUrl("file:///" + fileName[0], QUrl.TolerantMode))
コード例 #21
0
ファイル: IconEditorGrid.py プロジェクト: testmana2/test
 def editNew(self):
     """
     Public slot to generate a new, empty image.
     """
     from .IconSizeDialog import IconSizeDialog
     dlg = IconSizeDialog(self.__image.width(), self.__image.height())
     res = dlg.exec_()
     if res == QDialog.Accepted:
         width, height = dlg.getData()
         img = QImage(width, height, QImage.Format_ARGB32)
         img.fill(qRgba(0, 0, 0, 0))
         self.setIconImage(img)
コード例 #22
0
ファイル: svg.py プロジェクト: anthonyfok/frescobaldi
 def render(self, page):
     """Generate an image for this Page."""
     i = QImage(page.width, page.height, QImage.Format_ARGB32_Premultiplied)
     i.fill(self.paperColor)
     painter = QPainter(i)
     rect = QRect(0, 0, page.width, page.height)
     painter.translate(rect.center())
     painter.rotate(page.computedRotation * 90)
     if page.computedRotation & 1:
         rect.setSize(rect.size().transposed())
     painter.translate(-rect.center())
     page._svg_r.render(painter, QRectF(rect))
     return i
コード例 #23
0
ファイル: executors.py プロジェクト: Pewpews/happypanda
def _rounded_qimage(qimg, radius):
	r_image = QImage(qimg.width(), qimg.height(), QImage.Format_ARGB32)
	r_image.fill(Qt.transparent)
	p = QPainter()
	pen = QPen(Qt.darkGray)
	pen.setJoinStyle(Qt.RoundJoin)
	p.begin(r_image)
	p.setRenderHint(p.Antialiasing)
	p.setPen(Qt.NoPen)
	p.setBrush(QBrush(qimg))
	p.drawRoundedRect(0, 0, r_image.width(), r_image.height(), radius, radius)
	p.end()
	return r_image
コード例 #24
0
 def saveImage(self, frame):
     element = self.getPostElement(frame.documentElement())
     if element is not None:
         rect = element.geometry()
         image = QImage(rect.size(), QImage.Format_ARGB32_Premultiplied)
         image.fill(Qt.transparent)
         painter = QPainter(image)
         painter.setRenderHint(QPainter.Antialiasing, True)
         painter.setRenderHint(QPainter.TextAntialiasing, True)
         painter.setRenderHint(QPainter.SmoothPixmapTransform, True)
         element.render(painter)
         painter.end()
         image.save(self.getName(element))
コード例 #25
0
ファイル: svg.py プロジェクト: 19joho66/frescobaldi
 def render(self, page):
     """Generate an image for this Page."""
     i = QImage(page.width, page.height, self.imageFormat)
     i.fill(page.paperColor or self.paperColor or QColor(Qt.white))
     painter = QPainter(i)
     rect = QRect(0, 0, page.width, page.height)
     painter.translate(rect.center())
     painter.rotate(page.computedRotation * 90)
     if page.computedRotation & 1:
         rect.setSize(rect.size().transposed())
     painter.translate(-rect.center())
     page._svg_r.render(painter, QRectF(rect))
     return i
コード例 #26
0
ファイル: imagesources.py プロジェクト: ilastik/volumina
    def wait(self):
        array_data = self._arrayreq.wait()
        rectf = self.rectf
        if array_data.handedness_switched:  # array_data should be of type slicingtools.ProjectedArray
            rectf = QRectF(rectf.height(), rectf.width())

        from PyQt5.QtWidgets import QPainter

        img = QImage(QSize(self.rectf.width(), self.rectf.height()), QImage.Format_ARGB32_Premultiplied)
        img.fill(0xFFFFFFFF)
        p = QPainter(img)
        p.drawImage(0, 0, img)
        DummyItem(self.rectf).paint(p, None)
        return img
コード例 #27
0
 def fontValuePixmap(font):
     f = QFont(font)
     img = QImage(16, 16, QImage.Format_ARGB32_Premultiplied)
     img.fill(0)
     p = QPainter(img)
     p.setRenderHint(QPainter.TextAntialiasing, True)
     p.setRenderHint(QPainter.Antialiasing, True)
     f.setPointSize(13)
     p.setFont(f)
     t = QTextOption()
     t.setAlignment(Qt.AlignCenter)
     p.drawText(QRectF(0, 0, 16, 16), 'A', t)
     p.end()
     return QPixmap.fromImage(img)
コード例 #28
0
ファイル: converter.py プロジェクト: LeftRadio/ngl_utils
    def font_charBmp(font, char):
        metric = QFontMetrics( font ).boundingRect( char )
        char_rect = QRect( 0, 0, metric.width(), metric.height() )
        chr_img = QImage( char_rect.width()+1, char_rect.height(), QImage.Format_Mono )
        chr_img.fill(0)

        # set img painter and draw char to bmp
        painter = QPainter( chr_img )
        painter.setPen( QPen(Qt.white) )
        painter.setFont( font )
        painter.drawText( char_rect, Qt.AlignJustify, char )
        painter.end()
        del(painter)

        # crop left / right
        x0 = 0
        x1 = char_rect.width()
        while x0 < x1 - 1:
            data_col = 0
            for col in range( char_rect.height() ):
                data_col += chr_img.pixel(x0, col) & 0x00FFFFFF
            if not data_col:
                x0 += 1
            else: break
        char_rect.setX(x0)

        while x1 > x0 + 1:
            x1 -= 1
            data_col = 0
            for col in range( char_rect.height() ):
                data_col += chr_img.pixel(x1, col) & 0x00FFFFFF
            if not data_col:
                char_rect.setWidth(x1 - x0)
            else: break

        # crop bottom
        y1 = char_rect.height()
        while y1 > 1:
            y1 -= 1
            data_row = 0
            for row in range( char_rect.width() ):
                data_row += chr_img.pixel(row, y1) & 0x00FFFFFF
            if not data_row:
                char_rect.setHeight(y1)
            else: break

        chr_img = chr_img.copy( char_rect )
        # chr_img.save( '.\\img\\0%s.bmp' % char, 'bmp' )
        return chr_img
コード例 #29
0
    def _pasteIcon(self):
        mime = QApplication.clipboard().mimeData()
        if mime.hasImage():
            image = mime.imageData()
            # Fill transparent color if present
            fixedImage = QImage(image.size(), QImage.Format_RGB32)
            fixedImage.fill(QColor(Qt.white).rgb())
            painter = QPainter(fixedImage)
            painter.drawImage(0, 0, image)
            painter.end()

            self._setNewImage(fixedImage)
        elif mime.hasUrls():
            url = mime.urls()[0]
            self.loadFromFile(url.toLocalFile())
コード例 #30
0
    def get_image(self, size):
        if self.source_setting_changed():
            self.update_source()

        image = QImage(size.width(), size.height(), QImage.Format_ARGB32)
        painter = QPainter(image)
        if self.graph is None:
            if self.settings.contains('protofile'):
                url = QUrl(self.settings.value('protofile'))
                self.set_source(url.toDisplayString(QUrl.RemoveScheme))
            else:
                image.fill(QColor(200, 200, 200))
            return image
        self.renderer.load(QByteArray(self.graph))
        self.renderer.render(painter)
        return image
コード例 #31
0
class Map(QWidget):
    def __init__(self):
        super().__init__()

        self.initUI()



    elHght_72, elWdth_72 = 0, 0 #Mouse click WiFi zone
    elHght_54, elWdth_54 = 0, 0
    elHght_32, elWdth_32 = 0, 0
    elHght_11, elWdth_11 = 0, 0
    elHght_6, elWdth_6 = 0, 0
    elHght_1, elWdth_1 = 0, 0
    elCntH, elCntW = 0, 0 #Mouse click WiFi zone center
    clickNum = 0 #Number of mouse click for device
    devList = [] #Device list
    elClr = "#000000"

    def mousePressEvent(self, event):

        point = event.pos()

        painter = QPainter(self._im)
        painter.setPen(QPen(QColor(Map.elClr), 2, Qt.SolidLine, Qt.RoundCap))
        painter.setBrush(QBrush(QColor(Map.elClr), Qt.SolidPattern))
        painter.drawEllipse(point, Map.elCntH, Map.elCntW)

        painter.setPen(QPen(QColor("#000"), 2, Qt.SolidLine, Qt.RoundCap))
        painter.setBrush(QBrush(QColor("#000"), Qt.CrossPattern))
        painter.drawEllipse(point, Map.elHght_72, Map.elWdth_72)

        painter.setPen(QPen(QColor("#439232"), 2, Qt.SolidLine, Qt.RoundCap))
        painter.setBrush(QBrush(QColor("#439232"), Qt.CrossPattern))
        painter.drawEllipse(point, Map.elHght_54, Map.elWdth_54)

        painter.setPen(QPen(QColor("#923243"), 2, Qt.SolidLine, Qt.RoundCap))
        painter.setBrush(QBrush(QColor("#923243"), Qt.CrossPattern))
        painter.drawEllipse(point, Map.elHght_32, Map.elWdth_32)

        painter.setPen(QPen(QColor("#324392"), 2, Qt.SolidLine, Qt.RoundCap))
        painter.setBrush(QBrush(QColor("#324392"), Qt.CrossPattern))
        painter.drawEllipse(point, Map.elHght_11, Map.elWdth_11)

        painter.setPen(QPen(QColor("#324392"), 2, Qt.SolidLine, Qt.RoundCap))
        painter.setBrush(QBrush(QColor("#324392"), Qt.CrossPattern))
        painter.drawEllipse(point, Map.elHght_6, Map.elWdth_6)

        painter.setPen(QPen(QColor("#324392"), 2, Qt.SolidLine, Qt.RoundCap))
        painter.setBrush(QBrush(QColor("#324392"), Qt.CrossPattern))
        painter.drawEllipse(point, Map.elHght_1, Map.elWdth_1)

        if Map.elHght_1 >= 10:

            painter.setPen(QPen(QColor("#000000")))
            painter.setFont(QFont('Arial', 15))
            painter.drawText(point, str(Map.clickNum + 1))

            print("ClickNum:", Map.clickNum + 1)

            #Mouse click coordinates
            pointPressX = point.x()
            pointPressY = point.y()
            print("X is", pointPressX)
            print("Y is", pointPressY)

            #New device
            radiusWiFi = [Map.elHght_72, Map.elHght_54, Map.elHght_32, Map.elHght_11, Map.elHght_6, Map.elHght_1]
            dev = device.Device(Map.clickNum + 1, [pointPressX, pointPressY], radiusWiFi)

            #Device list
            Map.devList.append(dev)
            print("Map.devList", Map.devList)

            Map.clickNum += 1
            #if Map.clickNum >= 1:
            #    device.calcWifiDist(Map.devList)



        # Перерисуемся
        self.update()

    def paintEvent(self, event):
        super().paintEvent(event)

        painter = QPainter(self)
        painter.drawImage(0, 0, self._im)

    def initUI(self):
        QToolTip.setFont(QFont('SansSerif', 10))

        #Button Router
        btnRout = QPushButton("Router", self)
        btnRout.move(30, 50)

        btnESP = QPushButton("ESP-32", self)
        btnESP.move(160, 50)

        btnStp = QPushButton("Stop", self)
        btnStp.move(290, 50)


        btnShwInts = QPushButton("Result", self)
        #btnShwInts = btnStp = QPushButton("Result", self) #when click button, 2 buttons work (stop and Result)
        btnShwInts.move(420, 50)

        btnRout.clicked.connect(self.btnRoutnClicked)
        btnESP.clicked.connect(self.btnESPClicked)
        btnStp.clicked.connect(self.btnStopClicked)
        btnShwInts.clicked.connect(self.btnShwIntsClicked)

        #Size and color for drawing zone
        self._im = QImage(1700, 960, QImage.Format_ARGB32)
        self._im.fill(QColor("white"))

        #Painting of room - rectangle
        painterRect = QPainter(self._im)
        painterRect.setPen(QPen(QColor("#000"), 1, Qt.SolidLine, Qt.RoundCap))
        painterRect.drawRect(100, 100, 100, 800)

        ##History
#
        ## Size and color for drawing zone
        #self._in = QImage(1700, 960, QImage.Format_ARGB32)
        #self._in.fill(QColor("red"))
        #
        ##Color for speed 72Mbps
        #history = QPainter(self._in)
        #history.setPen(QPen(QColor("#439232"), 1, Qt.SolidLine, Qt.RoundCap))
        ##history_72.setBrush(QBrush(QColor("#439232"), Qt.CrossPattern))
        #history.drawRect(400, 100, 100, 800)
#
        ## Color for speed 54Mbps
        #history_54 = QPainter(self._im)
        #history_54.setPen(QPen(QColor("#923243"), 1, Qt.SolidLine, Qt.RoundCap))
        #history_54.setBrush(QBrush(QColor("#923243"), Qt.CrossPattern))
        #history_54.drawRect(50, 150, 50, 50)
#
        ## Color for speed 32Mbps
        #history_32 = QPainter(self._im)
        #history_32.setPen(QPen(QColor("#324392"), 1, Qt.SolidLine, Qt.RoundCap))
        #history_32.setBrush(QBrush(QColor("#324392"), Qt.CrossPattern))
        #history_32.drawRect(50, 200, 50, 50)
#
        ## Color for speed 11Mbps
        #history_11 = QPainter(self._im)
        #history_11.setPen(QPen(QColor("#000"), 1, Qt.SolidLine, Qt.RoundCap))
        #history_11.setBrush(QBrush(QColor("#000"), Qt.CrossPattern))
        #history_11.drawRect(50, 250, 50, 50)
#
        ## Color for speed 6Mbps
        #history_6 = QPainter(self._im)
        #history_6.setPen(QPen(QColor("#000"), 1, Qt.SolidLine, Qt.RoundCap))
        #history_6.setBrush(QBrush(QColor("#000"), Qt.CrossPattern))
        #history_6.drawRect(50, 300, 50, 50)
#
        ## Color for speed 1Mbps
        #history_1 = QPainter(self._im)
        #history_1.setPen(QPen(QColor("#000"), 1, Qt.SolidLine, Qt.RoundCap))
        #history_1.setBrush(QBrush(QColor("#000"), Qt.CrossPattern))
        #history_1.drawRect(50, 350, 50, 50)

        #Size and Title for program window
        self.setFixedSize(1700, 960)
        self.setWindowTitle('Room')

        self.show()

    def btnRoutnClicked(self):
        '''
        Function for button Router
        Changes size and color of router's wifi zone
        '''
        Map.elHght_72, Map.elWdth_72 = rtrWidth
        #Map.elHght_54, Map.elWdth_54
        #Map.elHght_32, Map.elWdth_32
        #Map.elHght_11, Map.elWdth_11
        #Map.elHght_6, Map.elWdth_6
        #Map.elHght_1, Map.elWdth_1
        Map.elCntH, Map.elCntW = rtrCnt
        Map.elClr = "#431292"
        print("Button Router pressed")

    def btnESPClicked(self):
        '''
        Function for button ESP-32
        Changes size and color of esp's wifi zone
        '''
        Map.elHght_72, Map.elWdth_72 = espWidth_72
        Map.elHght_54, Map.elWdth_54 = espWidth_54
        Map.elHght_32, Map.elWdth_32 = espWidth_32
        Map.elHght_11, Map.elWdth_11 = espWidth_11
        Map.elHght_6, Map.elWdth_6 = espWidth_6
        Map.elHght_1, Map.elWdth_1 = espWidth_1
        Map.elCntH, Map.elCntW = espWidth_Cnt
        Map.elClr = "#439232"
        print("Button ESP-32 pressed")

    def btnStopClicked(self):
        '''
        Function for button Stop
        Changes size of wifi zone to 0
        '''
        Map.elHght_72, Map.elWdth_72 = width_stop
        Map.elHght_54, Map.elWdth_54 = width_stop
        Map.elHght_32, Map.elWdth_32 = width_stop
        Map.elHght_11, Map.elWdth_11 = width_stop
        Map.elHght_6, Map.elWdth_6 = width_stop
        Map.elHght_1, Map.elWdth_1 = width_stop
        Map.elCntH, Map.elCntW = width_stop
        print("Button Stop pressed")

    def btnShwIntsClicked(self):
        print("Button Show intersections pressed")
        if Map.clickNum >= 1:
            speed = wifi_speed
            device.calcWifiDist(Map.devList, wifi_speed)
コード例 #32
0
ファイル: vizPos.py プロジェクト: jerryhan88/BNC_py
class Viz(QWidget):
    def __init__(self, prob):
        super().__init__()
        self.xLen = self.yLen = 10 * unit
        w, h = coX + self.xLen + margin * 1, coY + self.yLen + margin * 1
        self.canvasSize = (w, h)
        # self.image = QImage(w, h, QImage.Format_RGB32)
        # self.image.fill(Qt.white)
        # self.path = QPainterPath()
        # self.clearImage()
        #
        self.instances = []
        self.initInstances(prob)
        self.initUI(prob['problemName'])
        QShortcut(QKeySequence("Ctrl+Q"), self, self.close)

    def initInstances(self, prob):
        sL, sXY = [], []
        for i in range(len(prob['S'])):
            sL.append('s%d' % i)
            sx, sy = prob['XY'][prob['S'][i]]
            sXY.append((coX + sx * self.xLen, coY + (1.0 - sy) * self.yLen))
        self.instances.append(RoutineSequence(sL, sXY))
        for i in range(len(prob['P'])):
            wid = 'w%d' % i
            nid = prob['P'][i]
            hx, hy = prob['XY'][nid]
            clr = pallet[nid % len(pallet)]
            wh = WareHouse(wid, coX + hx * self.xLen,
                           coY + (1.0 - hy) * self.yLen, clr)
            self.instances.append(wh)
        partialSeq = prob['S']
        al_i, be_i, t_ij, bu = [
            prob[k] for k in ['al_i', 'be_i', 't_ij', 'bu']
        ]
        for k in range(len(prob['D'])):
            nid = 't%d' % k
            nx, ny = prob['XY'][prob['D'][k]]
            n0, n1 = prob['h_k'][k], prob['n_k'][k]
            clr = pallet[n0 % len(pallet)]
            isValidTask = None
            min_tt_seq = get_min_tt_seq(partialSeq, n0, n1, al_i, be_i, t_ij)
            if min_tt_seq is None:
                isValidTask = False
            else:
                tt = get_travelTime(min_tt_seq, al_i, be_i, t_ij)
                isValidTask = tt < bu
            self.instances.append(
                DeliveryPoint(nid, coX + nx * self.xLen,
                              coY + (1.0 - ny) * self.yLen, clr, isValidTask))

    # def clearImage(self):
    #     self.path = QPainterPath()
    #     self.image.fill(Qt.white)
    #     self.update()

    def initUI(self, problemName):
        w, h = self.canvasSize
        self.setGeometry(mainFrameOrigin[0], mainFrameOrigin[1], w, h)
        self.setWindowTitle(problemName)
        self.setFixedSize(QSize(w, h))
        #
        self.image = QImage(w, h, QImage.Format_RGB32)
        self.image.fill(Qt.white)
        pal = self.palette()
        pal.setColor(QPalette.Background, Qt.white)
        self.setAutoFillBackground(True)
        self.setPalette(pal)
        #
        self.show()

    def paintEvent(self, e):
        qp = QPainter()
        qp.begin(self)
        self.drawCanvas(qp)
        qp.end()
        #
        qp = QPainter()
        qp.begin(self.image)
        self.drawCanvas(qp)
        qp.end()

    def save_img(self, img_fpath):
        if img_fpath.endswith('.png'):
            self.image.save(img_fpath, 'png')
        else:
            assert img_fpath.endswith('.pdf')
            w, h = self.canvasSize
            printer = QPrinter(QPrinter.HighResolution)
            printer.setPageSizeMM(QSizeF(w / 15, h / 15))
            printer.setFullPage(True)
            printer.setPageMargins(0.0, 0.0, 0.0, 0.0, QPrinter.Millimeter)
            printer.setColorMode(QPrinter.Color)
            printer.setOutputFormat(QPrinter.PdfFormat)
            printer.setOutputFileName(img_fpath)
            pixmap = self.grab().scaledToHeight(
                printer.pageRect(
                    QPrinter.DevicePixel).size().toSize().height() * 2)
            painter = QPainter(printer)
            painter.drawPixmap(0, 0, pixmap)
            painter.end()

    def drawCanvas(self, qp):
        pen = QPen(Qt.black, 2, Qt.SolidLine)
        qp.setPen(pen)
        qp.setBrush(Qt.NoBrush)
        # Outer lines!
        qp.drawLine(coX, coY, coX, coY + self.yLen)
        qp.drawLine(coX, coY + self.yLen, coX + self.xLen, coY + self.yLen)
        qp.drawLine(coX + self.xLen, coY + self.yLen, coX + self.xLen, coY)
        qp.drawLine(coX + self.xLen, coY, coX, coY)
        #
        pen = QPen(Qt.gray, 1, Qt.DashLine)
        qp.setPen(pen)
        for i in range(numGridLines):
            qp.drawLine(coX + float(i + 1) / (numGridLines + 1) * self.xLen,
                        coY,
                        coX + float(i + 1) / (numGridLines + 1) * self.xLen,
                        coY + self.yLen)
            qp.drawLine(coX + self.xLen,
                        coY + float(i + 1) / (numGridLines + 1) * self.yLen,
                        coX,
                        coY + float(i + 1) / (numGridLines + 1) * self.yLen)
        #
        for ins in self.instances:
            ins.draw(qp)
コード例 #33
0
class ResultHandler(QDialog):
    def __init__(self, parent=None):
        super(ResultHandler, self).__init__()
        self.setWindowTitle('Dash results')
        self.control_label = QLabel()
        self.rendered_label = QLabel()
        self.diff_label = QLabel()

        self.mask_label = QLabel()
        self.new_mask_label = QLabel()

        grid = QGridLayout()
        self.test_name_label = QLabel()
        grid.addWidget(self.test_name_label, 0, 0)
        grid.addWidget(QLabel('Control'), 1, 0)
        grid.addWidget(QLabel('Rendered'), 1, 1)
        grid.addWidget(QLabel('Difference'), 1, 2)
        grid.addWidget(self.control_label, 2, 0)
        grid.addWidget(self.rendered_label, 2, 1)
        grid.addWidget(self.diff_label, 2, 2)
        grid.addWidget(QLabel('Current Mask'), 3, 0)
        grid.addWidget(QLabel('New Mask'), 3, 1)
        grid.addWidget(self.mask_label, 4, 0)
        grid.addWidget(self.new_mask_label, 4, 1)

        v_layout = QVBoxLayout()
        v_layout.addLayout(grid, 1)

        next_image_button = QPushButton()
        next_image_button.setText('Skip')
        next_image_button.pressed.connect(self.load_next)

        self.overload_spin = QDoubleSpinBox()
        self.overload_spin.setMinimum(1)
        self.overload_spin.setMaximum(255)
        self.overload_spin.setValue(1)

        preview_mask_button = QPushButton()
        preview_mask_button.setText('Preview New Mask')
        preview_mask_button.pressed.connect(self.preview_mask)

        save_mask_button = QPushButton()
        save_mask_button.setText('Save New Mask')
        save_mask_button.pressed.connect(self.save_mask)

        button_layout = QHBoxLayout()
        button_layout.addWidget(next_image_button)
        button_layout.addWidget(QLabel('Mask diff multiplier:'))
        button_layout.addWidget(self.overload_spin)
        button_layout.addWidget(preview_mask_button)
        button_layout.addWidget(save_mask_button)
        button_layout.addStretch()
        v_layout.addLayout(button_layout)
        self.setLayout(v_layout)

    def closeEvent(self, event):
        self.reject()

    def parse_url(self, url):
        print('Fetching dash results from: {}'.format(url))
        page = urllib.request.urlopen(url)
        soup = BeautifulSoup(page, "lxml")

        # build up list of rendered images
        measurement_img = [
            img for img in soup.find_all('img')
            if img.get('alt') and img.get('alt').startswith('Rendered Image')
        ]

        images = {}
        for img in measurement_img:
            m = re.search('Rendered Image (.*?)\s', img.get('alt'))
            test_name = m.group(1)
            rendered_image = img.get('src')
            images[test_name] = '{}/{}'.format(dash_url, rendered_image)

        print('found images:\n{}'.format(images))
        self.images = images
        self.load_next()

    def load_next(self):
        if not self.images:
            # all done
            self.accept()

        test_name, rendered_image = self.images.popitem()
        self.test_name_label.setText(test_name)
        control_image = self.get_control_image_path(test_name)
        if not control_image:
            self.load_next()
            return

        self.mask_image_path = control_image[:-4] + '_mask.png'
        self.load_images(control_image, rendered_image, self.mask_image_path)

    def load_images(self, control_image_path, rendered_image_path,
                    mask_image_path):
        self.control_image = imageFromPath(control_image_path)
        if not self.control_image:
            error('Could not read control image {}'.format(control_image_path))

        self.rendered_image = imageFromPath(rendered_image_path)
        if not self.rendered_image:
            error(
                'Could not read rendered image {}'.format(rendered_image_path))
        if not self.rendered_image.width() == self.control_image.width(
        ) or not self.rendered_image.height() == self.control_image.height():
            print(
                'Size mismatch - control image is {}x{}, rendered image is {}x{}'
                .format(self.control_image.width(),
                        self.control_image.height(),
                        self.rendered_image.width(),
                        self.rendered_image.height()))

        max_width = min(self.rendered_image.width(),
                        self.control_image.width())
        max_height = min(self.rendered_image.height(),
                         self.control_image.height())

        # read current mask, if it exist
        self.mask_image = imageFromPath(mask_image_path)
        if self.mask_image.isNull():
            print('Mask image does not exist, creating {}'.format(
                mask_image_path))
            self.mask_image = QImage(self.control_image.width(),
                                     self.control_image.height(),
                                     QImage.Format_ARGB32)
            self.mask_image.fill(QColor(0, 0, 0))

        self.diff_image = self.create_diff_image(self.control_image,
                                                 self.rendered_image,
                                                 self.mask_image)
        if not self.diff_image:
            self.load_next()
            return

        self.control_label.setPixmap(QPixmap.fromImage(self.control_image))
        self.rendered_label.setPixmap(QPixmap.fromImage(self.rendered_image))
        self.mask_label.setPixmap(QPixmap.fromImage(self.mask_image))
        self.diff_label.setPixmap(QPixmap.fromImage(self.diff_image))
        self.preview_mask()

    def preview_mask(self):
        self.new_mask_image = self.create_mask(self.control_image,
                                               self.rendered_image,
                                               self.mask_image,
                                               self.overload_spin.value())
        self.new_mask_label.setPixmap(QPixmap.fromImage(self.new_mask_image))

    def save_mask(self):
        self.new_mask_image.save(self.mask_image_path, "png")
        self.load_next()

    def create_mask(self,
                    control_image,
                    rendered_image,
                    mask_image,
                    overload=1):
        max_width = min(rendered_image.width(), control_image.width())
        max_height = min(rendered_image.height(), control_image.height())

        new_mask_image = QImage(control_image.width(), control_image.height(),
                                QImage.Format_ARGB32)
        new_mask_image.fill(QColor(0, 0, 0))

        # loop through pixels in rendered image and compare
        mismatch_count = 0
        linebytes = max_width * 4
        for y in range(max_height):
            control_scanline = control_image.constScanLine(y).asstring(
                linebytes)
            rendered_scanline = rendered_image.constScanLine(y).asstring(
                linebytes)
            mask_scanline = mask_image.scanLine(y).asstring(linebytes)

            for x in range(max_width):
                currentTolerance = qRed(
                    struct.unpack('I', mask_scanline[x * 4:x * 4 + 4])[0])

                if currentTolerance == 255:
                    # ignore pixel
                    new_mask_image.setPixel(
                        x, y,
                        qRgb(currentTolerance, currentTolerance,
                             currentTolerance))
                    continue

                expected_rgb = struct.unpack(
                    'I', control_scanline[x * 4:x * 4 + 4])[0]
                rendered_rgb = struct.unpack(
                    'I', rendered_scanline[x * 4:x * 4 + 4])[0]
                difference = min(
                    255,
                    colorDiff(expected_rgb, rendered_rgb) * overload)

                if difference > currentTolerance:
                    # update mask image
                    new_mask_image.setPixel(
                        x, y, qRgb(difference, difference, difference))
                    mismatch_count += 1
                else:
                    new_mask_image.setPixel(
                        x, y,
                        qRgb(currentTolerance, currentTolerance,
                             currentTolerance))
        return new_mask_image

    def get_control_image_path(self, test_name):
        if os.path.isfile(test_name):
            return path

        # else try and find matching test image
        script_folder = os.path.dirname(os.path.realpath(sys.argv[0]))
        control_images_folder = os.path.join(
            script_folder, '../tests/testdata/control_images')

        matching_control_images = [
            x[0] for x in os.walk(control_images_folder) if test_name in x[0]
        ]
        if len(matching_control_images) > 1:
            QMessageBox.warning(
                self, 'Result',
                'Found multiple matching control images for {}'.format(
                    test_name))
            return None
        elif len(matching_control_images) == 0:
            QMessageBox.warning(
                self, 'Result',
                'No matching control images found for {}'.format(test_name))
            return None

        found_control_image_path = matching_control_images[0]

        # check for a single matching expected image
        images = glob.glob(os.path.join(found_control_image_path, '*.png'))
        filtered_images = [i for i in images if not i[-9:] == '_mask.png']
        if len(filtered_images) > 1:
            error('Found multiple matching control images for {}'.format(
                test_name))
        elif len(filtered_images) == 0:
            error('No matching control images found for {}'.format(test_name))

        found_image = filtered_images[0]
        print('Found matching control image: {}'.format(found_image))
        return found_image

    def create_diff_image(self, control_image, rendered_image, mask_image):
        # loop through pixels in rendered image and compare
        mismatch_count = 0
        max_width = min(rendered_image.width(), control_image.width())
        max_height = min(rendered_image.height(), control_image.height())
        linebytes = max_width * 4

        diff_image = QImage(control_image.width(), control_image.height(),
                            QImage.Format_ARGB32)
        diff_image.fill(QColor(152, 219, 249))

        for y in range(max_height):
            control_scanline = control_image.constScanLine(y).asstring(
                linebytes)
            rendered_scanline = rendered_image.constScanLine(y).asstring(
                linebytes)
            mask_scanline = mask_image.scanLine(y).asstring(linebytes)

            for x in range(max_width):
                currentTolerance = qRed(
                    struct.unpack('I', mask_scanline[x * 4:x * 4 + 4])[0])

                if currentTolerance == 255:
                    # ignore pixel
                    continue

                expected_rgb = struct.unpack(
                    'I', control_scanline[x * 4:x * 4 + 4])[0]
                rendered_rgb = struct.unpack(
                    'I', rendered_scanline[x * 4:x * 4 + 4])[0]
                difference = colorDiff(expected_rgb, rendered_rgb)

                if difference > currentTolerance:
                    # update mask image
                    diff_image.setPixel(x, y, qRgb(255, 0, 0))
                    mismatch_count += 1

        if mismatch_count:
            return diff_image
        else:
            print('No mismatches')
            return None
コード例 #34
0
ファイル: imageview.py プロジェクト: justinshenk/qtpyvis
class QImageView(QWidget):
    '''An experimental class to display images using the QPixmap
    class.  This may be more efficient than using matplotlib for
    displaying images.
    '''

    image : QImage = None

    activationMask : QImage = None

    def __init__(self, parent):
        super().__init__(parent)
        #self.setScaledContents(True)
        # an alternative may be to call
        #     pixmap.scaled(self.size(), Qt.KeepAspectRatio)
        # in the myplot method.

    def setImage(self, image : np.ndarray):
        self.image = image
        if image is not None:
            # To construct a 8-bit monochrome QImage, we need a uint8
            # numpy array
            if image.dtype != np.uint8:
                image = (image*255).astype(np.uint8)
            self.image = QImage(image, image.shape[1], image.shape[0],
                                QImage.Format_Grayscale8)
        else:
            self.image = None

        self.update()


    def setActivationMask(self, mask, position = None):
        '''Set an (activation) mask to be displayed on top of
        the actual image. The mask should be

        Arguments
        ---------
        mask : numpy.ndarray

        '''
        if mask is None:
            self.activationMask = None
        else:
            self.activationMask = QImage(mask.shape[1], mask.shape[0],
                                         QImage.Format_ARGB32)
            self.activationMask.fill(Qt.red)

            alpha = QImage(mask, mask.shape[1], mask.shape[0],
                           mask.shape[1], QImage.Format_Alpha8)
            painter = QPainter(self.activationMask)
            painter.setCompositionMode(QPainter.CompositionMode_DestinationIn)
            painter.drawImage(QPoint(),alpha)
            painter.end()
        self.update()


    def paintEvent(self, event):
        '''Process the paint event by repainting this Widget.

        Arguments
        ---------
        event : QPaintEvent
        '''
        painter = QPainter()
        painter.begin(self)
        self._drawImage(painter)
        self._drawMask(painter)
        painter.end()

    def _drawImage(self, painter : QPainter):
        if self.image is not None:
            painter.drawImage(self.rect(),self.image)

    def _drawMask(self, painter : QPainter):
        '''Display the given image. Image is supposed to be a numpy array.
        '''
        if self.image is not None and self.activationMask is not None:
            scale_width = self.width() / self.image.width()
            scale_height = self.height() / self.image.height()
            delta = (self.image.size() - self.activationMask.size())/2
            target = QRect(delta.width()*scale_width,
                           delta.height()*scale_height,
                           self.activationMask.width()*scale_width,
                           self.activationMask.height()*scale_height)

            #source = QRect(QPoint(),self.activationMask.size())
            painter.drawImage(target, self.activationMask)
コード例 #35
0
def exportToMobile(model, params):
    IMAGE_FORMAT = 'jpg'
    IMAGE_COMPRESS = 50
    USED_FIELDS = ('title', 'unit', 'country', 'year', 'mint', 'mintmark',
        'issuedate', 'type', 'series', 'subjectshort', 'material', 'fineness',
        'diameter', 'thickness', 'weight', 'mintage', 'rarity',
        'obverseimg', 'reverseimg', 'subject', 'price1', 'price2', 'price3', 'price4')

    if os.path.isfile(params['file']):
        os.remove(params['file'])

    db = QSqlDatabase.addDatabase('QSQLITE', 'mobile')
    db.setDatabaseName(params['file'])
    if not db.open():
        print(db.lastError().text())
        QMessageBox.critical(None, "Create mobile collection", "Can't open collection")
        return

    sql = """CREATE TABLE "android_metadata" ("locale" TEXT DEFAULT 'en_US')"""
    QSqlQuery(sql, db)
    sql = """INSERT INTO "android_metadata" VALUES ('en_US')"""
    QSqlQuery(sql, db)

    mobile_settings = {'Version': 1, 'Type': 'MobilePro', 'Filter': params['filter']}

    sql = """CREATE TABLE settings (
        title CHAR NOT NULL UNIQUE,
        value CHAR)"""
    QSqlQuery(sql, db)
    for key, value in mobile_settings.items():
        query = QSqlQuery(db)
        query.prepare("""INSERT INTO settings (title, value)
                VALUES (?, ?)""")
        query.addBindValue(key)
        query.addBindValue(str(value))
        query.exec_()

    sql = """CREATE TABLE updates (
        title CHAR NOT NULL UNIQUE,
        value CHAR)"""
    QSqlQuery(sql, db)

    sql = """INSERT INTO updates (title, value)
                VALUES ('160203', '2016-02-03T10:19:00')"""
    QSqlQuery(sql, db)

    sql = """CREATE TABLE photos (
        id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
        image BLOB)"""
    QSqlQuery(sql, db)

    sql = """CREATE TABLE coins (
        id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
        description_id INTEGER,
        grade INTEGER,
        createdat STRING)"""
    QSqlQuery(sql, db)

    sql = """CREATE INDEX coins_descriptions ON coins(description_id)"""
    QSqlQuery(sql, db)

    sqlFields = []
    fields = CollectionFieldsBase()
    for field in fields:
        if field.name == 'id':
            sqlFields.append('id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT')
        elif field.name == 'image':
            sqlFields.append('image INTEGER')
        elif field.name in USED_FIELDS:
            sqlFields.append("%s %s" % (field.name, Type.toSql(field.type)))

    sql = "CREATE TABLE descriptions (" + ", ".join(sqlFields) + ")"
    QSqlQuery(sql, db)

    while model.canFetchMore():
        model.fetchMore()

    dest_model = QSqlTableModel(None, db)
    dest_model.setEditStrategy(QSqlTableModel.OnManualSubmit)
    dest_model.setTable('descriptions')
    dest_model.select()

    height = 64
    if params['density'] == 'HDPI':
        height *= 1.5
    elif params['density'] == 'XHDPI':
        height *= 2
    elif params['density'] == 'XXHDPI':
        height *= 3
    elif params['density'] == 'XXXHDPI':
        height *= 4
    maxHeight = height * 4

    is_obverse_enabled = params['image'] in (ExportDialog.IMAGE_OBVERSE, ExportDialog.IMAGE_BOTH)
    is_reverse_enabled = params['image'] in (ExportDialog.IMAGE_REVERSE, ExportDialog.IMAGE_BOTH)

    fields = CollectionFieldsBase()
    count = model.rowCount()
    progressDlg = Gui.ProgressDialog("Exporting records",
                                    "Cancel", count, None)

    for i in range(count):
        progressDlg.step()
        if progressDlg.wasCanceled():
            break

        coin = model.record(i)
        if coin.value('status') in ('pass', 'sold'):
            continue

        dest_record = dest_model.record()

        for field in fields:
            if field.name in ('id', 'image', 'obverseimg', 'reverseimg'):
                continue
            if field.name in USED_FIELDS:
                val = coin.value(field.name)
                if val is None or val == '':
                    continue

                dest_record.setValue(field.name, val)

        # Process images
        is_obverse_present = not coin.isNull('obverseimg')
        is_reverse_present = not coin.isNull('reverseimg')
        if is_obverse_present or is_reverse_present:
            obverseImage = QImage()
            reverseImage = QImage()

            if is_obverse_present:
                ba = QtCore.QByteArray()
                buffer = QtCore.QBuffer(ba)
                buffer.open(QtCore.QIODevice.WriteOnly)

                obverseImage.loadFromData(coin.value('obverseimg'))
                if not obverseImage.isNull() and not params['fullimage'] and obverseImage.height() > maxHeight:
                    scaledImage = obverseImage.scaled(maxHeight, maxHeight,
                            Qt.KeepAspectRatio, Qt.SmoothTransformation)
                    scaledImage.save(buffer, IMAGE_FORMAT, IMAGE_COMPRESS)
                    save_data = ba
                else:
                    if not obverseImage.isNull():
                        obverseImage.save(buffer, IMAGE_FORMAT, IMAGE_COMPRESS)
                        save_data = ba
                    else:
                        save_data = coin.value('obverseimg')

                query = QSqlQuery(db)
                query.prepare("""INSERT INTO photos (image)
                        VALUES (?)""")
                query.addBindValue(save_data)
                query.exec_()
                img_id = query.lastInsertId()
                dest_record.setValue('obverseimg', img_id)
            if not obverseImage.isNull():
                obverseImage = obverseImage.scaledToHeight(height,
                                                        Qt.SmoothTransformation)

            if is_reverse_present:
                ba = QtCore.QByteArray()
                buffer = QtCore.QBuffer(ba)
                buffer.open(QtCore.QIODevice.WriteOnly)

                reverseImage.loadFromData(coin.value('reverseimg'))
                if not reverseImage.isNull() and not params['fullimage'] and reverseImage.height() > maxHeight:
                    scaledImage = reverseImage.scaled(maxHeight, maxHeight,
                            Qt.KeepAspectRatio, Qt.SmoothTransformation)
                    scaledImage.save(buffer, IMAGE_FORMAT, IMAGE_COMPRESS)
                    save_data = ba
                else:
                    if not reverseImage.isNull():
                        reverseImage.save(buffer, IMAGE_FORMAT, IMAGE_COMPRESS)
                        save_data = ba
                    else:
                        save_data = coin.value('reverseimg')

                query = QSqlQuery(db)
                query.prepare("""INSERT INTO photos (image)
                        VALUES (?)""")
                query.addBindValue(save_data)
                query.exec_()
                img_id = query.lastInsertId()
                dest_record.setValue('reverseimg', img_id)
            if not reverseImage.isNull():
                reverseImage = reverseImage.scaledToHeight(height,
                                                    Qt.SmoothTransformation)

            if not is_obverse_enabled:
                obverseImage = QImage()
            if not is_reverse_enabled:
                reverseImage = QImage()

            image = QImage(obverseImage.width() + reverseImage.width(),
                                 height, QImage.Format_RGB32)
            image.fill(QColor(Qt.white).rgb())

            paint = QPainter(image)
            if is_obverse_present and is_obverse_enabled:
                paint.drawImage(QtCore.QRectF(0, 0, obverseImage.width(), height), obverseImage,
                                QtCore.QRectF(0, 0, obverseImage.width(), height))
            if is_reverse_present and is_reverse_enabled:
                paint.drawImage(QtCore.QRectF(obverseImage.width(), 0, reverseImage.width(), height), reverseImage,
                                QtCore.QRectF(0, 0, reverseImage.width(), height))
            paint.end()

            ba = QtCore.QByteArray()
            buffer = QtCore.QBuffer(ba)
            buffer.open(QtCore.QIODevice.WriteOnly)
            image.save(buffer, IMAGE_FORMAT, 75)

            query = QSqlQuery(db)
            query.prepare("""INSERT INTO photos (image)
                    VALUES (?)""")
            query.addBindValue(ba)
            query.exec_()
            img_id = query.lastInsertId()
            dest_record.setValue('image', img_id)

        dest_model.insertRecord(-1, dest_record)

    progressDlg.setLabelText("Saving...")
    dest_model.submitAll()

    progressDlg.setLabelText("Compact...")
    QSqlQuery("""UPDATE descriptions
SET
reverseimg = (select t2.id from descriptions t3 join (select id, image from photos group by image having count(*) > 1) t2 on t1.image = t2.image join photos t1 on t3.reverseimg = t1.id where t1.id <> t2.id and t3.id = descriptions.id)
WHERE descriptions.id in (select t3.id from descriptions t3 join (select id, image from photos group by image having count(*) > 1) t2 on t1.image = t2.image join photos t1 on t3.reverseimg = t1.id where t1.id <> t2.id)
""", db)
    QSqlQuery("""UPDATE descriptions
SET
obverseimg = (select t2.id from descriptions t3 join (select id, image from photos group by image having count(*) > 1) t2 on t1.image = t2.image join photos t1 on t3.obverseimg = t1.id where t1.id <> t2.id and t3.id = descriptions.id)
WHERE descriptions.id in (select t3.id from descriptions t3 join (select id, image from photos group by image having count(*) > 1) t2 on t1.image = t2.image join photos t1 on t3.obverseimg = t1.id where t1.id <> t2.id)
""", db)
    QSqlQuery("""UPDATE descriptions
SET
image = (select t2.id from descriptions t3 join (select id, image from photos group by image having count(*) > 1) t2 on t1.image = t2.image join photos t1 on t3.image = t1.id where t1.id <> t2.id and t3.id = descriptions.id)
WHERE descriptions.id in (select t3.id from descriptions t3 join (select id, image from photos group by image having count(*) > 1) t2 on t1.image = t2.image join photos t1 on t3.image = t1.id where t1.id <> t2.id)
""", db)

    QSqlQuery("""DELETE FROM photos
        WHERE id NOT IN (SELECT id FROM photos GROUP BY image)""", db)

    db.close()

    progressDlg.setLabelText("Vacuum...")
    db = QSqlDatabase.addDatabase('QSQLITE', 'mobile')
    db.setDatabaseName(params['file'])
    if not db.open():
        print(db.lastError().text())
        QMessageBox.critical(None, "Create mobile collection", "Can't open collection")
        return
    QSqlQuery("VACUUM", db)
    db.close()

    progressDlg.reset()
コード例 #36
0
class Window(QMainWindow):
    def __init__(self):
        super().__init__()

        title = "Paint Application"
        top = 400
        left = 400
        width = 800
        height = 600
        self.px_p_meter = 100

        icon = "icons/pain.png"

        self.setWindowTitle(title)
        self.setGeometry(top, left, width, height)
        self.setWindowIcon(QIcon(icon))

        self.image = QImage(self.size(), QImage.Format_RGB32)
        self.image.fill(Qt.white)

        self.waypoints = []
        self.drawing = False
        self.brushSize = 5
        self.brushColor = Qt.black
        self.lastPoint = QPoint()

        mainMenu = self.menuBar()
        fileMenu = mainMenu.addMenu("File")
        brushSize = mainMenu.addMenu("Brush Size")
        brushColor = mainMenu.addMenu("Brush Color")
        '''
        saveAction = QAction(QIcon("icons/save.png"), "Save",self)
        saveAction.setShortcut("Ctrl+S")
        fileMenu.addAction(saveAction)
        saveAction.triggered.connect(self.save)
        '''
        exportAction = QAction(QIcon("icons/export.png"), "Export Track", self)
        exportAction.setShortcut("Ctrl+E")
        fileMenu.addAction(exportAction)
        exportAction.triggered.connect(self.exportTrack)

        clearAction = QAction(QIcon("icons/clear.png"), "Clear", self)
        clearAction.setShortcut("Ctrl+C")
        fileMenu.addAction(clearAction)
        clearAction.triggered.connect(self.clear)

        threepxAction = QAction(QIcon("icons/threepx.png"), "3px", self)
        brushSize.addAction(threepxAction)
        threepxAction.triggered.connect(self.threePixel)

        fivepxAction = QAction(QIcon("icons/fivepx.png"), "5px", self)
        brushSize.addAction(fivepxAction)
        fivepxAction.triggered.connect(self.fivePixel)

        sevenpxAction = QAction(QIcon("icons/sevenpx.png"), "7px", self)
        brushSize.addAction(sevenpxAction)
        sevenpxAction.triggered.connect(self.sevenPixel)

        ninepxAction = QAction(QIcon("icons/ninepx.png"), "9px", self)
        brushSize.addAction(ninepxAction)
        ninepxAction.triggered.connect(self.ninePixel)

        blackAction = QAction(QIcon("icons/black.png"), "Black", self)
        blackAction.setShortcut("Ctrl+B")
        brushColor.addAction(blackAction)
        blackAction.triggered.connect(self.blackColor)

        whitekAction = QAction(QIcon("icons/white.png"), "White", self)
        whitekAction.setShortcut("Ctrl+W")
        brushColor.addAction(whitekAction)
        whitekAction.triggered.connect(self.whiteColor)

        redAction = QAction(QIcon("icons/red.png"), "Red", self)
        redAction.setShortcut("Ctrl+R")
        brushColor.addAction(redAction)
        redAction.triggered.connect(self.redColor)

        greenAction = QAction(QIcon("icons/green.png"), "Green", self)
        greenAction.setShortcut("Ctrl+G")
        brushColor.addAction(greenAction)
        greenAction.triggered.connect(self.greenColor)

        yellowAction = QAction(QIcon("icons/yellow.png"), "Yellow", self)
        yellowAction.setShortcut("Ctrl+Y")
        brushColor.addAction(yellowAction)
        yellowAction.triggered.connect(self.yellowColor)

        painter = QPainter(self.image)
        painter.setBrush(Qt.black)
        painter.setPen(QPen(Qt.black, 2, Qt.SolidLine))
        painter.drawLine(10, 50, 10 + self.px_p_meter, 50)

        pen = QPen(Qt.black)
        pen.setWidth(2)
        painter.setPen(pen)

        font = QFont()
        font.setFamily('Times')
        font.setBold(True)
        font.setPointSize(12)
        painter.setFont(font)

        painter.drawText(20 + self.px_p_meter, 55, "1 m")

    def mousePressEvent(self, event):
        if event.button() == Qt.LeftButton:
            #self.drawing = True
            self.lastPoint = event.pos()
            self.waypoints.append([self.lastPoint.x(), self.lastPoint.y()])
            painter = QPainter(self.image)
            painter.setPen(
                QPen(self.brushColor, self.brushSize, Qt.SolidLine,
                     Qt.RoundCap, Qt.RoundJoin))
            painter.drawPoint(self.lastPoint)
            self.update()
            print([self.lastPoint.x(), self.lastPoint.y()])
            #print(self.lastPoint)

    def mouseMoveEvent(self, event):
        if (event.buttons() & Qt.LeftButton) & self.drawing:
            painter = QPainter(self.image)
            painter.setPen(
                QPen(self.brushColor, self.brushSize, Qt.SolidLine,
                     Qt.RoundCap, Qt.RoundJoin))
            painter.drawLine(self.lastPoint, event.pos())
            self.lastPoint = event.pos()
            self.update()

    def mouseReleaseEvent(self, event):
        if event.button() == Qt.LeftButton:
            self.drawing = False

    def paintEvent(self, event):
        canvasPainter = QPainter(self)
        canvasPainter.drawImage(self.rect(), self.image, self.image.rect())

    def save(self):
        filePath, _ = QFileDialog.getSaveFileName(
            self, "Save Image", "",
            "PNG(*.png);;JPEG(*.jpg *.jpeg);;All Files(*.*) ")
        fig, ax1 = plt.subplots(nrows=1, ncols=1, figsize=(10, 10))
        points = 1 / 100 * np.array(self.waypoints)

        ax1.scatter(points[:, 0], points[:, 1])
        if filePath == "":
            return
        self.image.save(filePath)

    def exportTrack(self):
        print("exporting Track")
        fig, ax1 = plt.subplots(nrows=1, ncols=1, figsize=(10, 10))
        points = 1 / self.px_p_meter * np.array(self.waypoints)
        points[:, 0] = points[:, 0] - np.mean(points[:, 0])
        points[:, 1] = -points[:, 1] + np.mean(points[:, 1])
        ax1.scatter(points[:, 0], points[:, 1])
        plt.show()
        name = QFileDialog.getSaveFileName(self, "Save Waypoints", "",
                                           "CSV(*.csv)")
        np.savetxt(name[0], points, delimiter=', ')
        track_lu_table, smax = InterpolateTrack.generatelookuptable(
            "tracks/" + name[0][53:-4])
        r = 0.2
        lencar = 0.06
        trk_plt = plotter(track_lu_table, smax, r, lencar)
        trk_plt.plot_track()
        plt.show()

    def clear(self):
        print("clearing")
        self.image.fill(Qt.white)
        self.waypoints = []
        self.update()

    def threePixel(self):
        self.brushSize = 3

    def fivePixel(self):
        self.brushSize = 5

    def sevenPixel(self):
        self.brushSize = 7

    def ninePixel(self):
        self.brushSize = 9

    def blackColor(self):
        self.brushColor = Qt.black

    def whiteColor(self):
        self.brushColor = Qt.white

    def redColor(self):
        self.brushColor = Qt.red

    def greenColor(self):
        self.brushColor = Qt.green

    def yellowColor(self):
        self.brushColor = Qt.yellow
コード例 #37
0
ファイル: imageitem.py プロジェクト: farisachugthai/qtcalc
    def createImage(self, transform):
        original = QImage(self.image)
        if original.isNull():
            return original

        size = transform.map(QPoint(self.maxWidth, self.maxHeight))
        w = size.x()
        h = size.y()

        # Optimization: if image is smaller than maximum allowed size, just
        # return the loaded image.
        if (
            original.size().height() <= h
            and original.size().width() <= w
            and not self.adjustSize
            and self.scale == 1
        ):
            return original

        # Calculate what the size of the final image will be.
        w = min(w, float(original.size().width()) * self.scale)
        h = min(h, float(original.size().height()) * self.scale)

        adjustx = 1.0
        adjusty = 1.0
        if self.adjustSize:
            adjustx = min(transform.m11(), transform.m22())
            adjusty = max(transform.m22(), adjustx)
            w *= adjustx
            h *= adjusty

        # Create a new image with correct size, and draw original on it.
        image = QImage(int(w + 2), int(h + 2), QImage.Format_ARGB32_Premultiplied)
        image.fill(QColor(0, 0, 0, 0).rgba())
        painter = QPainter(image)
        painter.setRenderHints(QPainter.Antialiasing | QPainter.SmoothPixmapTransform)
        if self.adjustSize:
            painter.scale(adjustx, adjusty)
        if self.scale != 1:
            painter.scale(self.scale, self.scale)
        painter.drawImage(0, 0, original)

        if not self.adjustSize:
            # Blur out edges.
            blur = 30

            if h < original.height():
                brush1 = QLinearGradient(0, h - blur, 0, h)
                brush1.setSpread(QLinearGradient.PadSpread)
                brush1.setColorAt(0.0, QColor(0, 0, 0, 0))
                brush1.setColorAt(1.0, Colors.sceneBg1)
                painter.fillRect(0, int(h) - blur, original.width(), int(h), brush1)

            if w < original.width():
                brush2 = QLinearGradient(w - blur, 0, w, 0)
                brush2.setSpread(QLinearGradient.PadSpread)
                brush2.setColorAt(0.0, QColor(0, 0, 0, 0))
                brush2.setColorAt(1.0, Colors.sceneBg1)
                painter.fillRect(int(w) - blur, 0, int(w), original.height(), brush2)

        return image
コード例 #38
0
ファイル: paint.py プロジェクト: PrajjwalDatir/PaintPyQT5
class Window(QMainWindow):
    def __init__(self):
        super().__init__()

        title = "Prajjwal's Paint Application"
        x = 500
        y = 100
        width = 1080
        height = 720

        icon = "icons/Code_Maniac.jpg"

        self.setWindowTitle(title)
        self.setGeometry(x, y, width, height)
        self.setWindowIcon(QIcon(icon))

        self.image = QImage(self.size(), QImage.Format_RGB32)
        self.image.fill(Qt.white)

        self.drawing = False
        self.brushSize = 2
        self.brushColor = Qt.black
        self.lastPoint = QPoint()

        mainMenu = self.menuBar()
        fileMenu = mainMenu.addMenu("File")
        brushSize = mainMenu.addMenu("Brush Size")
        brushColor = mainMenu.addMenu("Brush Color")
        shapes = mainMenu.addMenu("Add Shapes")

        circleAction = QAction(QIcon("icons/save.png"), "Cicle", self)
        circleAction.setShortcut("Alt+C")
        shapes.addAction(circleAction)
        circleAction.triggered.connect(self.circle)

        rectAction = QAction(QIcon("icons/save.png"), "Rectangle", self)
        rectAction.setShortcut("Alt+R")
        shapes.addAction(rectAction)
        rectAction.triggered.connect(self.rectangle)

        saveAction = QAction(QIcon("icons/save.png"), "Save", self)
        saveAction.setShortcut("Ctrl+S")
        fileMenu.addAction(saveAction)
        saveAction.triggered.connect(self.save)

        clearAction = QAction(QIcon("icons/clear.png"), "Clear", self)
        clearAction.setShortcut("Ctrl+C")
        fileMenu.addAction(clearAction)
        clearAction.triggered.connect(self.clear)

        threepxAction = QAction("3px", self)
        brushSize.addAction(threepxAction)
        threepxAction.triggered.connect(self.threePixel)

        fivepxAction = QAction("5px", self)
        brushSize.addAction(fivepxAction)
        fivepxAction.triggered.connect(self.fivePixel)

        sevenpxAction = QAction("7px", self)
        brushSize.addAction(sevenpxAction)
        sevenpxAction.triggered.connect(self.sevenPixel)

        ninepxAction = QAction("9px", self)
        brushSize.addAction(ninepxAction)
        ninepxAction.triggered.connect(self.ninePixel)

        blackAction = QAction(QIcon("icons/black.png"), "Black", self)
        blackAction.setShortcut("Ctrl+B")
        brushColor.addAction(blackAction)
        blackAction.triggered.connect(self.blackColor)

        whitekAction = QAction(QIcon("icons/white.png"), "White", self)
        whitekAction.setShortcut("Ctrl+W")
        brushColor.addAction(whitekAction)
        whitekAction.triggered.connect(self.whiteColor)

        redAction = QAction(QIcon("icons/red.png"), "Red", self)
        redAction.setShortcut("Ctrl+R")
        brushColor.addAction(redAction)
        redAction.triggered.connect(self.redColor)

        greenAction = QAction(QIcon("icons/green.png"), "Green", self)
        greenAction.setShortcut("Ctrl+G")
        brushColor.addAction(greenAction)
        greenAction.triggered.connect(self.greenColor)

        yellowAction = QAction(QIcon("icons/yellow.png"), "Yellow", self)
        yellowAction.setShortcut("Ctrl+Y")
        brushColor.addAction(yellowAction)
        yellowAction.triggered.connect(self.yellowColor)

    def mousePressEvent(self, event):
        if event.button() == Qt.LeftButton:
            self.drawing = True
            self.lastPoint = event.pos()
            #print(self.lastPoint)

    def exit_paint(self, event):
        if event.type() == KEY_DOWN:
            if event.key() == Qt.Key_Escape:
                self.close()

    def mouseMoveEvent(self, event):
        if (event.buttons() & Qt.LeftButton) & self.drawing:
            painter = QPainter(self.image)
            painter.setPen(
                QPen(self.brushColor, self.brushSize, Qt.SolidLine,
                     Qt.RoundCap, Qt.RoundJoin))
            painter.drawLine(self.lastPoint, event.pos())
            self.lastPoint = event.pos()
            self.update()

    def mouseReleaseEvent(self, event):

        if event.button() == Qt.LeftButton:
            self.drawing = False

    def paintEvent(self, event):
        canvasPainter = QPainter(self)
        canvasPainter.drawImage(self.rect(), self.image, self.image.rect())

    def save(self):
        filePath, _ = QFileDialog.getSaveFileName(
            self, "Save Image", "",
            "PNG(*.png);;JPEG(*.jpg *.jpeg);;All Files(*.*) ")

        if filePath == "":
            return
        self.image.save(filePath)

    def clear(self):
        self.image.fill(Qt.white)
        self.update()

    def threePixel(self):
        self.brushSize = 3

    def fivePixel(self):
        self.brushSize = 5

    def sevenPixel(self):
        self.brushSize = 7

    def ninePixel(self):
        self.brushSize = 9

    def blackColor(self):
        self.brushColor = Qt.black

    def whiteColor(self):
        self.brushColor = Qt.white

    def redColor(self):
        self.brushColor = Qt.red

    def greenColor(self):
        self.brushColor = Qt.green

    def yellowColor(self):
        self.brushColor = Qt.yellow

    def circle(self):
        painter = QPainter(self)
        painter.setPen(QPen(Qt.green, 5, Qt.SolidLine))
        painter.setBrush(QBrush(Qt.green, Qt.SolidPattern))
        painter.drawEllipse(40, 40, 400, 200)
        pass

    def rectangle(self):
        pass
コード例 #39
0
class MaskTransparencyWidget(QWidget):
    def __init__(self, parent, imgPaths, fov_id_list, mask_dir):
        super(MaskTransparencyWidget, self).__init__(parent)

        self.mask_dir = mask_dir
        self.frameIndex = 0

        self.imgPaths = imgPaths
        self.fov_id_list = fov_id_list
        self.fovIndex = 0
        self.fov_id = self.fov_id_list[self.fovIndex]

        self.imgIndex = 0
        self.maskImgPath = self.imgPaths[self.fov_id][self.imgIndex][1]

        # TO DO: check if re-annotated mask exists in training_dir, and present that instead of original mask
        #        make indicator appear if we're re-editing the mask again.
        experiment_name = params['experiment_name']
        original_file_name = self.maskImgPath
        pat = re.compile(
            r'.+(xy\d{3,4})_(p\d{3,4})_.+')  # supports 3- or 4-digit naming
        mat = pat.match(original_file_name)
        fovID = mat.groups()[0]
        peakID = mat.groups()[1]
        fileBaseName = '{}_{}_{}_t{:0=4}.tif'.format(experiment_name, fovID,
                                                     peakID,
                                                     self.frameIndex + 1)
        savePath = os.path.join(self.mask_dir, fileBaseName)

        self.maskStack = io.imread(self.maskImgPath)
        if os.path.isfile(savePath):
            print(
                'Re-annotated mask exists in training directory. Loading it.')
            # add widget to express whether this mask is one you already re-annotated
            # print(self.frameIndex)
            self.maskStack[self.frameIndex, :, :] = io.imread(savePath)
            overwriteSegFile = True
        else:
            overwriteSegFile = False

        img = self.maskStack[self.frameIndex, :, :]
        img[img > 0] = 255
        self.RGBImg = color.gray2rgb(img).astype('uint8')
        self.RGBImg[:, :,
                    1:] = 0  # set GB channels to 0 to make the transarency mask red
        alphaFloat = 0.15
        alphaArray = np.zeros(img.shape, dtype='uint8')
        alphaArray = np.expand_dims(alphaArray, -1)
        self.alpha = int(255 * alphaFloat)
        alphaArray[...] = self.alpha
        self.RGBAImg = np.append(self.RGBImg, alphaArray, axis=-1)

        self.originalHeight, self.originalWidth, self.originalChannelNumber = self.RGBAImg.shape
        self.maskQimage = QImage(self.RGBAImg, self.originalWidth,
                                 self.originalHeight, self.RGBAImg.strides[0],
                                 QImage.Format_RGBA8888).scaled(
                                     1024,
                                     1024,
                                     aspectRatioMode=Qt.KeepAspectRatio)
        self.maskQpixmap = QPixmap(self.maskQimage)

        self.label = QLabel(self)
        self.label.setPixmap(self.maskQpixmap)

        self.drawing = False
        self.brushSize = 2
        self.brushColor = QColor(0, 0, 0, self.alpha)
        self.lastPoint = QPoint()

    def mousePressEvent(self, event):
        if event.button() == Qt.LeftButton:
            self.drawing = True
            self.lastPoint = event.pos()

    def mouseMoveEvent(self, event):
        if (event.buttons() & Qt.LeftButton) & self.drawing:

            # make the mouse position the center of a circle whose radius is defined as self.brushSize
            rr, cc = draw.circle(event.y(), event.x(), self.brushSize)
            for pix in zip(rr, cc):
                rowIndex = pix[0]
                colIndex = pix[1]
                self.maskQimage.setPixelColor(colIndex, rowIndex,
                                              self.brushColor)

            self.maskQpixmap = QPixmap(self.maskQimage)
            self.label.setPixmap(self.maskQpixmap)
            self.lastPoint = event.pos()
            self.update()

    def mouseReleaseEvent(self, event):
        if event.button == Qt.LeftButton:
            self.drawing = False

    def save(self):
        filePath, _ = QFileDialog.getSaveFileName(
            self, "Save Image", "",
            "PNG(*.png);;JPEG(*.jpg *.jpeg);;TIFF(*.tif *.tiff);;ALL FILES(*.*)"
        )
        if filePath == "":
            return
        saveImg = self.maskQimage.convertToFormat(
            QImage.Format_Grayscale8).scaled(self.originalWidth,
                                             self.originalHeight)
        qimgHeight = saveImg.height()
        qimgWidth = saveImg.width()

        for rowIndex in range(qimgHeight):

            for colIndex in range(qimgWidth):
                pixVal = qGray(saveImg.pixel(colIndex, rowIndex))
                if pixVal > 0:
                    saveImg.setPixelColor(colIndex, rowIndex, QColor(1, 1, 1))
                    pixVal = qGray(saveImg.pixel(colIndex, rowIndex))

        saveImg.save(filePath)

    def buttonSave(self):
        experiment_name = params['experiment_name']
        original_file_name = self.maskImgPath
        pat = re.compile(
            r'.+(xy\d{3,4})_(p\d{3,4})_.+')  # supports 3- or 4-digit naming
        mat = pat.match(original_file_name)
        fovID = mat.groups()[0]
        peakID = mat.groups()[1]
        fileBaseName = '{}_{}_{}_t{:0=4}.tif'.format(experiment_name, fovID,
                                                     peakID,
                                                     self.frameIndex + 1)
        savePath = os.path.join(self.mask_dir, fileBaseName)
        # labelSavePath = os.path.join(params['seg_dir'],fileBaseName)
        print("Saved binary mask image as: ", savePath)

        if not os.path.isdir(self.mask_dir):
            os.makedirs(self.mask_dir)

        # saveImg = self.maskQimage.convertToFormat(QImage.Format_Grayscale8)

        # This was bugging out and making the image not the same size as it started
        # saveImg = self.maskQimage.convertToFormat(QImage.Format_Grayscale8).scaled(self.originalWidth,self.originalHeight,aspectRatioMode=Qt.KeepAspectRatio)

        saveImg = self.maskQimage.convertToFormat(
            QImage.Format_Grayscale8).scaled(self.originalWidth,
                                             self.originalHeight)

        qimgHeight = saveImg.height()
        qimgWidth = saveImg.width()

        print(self.originalHeight, self.originalWidth, qimgHeight, qimgWidth)

        saveArr = np.zeros((qimgHeight, qimgWidth), dtype='uint8')
        for rowIndex in range(qimgHeight):

            for colIndex in range(qimgWidth):
                pixVal = qGray(saveImg.pixel(colIndex, rowIndex))
                if pixVal > 0:
                    saveArr[rowIndex, colIndex] = 1

        io.imsave(savePath, saveArr)
        # labelArr = measure.label(saveArr, connectivity=1)
        # labelArr = labelArr.astype('uint8')

        # print(labelSavePath)
        # io.imsave(labelSavePath,labelArr)

    def reset(self):
        self.maskQimage = QImage(self.RGBAImg, self.originalWidth,
                                 self.originalHeight, self.RGBAImg.strides[0],
                                 QImage.Format_RGBA8888).scaled(
                                     1024,
                                     1024,
                                     aspectRatioMode=Qt.KeepAspectRatio)
        self.maskQpixmap = QPixmap(self.maskQimage)
        self.label.setPixmap(self.maskQpixmap)
        self.update()

    def clear(self):
        self.imgFill = QColor(0, 0, 0, self.alpha)
        self.maskQimage = QImage(self.RGBAImg, self.originalWidth,
                                 self.originalHeight, self.RGBAImg.strides[0],
                                 QImage.Format_RGBA8888).scaled(
                                     1024,
                                     1024,
                                     aspectRatioMode=Qt.KeepAspectRatio)
        self.maskQimage.fill(self.imgFill)
        self.maskQpixmap = QPixmap(self.maskQimage)
        self.label.setPixmap(self.maskQpixmap)
        self.update()

    def onePx(self):
        self.brushSize = 1

    def threePx(self):
        self.brushSize = 3

    def fivePx(self):
        self.brushSize = 5

    def sevenPx(self):
        self.brushSize = 7

    def ninePx(self):
        self.brushSize = 9

    def blackColor(self):
        self.brushColor = QColor(0, 0, 0, self.alpha)

    def redColor(self):
        self.brushColor = QColor(255, 0, 0, self.alpha)

    def whiteColor(self):
        self.brushColor = QColor(255, 255, 255, self.alpha)

    # def setFOVPeakFrameIndex(self,frame_index,peak_index,fov_id):
    #     self.frameIndex = frame_index
    #     self.fov_id = fov_id
    #     self.imgIndex = peak_id

    def setImg(self, img):
        img[img > 0] = 255
        self.RGBImg = color.gray2rgb(img).astype('uint8')
        self.RGBImg[:, :,
                    1:] = 0  # set green and blue channels to 0 to make the transarency mask red
        alphaFloat = 0.25
        alphaArray = np.zeros(img.shape, dtype='uint8')
        alphaArray = np.expand_dims(alphaArray, -1)
        self.alpha = int(255 * alphaFloat)
        alphaArray[...] = self.alpha
        self.RGBAImg = np.append(self.RGBImg, alphaArray, axis=-1)

        self.originalHeight, self.originalWidth, self.originalChannelNumber = self.RGBAImg.shape
        self.maskQimage = QImage(self.RGBAImg, self.originalWidth,
                                 self.originalHeight, self.RGBAImg.strides[0],
                                 QImage.Format_RGBA8888).scaled(
                                     1024,
                                     1024,
                                     aspectRatioMode=Qt.KeepAspectRatio)
        self.maskQpixmap = QPixmap(self.maskQimage)
        self.label.setPixmap(self.maskQpixmap)

    def next_frame(self):
        self.frameIndex += 1
        try:
            experiment_name = params['experiment_name']
            original_file_name = self.maskImgPath
            pat = re.compile(r'.+(xy\d{3,4})_(p\d{3,4})_.+'
                             )  # supports 3- or 4-digit naming
            mat = pat.match(original_file_name)
            fovID = mat.groups()[0]
            peakID = mat.groups()[1]
            fileBaseName = '{}_{}_{}_t{:0=4}.tif'.format(
                experiment_name, fovID, peakID, self.frameIndex + 1)
            savePath = os.path.join(self.mask_dir, fileBaseName)

            if os.path.isfile(savePath):
                print(
                    'Re-annotated mask exists in training directory. Loading it.'
                )
                # add widget to express whether this mask is one you already re-annotated
                self.maskStack[self.frameIndex, :, :] = io.imread(savePath)
            img = self.maskStack[self.frameIndex, :, :]
        except IndexError:
            sys.exit(
                "You've already edited the last frame's mask. Write in functionality to increment to next peak_id now!"
            )

        self.setImg(img)

    def prior_frame(self):
        self.frameIndex -= 1
        try:
            experiment_name = params['experiment_name']
            original_file_name = self.maskImgPath
            pat = re.compile(r'.+(xy\d{3,4})_(p\d{3,4})_.+'
                             )  # supports 3- or 4-digit naming
            mat = pat.match(original_file_name)
            fovID = mat.groups()[0]
            peakID = mat.groups()[1]
            fileBaseName = '{}_{}_{}_t{:0=4}.tif'.format(
                experiment_name, fovID, peakID, self.frameIndex + 1)
            savePath = os.path.join(self.mask_dir, fileBaseName)

            if os.path.isfile(savePath):
                print(
                    'Re-annotated mask exists in training directory. Loading it.'
                )
                # add widget to express whether this mask is one you already re-annotated
                self.maskStack[self.frameIndex, :, :] = io.imread(savePath)
            img = self.maskStack[self.frameIndex, :, :]
        except IndexError:
            sys.exit(
                "You've already edited the last frame's mask. Write in functionality to increment to next peak_id now!"
            )
        self.setImg(img)

    def next_peak(self):
        self.imgIndex += 1
        self.maskImgPath = self.imgPaths[self.fov_id][self.imgIndex][1]
        self.maskStack = io.imread(self.maskImgPath)

        self.frameIndex = 0

        experiment_name = params['experiment_name']
        original_file_name = self.maskImgPath
        pat = re.compile(
            r'.+(xy\d{3,4})_(p\d{3,4})_.+')  # supports 3- or 4-digit naming
        mat = pat.match(original_file_name)
        fovID = mat.groups()[0]
        peakID = mat.groups()[1]
        fileBaseName = '{}_{}_{}_t{:0=4}.tif'.format(experiment_name, fovID,
                                                     peakID,
                                                     self.frameIndex + 1)
        savePath = os.path.join(self.mask_dir, fileBaseName)

        if os.path.isfile(savePath):
            print(
                'Re-annotated mask exists in training directory. Loading it.')
            # add widget to express whether this mask is one you already re-annotated
            self.maskStack[self.frameIndex, :, :] = io.imread(savePath)

        img = self.maskStack[self.frameIndex, :, :]
        self.setImg(img)

    def prior_peak(self):
        self.imgIndex -= 1
        self.maskImgPath = self.imgPaths[self.fov_id][self.imgIndex][1]
        self.maskStack = io.imread(self.maskImgPath)

        self.frameIndex = 0

        experiment_name = params['experiment_name']
        original_file_name = self.maskImgPath
        pat = re.compile(
            r'.+(xy\d{3,4})_(p\d{3,4})_.+')  # supports 3- or 4-digit naming
        mat = pat.match(original_file_name)
        fovID = mat.groups()[0]
        peakID = mat.groups()[1]
        fileBaseName = '{}_{}_{}_t{:0=4}.tif'.format(experiment_name, fovID,
                                                     peakID,
                                                     self.frameIndex + 1)
        savePath = os.path.join(self.mask_dir, fileBaseName)

        if os.path.isfile(savePath):
            print(
                'Re-annotated mask exists in training directory. Loading it.')
            # add widget to express whether this mask is one you already re-annotated
            self.maskStack[self.frameIndex, :, :] = io.imread(savePath)
        img = self.maskStack[self.frameIndex, :, :]
        self.setImg(img)

    def next_fov(self):
        self.fovIndex += 1
        self.fov_id = self.fov_id_list[self.fovIndex]

        self.imgIndex = 0
        self.maskImgPath = self.imgPaths[self.fov_id][self.imgIndex][1]
        self.maskStack = io.imread(self.maskImgPath)

        self.frameIndex = 0

        experiment_name = params['experiment_name']
        original_file_name = self.maskImgPath
        pat = re.compile(
            r'.+(xy\d{3,4})_(p\d{3,4})_.+')  # supports 3- or 4-digit naming
        mat = pat.match(original_file_name)
        fovID = mat.groups()[0]
        peakID = mat.groups()[1]
        fileBaseName = '{}_{}_{}_t{:0=4}.tif'.format(experiment_name, fovID,
                                                     peakID,
                                                     self.frameIndex + 1)
        savePath = os.path.join(self.mask_dir, fileBaseName)

        if os.path.isfile(savePath):
            print(
                'Re-annotated mask exists in training directory. Loading it.')
            # add widget to express whether this mask is one you already re-annotated
            self.maskStack[self.frameIndex, :, :] = io.imread(savePath)
        img = self.maskStack[self.frameIndex, :, :]
        self.setImg(img)

    def prior_fov(self):
        self.fovIndex -= 1
        self.fov_id = self.fov_id_list[self.fovIndex]

        self.imgIndex = 0
        self.maskImgPath = self.imgPaths[self.fov_id][self.imgIndex][1]
        self.maskStack = io.imread(self.maskImgPath)

        self.frameIndex = 0
        experiment_name = params['experiment_name']
        original_file_name = self.maskImgPath
        pat = re.compile(
            r'.+(xy\d{3,4})_(p\d{3,4})_.+')  # supports 3- or 4-digit naming
        mat = pat.match(original_file_name)
        fovID = mat.groups()[0]
        peakID = mat.groups()[1]
        fileBaseName = '{}_{}_{}_t{:0=4}.tif'.format(experiment_name, fovID,
                                                     peakID,
                                                     self.frameIndex + 1)
        savePath = os.path.join(self.mask_dir, fileBaseName)

        if os.path.isfile(savePath):
            print(
                'Re-annotated mask exists in training directory. Loading it.')
            # add widget to express whether this mask is one you already re-annotated
            self.maskStack[self.frameIndex, :, :] = io.imread(savePath)
        img = self.maskStack[self.frameIndex, :, :]
        self.setImg(img)
コード例 #40
0
 def _create_image(self):
     image = QImage(80, 60, QImage.Format_RGB32)
     image.fill(Qt.green)
     return image
コード例 #41
0
class Window(QMainWindow):
    def __init__(self):
        super().__init__()
        self.buildGUI()
        self.graph = Graph()
        self.countCity = 0
        self.countCom = 0
        self.isHandle = False
        self.countParam = 2
        self.selectedTop = []  # list for two connected tops type - Top

    def buildGUI(self):
        self.resize(1000, 750)

        self.image = QImage(2000, 2000, QImage.Format_RGB32)
        self.image.fill(Qt.white)
        self.brushSize = 2
        self.brushColor = Qt.blue

        self.initNeed()  # инициализируем нужные настройки

        self.statusBar()
        self.createWidget()
        self.center()
        self.setWindowTitle('Нахождение кратчайшевого пути')
        self.setWindowIcon(QIcon('iconCat.png'))
        self.setContextMenuPolicy(Qt.NoContextMenu)
        self.show()

    def initNeed(self):
        painter = QPainter(self.image)
        painter.drawText(QPointF(10, 50), "Начальная вершина: ")
        painter.drawText(QPointF(10, 70), "Конечная вершина: ")

    def mousePressEvent(self, event):
        selected = False  # typ - boolean
        topCur = Top(event.pos(), self.graph.size() + 1)  # type - Top
        point = event.pos()  # type - QPointF
        painter = QPainter(self.image)

        for top in self.graph.getSetV():
            if top.inside(point):
                self.brushColor = Qt.red  # selected
                selected = True
                topCur = top
                if top in self.selectedTop:
                    self.brushColor = Qt.blue
                    self.selectedTop.remove(top)
                else:
                    self.selectedTop.append(top)  # add in selected list

                self.pen(painter)
                painter.drawEllipse(topCur.x() - Constant.rad / 2,
                                    topCur.y() - Constant.rad / 2,
                                    Constant.rad, Constant.rad)

                break

        if event.button() == Qt.LeftButton:

            # if not selected top, then draw
            if not selected:
                # create the top of the graph and installed of the color pen
                self.brushColor = Qt.blue
                self.graph.add(topCur)
                self.countCity = self.countCity + 1
                painter.drawText(point, str(topCur.getNumber()))
                self.pen(painter)
                painter.drawEllipse(topCur.x() - Constant.rad / 2,
                                    topCur.y() - Constant.rad / 2,
                                    Constant.rad, Constant.rad)

            # create the line
            if len(self.selectedTop) == 2:
                self.brushColor = Qt.green
                self.pen(painter)
                top1 = self.selectedTop.pop(1)  # type - Top
                top2 = self.selectedTop.pop(0)

                # check for excisting the road
                #if not top1.exsitRoad(top2):
                if not self.graph.exsitRoad(top1, top2):
                    painter.drawLine(top1.x(), top1.y(), top2.x(), top2.y())

                    # target - add first top (top1) connected top (top2) in the list
                    # bilaterial
                    if self.isHandle:
                        self.instalParametDialog()
                        self.brushColor = Qt.black
                        self.pen(painter)
                        param = []
                        for k in range(self.countParam):
                            param.append(int(self.parametrs[k].text()))
                            painter.drawText(
                                QPointF(
                                    (top1.x() + top2.x()) / 2 + 5,
                                    (top1.y() + top2.y()) / 2 - 5 + 20 * k),
                                self.parametrs[k].text())
                        # закомменчено для варианта работы со списокм смежности
                        #top1.add(top2, param)
                        #top2.add(top1, param)
                        self.graph.addConnection(top1, top2, param)

                    else:
                        param = []
                        for i in range(self.countParam):
                            param.append(random.randint(1, 100))
                        # добавлено
                        self.graph.addConnection(top1, top2, param)
                        #top1.add(top2, param)
                        #top2.add(top1, param)

                        self.brushColor = Qt.black
                        self.pen(painter)
                        for k in range(self.countParam):
                            painter.drawText(
                                QPointF(
                                    (top1.x() + top2.x()) / 2 + 5,
                                    (top1.y() + top2.y()) / 2 - 5 + 20 * k),
                                "p=" + str(param[k]))

                self.brushColor = Qt.blue
                self.pen(painter)
                painter.drawEllipse(top1.x() - Constant.rad / 2,
                                    top1.y() - Constant.rad / 2, Constant.rad,
                                    Constant.rad)
                painter.drawEllipse(top2.x() - Constant.rad / 2,
                                    top2.y() - Constant.rad / 2, Constant.rad,
                                    Constant.rad)

        self.update()

    def paintEvent(self, event):
        canvasPainter = QPainter(self)
        canvasPainter.drawImage(self.image.rect(), self.image,
                                self.image.rect())

    def pen(self, painter):
        painter.setPen(
            QPen(self.brushColor, self.brushSize, Qt.SolidLine, Qt.RoundCap,
                 Qt.RoundJoin))  # installed the pen

    def createWidget(self):
        exitAction = QAction(
            QIcon('iconCat.png'), '&Выход',
            self)  # create action, install icon, text and parent(where it is)
        exitAction.setShortcut('Ctrl+Q')  # hot keys
        exitAction.setStatusTip('Выйти из приложения')  # tip
        exitAction.triggered.connect(qApp.quit)

        self.toolbar = self.addToolBar('Exit')
        self.toolbar.addAction(exitAction)

        createBut = QPushButton('Создать')
        createBut.setShortcut('Ctrl+N')
        createBut.setToolTip('Настройки для графа')
        runBut = QPushButton('Запуск')  # graph is generated, find the path
        runBut.setShortcut('Ctrl+R')
        runBut.setToolTip('Найти путь')
        clear = QPushButton('Удалить')
        clear.setShortcut('Delete')
        clear.setToolTip('Очистить')
        infoBut = QPushButton("Инфо")
        infoBut.setShortcut('Ctrl+I')
        infoBut.setToolTip('Информация о программе')

        createBut.clicked.connect(self.on_click)
        runBut.clicked.connect(
            self.click_run)  # start the work of the basic target program
        clear.clicked.connect(self.click_del)
        infoBut.clicked.connect(self.click_info)

        toolbar = self.addToolBar('Exit')
        # toolbar.addWidget(createBut) потом добавить обратно
        toolbar.addWidget(runBut)
        toolbar.addWidget(clear)
        toolbar.addWidget(infoBut)

    def drawPath(self, path, painter):
        #self.brushColor = Qt.red
        #painter = QPainter(self.image)
        self.pen(painter)

        for j in range(len(path) - 1):
            top1 = self.graph.listV[path[j + 1] - 1]  # type - Top
            top2 = self.graph.listV[path[j] - 1]
            painter.drawLine(top1.x(), top1.y(), top2.x(), top2.y())

        if len(path) != 0:
            start = path[0]
            end = path[len(path) - 1]
            self.brushColor = Qt.black
            self.pen(painter)
            top = self.graph.listV[start - 1]
            painter.drawEllipse(top.x() - Constant.rad / 2,
                                top.y() - Constant.rad / 2, Constant.rad,
                                Constant.rad)
            top = self.graph.listV[end - 1]
            painter.drawEllipse(top.x() - Constant.rad / 2,
                                top.y() - Constant.rad / 2, Constant.rad,
                                Constant.rad)

        self.update()

    @pyqtSlot()
    def on_click(self):
        self.showdialog()

    @pyqtSlot()
    def clickSaveSettin(self):
        self.d.close()

    def handleInput(self, state):
        if state == Qt.Checked:
            self.isHandle = True
            #self.countParam = 0

    @pyqtSlot()
    def click_info(self):
        infoDialog = QDialog()
        aboutMe = QTextEdit(Constant.info)

        grid = QGridLayout()
        grid.setSpacing(10)
        grid.addWidget(aboutMe, 0, 0)
        infoDialog.setLayout(grid)

        infoDialog.resize(200, 200)
        infoDialog.setWindowTitle("Input parametrs")
        infoDialog.setWindowModality(Qt.ApplicationModal)
        infoDialog.exec_()

    @pyqtSlot()
    def click_run(self):
        start = 1
        end = self.graph.size()

        if len(self.selectedTop) == 2:

            top1 = self.selectedTop.pop(1)  # type - Top
            top2 = self.selectedTop.pop(0)
            start = top1.getNumber()
            end = top2.getNumber()

            if start > end:
                a = start
                start = end
                end = a

            self.graph.initData()
            self.graph.deystra(start)
            path = self.graph.printPath(start, end,
                                        self.graph.parent)  # last top

        else:
            self.graph.initData()
            # закоменченные строки это правка в оригинале были
            # countCom = self.graph.countComponent()
            # self.statusBar().showMessage(str(countCom))

            #self.graph.initData() # можно убрать в метое есть проверка нужна ли инициализация
            #for x in self.graph.beginComponent:
            self.graph.deystra(1)
            path = self.graph.printPath(start, end,
                                        self.graph.parent)  # last top

        if len(path) == 1 or len(path) == 0:
            print('Not path')
            self.statusBar().showMessage('Not path')
        else:
            self.brushColor = Qt.red
            painter = QPainter(self.image)
            painter.drawText(QPointF(160, 50), str(start))
            painter.drawText(QPointF(160, 70), str(end))
            self.drawPath(path, painter)  # type - List<int>
            self.statusBar().showMessage(
                str(path) + " = " + str(self.graph.dist[self.graph.size()]))

    # TODO: найти пересекающиеся ребра и восстановить их
    @pyqtSlot()
    def click_del(self):
        if len(self.selectedTop) != 0:
            for x in self.selectedTop:
                self.brushColor = Qt.white
                painter = QPainter(self.image)
                self.pen(painter)
                #clear deleting top
                painter.drawEllipse(x.x() - Constant.rad / 2,
                                    x.y() - Constant.rad / 2, Constant.rad,
                                    Constant.rad)

                # clear conection lines
                for rib in x.list:
                    painter.drawLine(rib.to.x(), rib.to.y(), x.x(), x.y())

                    for k in range(self.countParam):
                        painter.eraseRect(
                            QRectF((x.x() + rib.to.x()) / 2 + 5,
                                   (x.y() + rib.to.y()) / 2 - 15, 50,
                                   10 * self.countParam))
                painter.eraseRect(
                    QRectF(x.x() - 15,
                           x.y() - 15, Constant.rad * 2, Constant.rad * 2))

                # restore adjacent circles
                self.brushColor = Qt.blue
                self.pen(painter)
                for rib in x.list:
                    painter.drawEllipse(rib.to.x() - Constant.rad / 2,
                                        rib.to.y() - Constant.rad / 2,
                                        Constant.rad, Constant.rad)
                    self.brushColor = Qt.black
                    self.pen(painter)
                    painter.drawText(QPointF(rib.to.x(), rib.to.y()),
                                     str(rib.to.getNumber()))

                self.graph.delete(x)
            self.selectedTop.clear()
        else:
            self.graph.deleteAll()
            self.image.fill(Qt.white)
            self.countCom = 0
            self.countCity = 0

        self.initNeed()
        self.update()

    @pyqtSlot()
    def clickOk(self):
        # at first draw tops
        self.d.close()
        if self.countCity == 0:
            self.countCity = 5
        if self.countCom == 0:
            self.countCom = 5
        if self.countParam == 0:
            self.countParam = 1
        if self.countCom > (self.countCity * (self.countCity - 1)) / 2:
            self.statusBar().showMessage('Too many connections')
            return

        painter = QPainter(self.image)
        width = self.width()
        height = self.height()
        flagInside = False

        i = 0
        while i < self.countCity:
            pos = QPointF(
                random.randint(Constant.rad * 2, width - Constant.rad * 2),
                random.randint(Constant.rad * 2, height - Constant.rad * 2))
            for top in self.graph.getSetV():
                if top.inside(pos):

                    flagInside = True
                    break

            if not flagInside:
                top = Top(pos, self.graph.size() + 1)
                self.graph.add(top)

                self.brushColor = Qt.black
                self.pen(painter)
                painter.drawText(pos, str(top.getNumber()))

                self.brushColor = Qt.blue
                self.pen(painter)
                painter.drawEllipse(top.x() - Constant.rad / 2,
                                    top.y() - Constant.rad / 2, Constant.rad,
                                    Constant.rad)
                i = i + 1

            flagInside = False

        # draw connection
        i = 0
        while i < self.countCom:
            self.brushColor = Qt.green
            self.pen(painter)

            a = random.randint(0, self.graph.size() - 1)
            top1 = self.graph.listV[a]  # type - Top
            b = random.randint(0, self.graph.size() - 1)
            if a == b:
                if a + 1 == self.graph.size():
                    b = b - 1
                else:
                    b = b + 1
            top2 = self.graph.listV[b]

            # check for excisting the road
            if not top1.exsitRoad(top2):
                painter.drawLine(top1.x(), top1.y(), top2.x(), top2.y())

                # count parametres
                param = []
                for j in range(self.countParam):
                    param.append(random.randint(1, 100))
                top1.add(top2, param)
                top2.add(top1, param)

                self.brushColor = Qt.black
                self.pen(painter)

                for k in range(self.countParam):
                    p = str(param[k])
                    painter.drawText(
                        QPointF((top1.x() + top2.x()) / 2 + 5,
                                (top1.y() + top2.y()) / 2 - 5 + 20 * k), p)

                i = i + 1

        self.update()

    def autoCheckBox(self, state):
        if state == Qt.Checked:
            self.countCity = random.randint(2, 10)
            a = int((self.countCity * (self.countCity - 1)) / 2)
            self.countCom = random.randint(1, a)
            self.countParam = random.randint(0, 3)

    def editCity(self):
        if len(self.countCityF.text()) != 0:
            self.countCity = int(self.countCityF.text())

    def editCom(self):
        self.countCom = int(self.countCommunF.text())

    def editParam(self):
        self.countParam = int(self.countParamF.text())

    def center(self):
        position = self.frameGeometry()  #get rectangle our app
        cnrScreen = QDesktopWidget().availableGeometry().center(
        )  # get the center point on the screen
        position.moveCenter(cnrScreen)  # rect put on the center
        self.move(position.topLeft())  # shift app

    # доделать динамическое обновление параметров
    @pyqtSlot()
    def inputToFieldPar(self):
        line = QLineEdit(self.parDial)
        self.parametrs.append(line)
        grid = self.parDial.layout()
        grid.addWidget(line, len(self.parametrs), 0)
        line.returnPressed.connect(self.inputToFieldPar)

    @pyqtSlot()
    def saveParam(self):
        self.parDial.close()

    # диалог, где  вручную вводим параметры
    def instalParametDialog(self):
        self.parDial = QDialog()
        self.parametrs = []

        grid = QGridLayout()
        grid.setSpacing(10)
        countPara = self.countParam

        for i in range(countPara):

            line = QLineEdit('0', self.parDial)
            grid.addWidget(line, i + 1, 0)
            self.parametrs.append(line)

    # self.parametrs[0].returnPressed.connect(self.inputToFieldPar)

        saveParam = QPushButton("Save", self.parDial)
        grid.addWidget(saveParam, countPara + 1, 1)
        saveParam.clicked.connect(self.saveParam)
        self.parDial.setLayout(grid)
        self.parDial.resize(150, 150)
        self.parDial.setWindowTitle("Input parametrs")
        self.parDial.setWindowModality(Qt.ApplicationModal)
        self.parDial.exec_()

    def showdialog(self):
        self.d = QDialog()
        self.countCityF = QLineEdit(self.d)
        self.countCommunF = QLineEdit(self.d)
        self.countParamF = QLineEdit(self.d)
        isHandleInputF = QCheckBox('')
        autoGenC = QCheckBox('Авто')
        ok = QPushButton("ОК", self.d)
        saveSetting = QPushButton("Сохранить", self.d)
        saveSetting.setMaximumSize(ok.width(), ok.height())

        grid = QGridLayout()
        grid.setSpacing(10)

        grid.addWidget(QLabel('Желаемое количество городов:', self.d), 1, 0)
        grid.addWidget(self.countCityF, 1, 1)
        grid.addWidget(QLabel('Желаемое количество связей', self.d), 2, 0)
        grid.addWidget(self.countCommunF, 2, 1)
        grid.addWidget(QLabel('Желаемое количество параметров', self.d), 3, 0)
        grid.addWidget(self.countParamF, 3, 1)
        grid.addWidget(QLabel('Сгенерировать:', self.d), 4, 0)
        grid.addWidget(autoGenC, 4, 1)
        grid.addWidget(QLabel('Ручная настройка параметров?', self.d), 5, 0)
        grid.addWidget(isHandleInputF, 5, 1)
        grid.addWidget(saveSetting, 6, 0)
        grid.addWidget(ok, 6, 1)

        ok.clicked.connect(self.clickOk)
        saveSetting.clicked.connect(self.clickSaveSettin)
        autoGenC.stateChanged.connect(self.autoCheckBox)
        isHandleInputF.stateChanged.connect(self.handleInput)
        self.countCityF.editingFinished.connect(self.editCity)
        self.countCommunF.editingFinished.connect(self.editCom)
        self.countParamF.editingFinished.connect(self.editParam)

        self.d.setLayout(grid)
        self.d.resize(150, 150)
        self.d.setWindowTitle("Настройка графа")
        self.d.setWindowModality(Qt.ApplicationModal)
        self.d.exec_()
コード例 #42
0
ファイル: lab9.py プロジェクト: wh75er/computer_graphics
class Window(QtWidgets.QMainWindow):
    def __init__(self):
        QtWidgets.QWidget.__init__(self)
        uic.loadUi("window.ui", self)
        self.setMouseTracking(True)
        self.scene = QtWidgets.QGraphicsScene(0, 0, 520, 520)
        self.view.setScene(self.scene)
        self.image = QImage(520, 520, QImage.Format_ARGB32_Premultiplied)
        self.pen = QPen(black)

        self.polygon = []
        self.cut = []
        self.mode = None
        self.lock = None

        self.line_2.setEnabled(False)

        self.click_check = False
        self.start_point = None
        self.prev_point = None

        self.clean.clicked.connect(lambda: self.clean_on_click_button(self))
        self._polygon.clicked.connect(lambda: self.add_line_mode(self))
        self.line_2.clicked.connect(lambda: self.add_par_line(self))
        self._lock.clicked.connect(lambda: self.lock_on_click_button(self))
        self.paint.clicked.connect(lambda: self.paint_on_click_button(self))
        self.cutter.clicked.connect(lambda: self.add_cutter_mode(self))

        self.scene.installEventFilter(self)

#-----------------   click event   ------------------------------------

    def eventFilter(self, object, event):
        if event.type() == QtCore.QEvent.GraphicsSceneMousePress:
            point = event.scenePos()
            if (self.mode == "line_mode"):
                self.add_line(event.scenePos())
            if (self.mode == "cutter_mode"):
                self.add_cutter(event.scenePos())
            self.add_point_mouse(point)

        return False

    def add_point_mouse(self, point):
        self.coord.setText("X: " + str(point.x()) + "\nY: " + str(point.y()))
        #print("coords : ", point.x(), point.y());

    def add_line(self, point):
        #print("line coords : ", point.x(), point.y());

        if self.lock:
            line = []
            line.append(self.prev_point)
            line.append(point)
            if line not in self.polygon:
                self.pen.setColor(blue)
                self.add_row(line, self.table_polygon)
                self.polygon.append(line)
                self.scene.addLine(line[0].x(), line[0].y(), line[1].x(),
                                   line[1].y(), self.pen)
            self.prev_point = point
        else:
            self.lock = True
            self.start_point = point
            self.prev_point = point

    def add_cutter(self, point):
        #print("cutter coords : ", point.x(), point.y());

        if self.lock:
            line = []
            line.append(self.prev_point)
            line.append(point)
            if line not in self.cut:
                self.add_row(line, self.table_cut)
                self.cut.append(line)
                self.scene.addLine(line[0].x(), line[0].y(), line[1].x(),
                                   line[1].y(), self.pen)
            self.prev_point = point
        else:
            self.lock = True
            self.start_point = point
            self.prev_point = point

#-----------------   buttons   ------------------------------------

    def add_line_mode(self, win):
        self.mode = None if self.mode != None else "line_mode"
        self.button_mode_set()
        self.click_check = False

    def add_cutter_mode(self, win):
        self.mode = None if self.mode != None else "cutter_mode"
        self.button_mode_set()
        self.click_check = False

    def lock_on_click_button(self, win):
        print("locked")
        if self.prev_point and self.lock:
            line = []
            line.append(self.prev_point)
            line.append(self.start_point)
            if self.mode == "cutter_mode":
                self.add_row(line, self.table_cut)
                self.cut.append(line)
                self.scene.addLine(self.prev_point.x(), self.prev_point.y(),
                                   self.start_point.x(), self.start_point.y(),
                                   self.pen)
                self.prev_point = None
                self.start_point = None
                self.lock = None
                self.pen.setColor(black)

            if self.mode == "line_mode":
                self.add_row(line, self.table_polygon)
                self.polygon.append(line)
                self.scene.addLine(self.prev_point.x(), self.prev_point.y(),
                                   self.start_point.x(), self.start_point.y(),
                                   self.pen)
                self.prev_point = None
                self.start_point = None
                self.lock = None
                self.pen.setColor(black)

    def paint_on_click_button(self, win):
        if not self.cut or not self.polygon:
            print("Check your input data to continue...")
            return

        self.pen.setColor(red)
        self.make_cut()
        self.pen.setColor(blue)

    def clean_on_click_button(self, win):
        self.line_2.setEnabled(False)
        self.scene.clear()
        self.polygon = []
        self.cut = []
        self.image.fill(white)
        self.pen.setColor(black)
        self.table_clean(self.table_cut)
        self.table_clean(self.table_polygon)

    def add_par_line(self, win):
        if not self.cut:
            return

        print("parrallel lines")


#-----------------   methods   ------------------------------------

    def checkConvexPolygon(self):
        line_start = self.cut[0]
        line_end = self.cut[len(self.cut) - 1]
        rotate = 1
        sign = None
        for i in range(len(self.cut) - 1):
            line_1 = self.cut[i]
            line_2 = self.cut[i + 1]
            v1 = self.vec(line_1[0], line_1[1])
            v2 = self.vec(line_2[0], line_2[1])
            rotate = v1.x() * v2.y() - v1.y() * v2.x()
            if sign:
                if self.sign(sign) != self.sign(rotate):
                    sign = None
                    break
            else:
                sign = rotate
        if sign:
            v1 = self.vec(line_end[0], line_end[1])
            v2 = self.vec(line_start[0], line_start[1])
            rotate = v1.x() * v2.y() - v1.y() * v2.x(
            )  # finding z direction of [a, b]
            if self.sign(sign) != self.sign(rotate):
                sign = None

        if sign:
            return sign
        return False

    def param_line(self, p1, p2, t):
        return QPointF(p1.x() + (p2.x() - p1.x()) * t,
                       p1.y() + (p2.y() - p1.y()) * t)

    def sign(self, a):
        if a <= 0:
            return False
        return True

    def normal(self, vec, norm):
        if norm > 0:
            return QPointF(-1 * vec.y(), vec.x())
        return QPointF(vec.y(), -1 * vec.x())

    def vec(self, p1, p2):
        return p2 - p1

    def vecLen(self, vec):
        return sqrt(vec.x()**2 + vec.y()**2)

    def scalar(self, v1, v2):
        return v1.x() * v2.x() + v1.y() * v2.y()

    def table_clean(self, table):
        table.clear()
        r = table.rowCount()
        for i in range(r, -1, -1):
            table.removeRow(i)

    def button_mode_set(self):
        if self.mode == None:
            if self.cut:
                self.line_2.setEnabled(True)
            self.clean.setEnabled(True)
            self.paint.setEnabled(True)
            self.cutter.setEnabled(True)
            self._polygon.setEnabled(True)
        if self.mode == "line_mode":
            self.clean.setEnabled(False)
            self.paint.setEnabled(False)
            self.cutter.setEnabled(False)
            self.line_2.setEnabled(False)
        if self.mode == "cutter_mode":
            self.clean.setEnabled(False)
            self.paint.setEnabled(False)
            self._polygon.setEnabled(False)
            self.line_2.setEnabled(False)

    def add_row(self, line, table):
        table.insertRow(table.rowCount())
        i = table.rowCount() - 1
        item_b = QTableWidgetItem("[{0}, {1}]".format(line[0].x(),
                                                      line[0].y()))
        item_e = QTableWidgetItem("[{0}, {1}]".format(line[1].x(),
                                                      line[1].y()))
        table.setItem(i, 0, item_b)
        table.setItem(i, 1, item_e)

    def make_cut(self):
        print("pain")
        norm = self.checkConvexPolygon()
        if (norm == False):
            print("The polygon is not convex! Try another one...")
            return

        cut, polygon = self.getPoints(self.cut, self.polygon)
        polygon = self.sutherland_bodgman(cut, polygon, norm)

        if not polygon:
            return
        self.pen.setColor(red)
        polygon.append(polygon[0])
        for i in range(len(polygon)):
            if i == 0:
                f = polygon[i]
            else:
                self.scene.addLine(f.x(), f.y(), polygon[i].x(),
                                   polygon[i].y(), self.pen)
                f = polygon[i]
        self.pen.setColor(black)

    def sutherland_bodgman(self, cut, polygon, norm):
        for i in range(len(cut) - 1):
            cutted = []
            for j in range(len(polygon)):
                if j == 0:
                    f = polygon[j]
                else:
                    t = self.intersection([s, polygon[j]],
                                          [cut[i], cut[i + 1]], norm)
                    if t:
                        cutted.append(t)

                s = polygon[j]
                if self.visible(s, [cut[i], cut[i + 1]], norm):
                    cutted.append(s)
            if len(cutted) != 0:
                t = self.intersection([s, f], [cut[i], cut[i + 1]], norm)
                if t:
                    cutted.append(t)
            polygon = copy.deepcopy(cutted)
        print(polygon)

        if not len(polygon):
            return None

        return polygon

    def getPoints(self, cut, polygon):
        newCut = []
        for i in cut:
            newCut.append(i[0])
        newCut.append(cut[0][0])

        newPol = []
        for i in polygon:
            newPol.append(i[0])

        return newCut, newPol

    def visible(self, s, edge, norm):
        v1 = self.vec(edge[0], edge[1])
        v2 = self.vec(edge[0], s)
        v = v2.x() * v1.y() - v2.y() * v1.x()
        if norm * v < 0:
            return True
        else:
            return False

    def intersection(self, line, edge, norm):
        vis1 = self.visible(line[0], edge, norm)
        vis2 = self.visible(line[1], edge, norm)
        if (vis1 and not vis2) or (not vis1 and vis2):

            p1 = line[0]
            p2 = line[1]

            q1 = edge[0]
            q2 = edge[1]

            d = (p2.x() - p1.x()) * (q1.y() - q2.y()) - (q1.x() - q2.x()) * (
                p2.y() - p1.y())
            w = (q1.x() - p1.x()) * (q1.y() - q2.y()) - (q1.x() - q2.x()) * (
                q1.y() - p1.y())

            if abs(d) <= 1e-8:
                return p2

            t = w / d

            return QPointF(p1.x() + (p2.x() - p1.x()) * t,
                           p1.y() + (p2.y() - p1.y()) * t)
        else:
            return False
コード例 #43
0
ファイル: MainWindow.py プロジェクト: rlkiran/MMBG
class CanvasClass(QtWidgets.QMainWindow):
    def __init__(self):
        global color
        super(CanvasClass, self).__init__()
        top = 0
        left = 0
        width = 800
        height = 480

        self.setGeometry(top, left, width, height)
        self.image = QImage(self.size(), QImage.Format_RGB32)
        self.image.fill(Qt.white)
        uic.loadUi('Canvas.ui', self)
        homeIcon = os.getcwd() + "\\images\\Icons\\" +"home.png"
        logoutIcon = os.getcwd() + "\\images\\Icons\\" +"logout.png"
        pencilIcon = os.getcwd() + "\\images\\Icons\\" +"pencil_size.png"
        BrushIcon = os.getcwd() + "\\images\\Icons\\" +"paint_brush.png"
        paletteIcon = os.getcwd() + "\\images\\Icons\\" +"color_palette.png"
        eraserIcon = os.getcwd() + "\\images\\Icons\\" +"eraser.png"
        self.setWindowFlags(QtCore.Qt.FramelessWindowHint)
        self.shortcut = QShortcut(QKeySequence("Ctrl+Q"), self)
        self.shortcut.activated.connect(self.quitApp)
        self.homeImg = self.findChild(QtWidgets.QLabel, 'homeIcon')
        self.homeImg.setPixmap(QPixmap(homeIcon))
        self.BrushImg = self.findChild(QtWidgets.QLabel, 'BrushImg')
        self.BrushImg.setPixmap(QPixmap(BrushIcon))
        self.paleteButton = self.findChild(QtWidgets.QPushButton,'paleteButton')
        self.paleteButton.setIcon(QtGui.QIcon(paletteIcon))
        self.logoutButton = self.findChild(QtWidgets.QPushButton,'logoutButton')
        self.logoutButton.setIcon(QtGui.QIcon(logoutIcon))
        self.paleteButton.setIconSize(QtCore.QSize(24,24))
        self.paleteButton.clicked.connect(self.openColorDialog)
        self.logoutButton.clicked.connect((self.logout))
        self.HomeButton = self.findChild(QtWidgets.QPushButton,'HomeButton')
        self.HomeButton.clicked.connect(self.openLs)
        self.NextButton = self.findChild(QtWidgets.QPushButton,'NextButton')
        self.NextButton.clicked.connect(self.setCanvasImage)
        self.imgLabel = self.findChild(QtWidgets.QLabel, 'label')
        self.horizontalSlider = self.findChild(QtWidgets.QSlider,'horizontalSlider')
        self.horizontalSlider.valueChanged[int].connect(self.getsliderValue)

        self.horizontalSlider.setMinimum(1)
        self.horizontalSlider.setMaximum(20)
        self.horizontalSlider.setValue(20)
        self.horizontalSlider.setTickPosition(QSlider.NoTicks)
        self.horizontalSlider.setTickInterval(2)

        self.drawing = False
        self.brushSize = 20
        self.brushColor = color
        self.lastpoint = QPoint()

        self.show()      

    def mousePressEvent(self, event):
        if event.button() == Qt.LeftButton:
            self.drawing = True
            self.lastpoint = event.pos()

    def mouseMoveEvent(self, event):
        if (event.buttons() & Qt.LeftButton) & self.drawing:
            painter = QPainter(self.image)
            painter.setPen(QPen(self.brushColor, self.brushSize, Qt.SolidLine, Qt.RoundCap, Qt.RoundJoin))
            painter.drawLine(self.lastpoint, event.pos())
            self.lastpoint = event.pos()
            self.update()

    def mouseReleaseEvent(self, event):
        if event.button == Qt.LeftButton:
            self.drawing = False

    def paintEvent(self, event):
        canvasPainter = QPainter(self)
        canvasPainter.drawImage(self.rect(), self.image, self.image.rect())

    def setCanvasImage(self):
        global LangDir
        global fileList
        global imgCount
        global count
        global Lang
        global Cat

        print(imgCount)
        if(self.NextButton.text() == 'NEXT'):
            iname = str(Lang)+"-"+str(Cat)+"-"+str(count)
            self.saveImage(iname)
            self.clearCanvas()
            if count==imgCount-1:
                msg = QMessageBox()
                msg.setIcon(QMessageBox.Information)
                msg.setText("Success")
                msg.setInformativeText('You Have Successfully Completed the Task')
                msg.setWindowTitle("Success")
                msg.exec_()                
                self.openLs()
            elif count<imgCount-1:
                count = count + 1
                print(count)
            else:
                count = 0
            self.imgLabel.setPixmap(QPixmap(LangDir + "\\"+ fileList[count]))
        if(self.NextButton.text() == 'START'):
            self.NextButton.setText('NEXT')
            self.imgLabel.setPixmap(QPixmap(LangDir + "\\"+ fileList[count]))
            self.clearCanvas()
    def clearCanvas(self):
        self.image.fill(Qt.white)
    def saveImage(self,imgname):
        global userDir
        global cwd
        os.chdir(userDir)
        filename = str(imgname)+".png"
        self.image.save(filename,"PNG")
        os.chdir(cwd)



    def quitApp(self):
        sys.exit(0)
    
    def openLs(self):
        loop = QEventLoop()
        QTimer.singleShot(100, loop.quit)
        loop.exec_()
        self.close()
        self.open = LanguageSelection()    	
    @pyqtSlot()
    def on_click(self):
        openColorDialog(self)

    def openColorDialog(self):
        global color
        tmpcolor = QColorDialog.getColor()

        if tmpcolor.isValid():
            tmpcolor = (tmpcolor.name()).strip('#')
            tuple1 = tuple(int(tmpcolor[i:i+2], 16) for i in (0, 2, 4))
            color = QColor.fromRgb(tuple1[0],tuple1[1],tuple1[2])
            self.brushColor = color

    def logout(self):
        loop = QEventLoop()
        QTimer.singleShot(100, loop.quit)
        loop.exec_()
        self.close()
        self.open = Ui2()

    def getsliderValue(self,value):
        self.brushSize= value
コード例 #44
0
ファイル: lines.py プロジェクト: LarsThore/PyQt_Network
from PyQt5.QtGui import QColor, QPen, QBrush, QCursor, QImage, QPainter
from PyQt5.QtWidgets import QWidget, QApplication
from PyQt5.uic import loadUi

from types import MethodType
import sys
import numpy as np

app = QApplication(sys.argv)

##################### importing the file made qt designer #####################
w = loadUi("03-circles.ui")

#################### image for saving the picture of circles ##################
img = QImage(w.widget.width(), w.widget.height(), QImage.Format_RGB32)
img.fill(Qt.white)  # image appears white in the beginning (not black)

################################ set painter ##################################
imgPainter = QPainter()  # first painter
painter = QPainter()  # second painter

################################## set pen ####################################
line_drawer = QPen()
line_drawer.setWidth(4)

################################# set switch ###################################
switch = 0

start_point_list = [0]
end_point_list = [0]
コード例 #45
0
class Menu(QDialog):
    def __init__(self):
        super().__init__()
        self.ui = loadUi("design.ui", self)
        self.ui.classify.setDisabled(True)

        self.predictor = Inference()

        self.image = QImage(self.size(), QImage.Format_Grayscale8)
        self.image.fill(Qt.white)

        self.drawing = False
        self.brush_size = 2
        self.color = Qt.black
        self.last_point = QPoint()

        self.ui.clear.clicked.connect(self.clear_canvas)
        self.ui.classify.clicked.connect(self.classify_image)
        self.ui.select_model.clicked.connect(self.select_model_dialog)

        self.set_tooltips()

        self.show()

    @pyqtSlot()
    def select_model_dialog(self):
        gui_utils.set_widgets_to_gray(self)
        self.update()

        model_path, _ = QFileDialog.getOpenFileName(self)

        if model_path:
            gui_utils.display_model_path(self, model_path)
            self.predictor.load(model_path)
            logging.info("Model loaded")

        gui_utils.set_widgets_clickable(self)

    @pyqtSlot()
    def mousePressEvent(self, event):

        if (event.button() == Qt.LeftButton) & gui_utils.check_boundaries(
                self, event):
            self.drawing = True
            self.last_point = event.pos()

    @pyqtSlot()
    def mouseMoveEvent(self, event):
        if (event.buttons() & Qt.LeftButton) & gui_utils.check_boundaries(
                self, event):
            painter = QPainter(self.image)
            painter.setPen(
                QPen(self.color, self.brush_size, Qt.SolidLine, Qt.RoundCap,
                     Qt.RoundJoin))
            painter.drawLine(self.last_point, event.pos())
            self.last_point = event.pos()
            self.update()

    @pyqtSlot()
    def mouseReleaseEvent(self, event):
        if event.button == Qt.LeftButton:
            self.drawing = False

    @pyqtSlot()
    def paintEvent(self, event):
        canvas_painter = QPainter(self)
        canvas_painter.drawImage(self.rect(), self.image, self.image.rect())

    @pyqtSlot()
    def clear_canvas(self):
        logging.debug("Clear canvas procedure executed.")
        self.image.fill(Qt.white)
        self.update()

    @pyqtSlot()
    def keyPressEvent(self, event):

        if event.key() == Qt.Key_Shift:
            self.clear_canvas()

        if event.key() == Qt.Key_P:
            self.classify_image()

        if event.key() == Qt.Key_Escape:
            logging.debug("Escape button pressed, terminate program.")
            logging.debug("Classification creation program terminated -- %s" %
                          (datetime.datetime.now()))
            sys.exit(0)

    @pyqtSlot()
    def closeEvent(self, event):
        logging.debug("Classification program terminated -- %s" %
                      (datetime.datetime.now()))

    @pyqtSlot()
    def classify_image(self):
        img = self.image.copy(QRect(70, 130, 224, 224))
        image_path = gui_utils.save_input_image(img)
        results = self.predictor.predict_top3(image_path)
        gui_utils.display_results(self, results)
        logging.info(f'Image classified as {results[0]} with {[results[1]]}')
        self.update()
        return

    @pyqtSlot()
    def set_tooltips(self):
        self.ui.label_model_selection.setToolTip(
            "Select the pretrained model that shall"
            " be used to classify the input image.")
        self.ui.label_result_first.setToolTip(
            "Likelihood for the most probable classification"
            " result of the input image.")
        self.ui.label_result_second.setToolTip(
            "Likelihood for the second most probable classification"
            " result of the input image.")
        self.ui.label_result_third.setToolTip(
            "Likelihood for the third most probable classification result"
            " of the input image.")
        self.ui.label_results.setToolTip(
            "The results of the image classification using the selected model"
            " in the table on the left.")

        self.ui.select_model.setToolTip(
            "Select the pretrained model that shall be used to classify the input image."
        )

        self.ui.clear.setToolTip(
            "Clear the drawing canvas above. Use SHIFT alternatively.")

        self.ui.classify.setToolTip(
            "Click in this button to classify the drawn input image using"
            " the currently selected model in the table above.")

        self.ui.frame.setToolTip(
            "Please draw the greek letter you want to classify.\nBoth,"
            " lower and uppercase letters work.")
        self.ui.result_first.setToolTip(
            "The most probable classification result of the input image.")
        self.ui.result_second.setToolTip(
            "The second most probable classification result of the input image."
        )
        self.ui.result_third.setToolTip(
            "The third most probable classification result of the input image."
        )
コード例 #46
0
def updateMask(control_image_path, rendered_image_path, mask_image_path):
    control_image = imageFromPath(control_image_path)
    if not control_image:
        error('Could not read control image {}'.format(control_image_path))

    rendered_image = imageFromPath(rendered_image_path)
    if not rendered_image:
        error('Could not read rendered image {}'.format(rendered_image_path))
    if not rendered_image.width() == control_image.width(
    ) or not rendered_image.height() == control_image.height():
        print(
            ('Size mismatch - control image is {}x{}, rendered image is {}x{}'.
             format(control_image.width(), control_image.height(),
                    rendered_image.width(), rendered_image.height())))

    max_width = min(rendered_image.width(), control_image.width())
    max_height = min(rendered_image.height(), control_image.height())

    # read current mask, if it exist
    mask_image = imageFromPath(mask_image_path)
    if mask_image.isNull():
        print('Mask image does not exist, creating {}'.format(mask_image_path))
        mask_image = QImage(control_image.width(), control_image.height(),
                            QImage.Format_ARGB32)
        mask_image.fill(QColor(0, 0, 0))

    # loop through pixels in rendered image and compare
    mismatch_count = 0
    linebytes = max_width * 4
    for y in range(max_height):
        control_scanline = control_image.constScanLine(y).asstring(linebytes)
        rendered_scanline = rendered_image.constScanLine(y).asstring(linebytes)
        mask_scanline = mask_image.scanLine(y).asstring(linebytes)

        for x in range(max_width):
            currentTolerance = qRed(
                struct.unpack('I', mask_scanline[x * 4:x * 4 + 4])[0])

            if currentTolerance == 255:
                # ignore pixel
                continue

            expected_rgb = struct.unpack('I',
                                         control_scanline[x * 4:x * 4 + 4])[0]
            rendered_rgb = struct.unpack('I',
                                         rendered_scanline[x * 4:x * 4 + 4])[0]
            difference = colorDiff(expected_rgb, rendered_rgb)

            if difference > currentTolerance:
                # update mask image
                mask_image.setPixel(x, y,
                                    qRgb(difference, difference, difference))
                mismatch_count += 1

    if mismatch_count:
        # update mask
        mask_image.save(mask_image_path, "png")
        print('Updated {} pixels in {}'.format(mismatch_count,
                                               mask_image_path))
    else:
        print('No mismatches in {}'.format(mask_image_path))
コード例 #47
0
class QtCrackWidget(QWidget):

    closeCrackWidget = pyqtSignal()

    def __init__(self, map, blob, x, y, parent=None):
        super(QtCrackWidget, self).__init__(parent)

        self.setStyleSheet("background-color: rgb(60,60,65); color: white")

        self.qimg_cropped = utils.cropQImage(map, blob.bbox)
        arr = utils.qimageToNumpyArray(self.qimg_cropped)
        self.input_arr = rgb2gray(arr) * 255
        self.tolerance = 20
        self.blob = blob
        self.xmap = x
        self.ymap = y
        self.qimg_crack = QImage(self.qimg_cropped.width(),
                                 self.qimg_cropped.height(),
                                 QImage.Format_RGB32)
        self.qimg_crack.fill(qRgb(0, 0, 0))

        self.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        self.setFixedWidth(400)
        self.setFixedHeight(400)

        SLIDER_WIDTH = 200
        IMAGEVIEWER_SIZE = 300  # SIZE x SIZE

        self.sliderTolerance = QSlider(Qt.Horizontal)
        self.sliderTolerance.setFocusPolicy(Qt.StrongFocus)
        self.sliderTolerance.setMinimumWidth(SLIDER_WIDTH)
        self.sliderTolerance.setMinimum(1)
        self.sliderTolerance.setMaximum(100)
        self.sliderTolerance.setValue(self.tolerance)
        self.sliderTolerance.setTickInterval(5)
        self.sliderTolerance.setAutoFillBackground(True)
        self.sliderTolerance.valueChanged.connect(self.sliderToleranceChanged)

        self.lblTolerance = QLabel("Tolerance: 20")
        self.lblTolerance.setAutoFillBackground(True)
        str = "Tolerance {}".format(self.tolerance)
        self.lblTolerance.setText(str)

        layoutTolerance = QHBoxLayout()
        layoutTolerance.addWidget(self.lblTolerance)
        layoutTolerance.addWidget(self.sliderTolerance)

        self.viewerplus = QtImageViewerPlus()
        self.viewerplus.disableScrollBars()
        self.viewerplus.setFixedWidth(IMAGEVIEWER_SIZE)
        self.viewerplus.setFixedHeight(IMAGEVIEWER_SIZE)

        self.btnCancel = QPushButton("Cancel")
        self.btnCancel.setAutoFillBackground(True)

        self.btnApply = QPushButton("Apply")
        self.btnApply.setAutoFillBackground(True)

        layoutButtons = QHBoxLayout()
        layoutButtons.addWidget(self.btnCancel)
        layoutButtons.addWidget(self.btnApply)

        layoutV = QVBoxLayout()
        layoutV.addLayout(layoutTolerance)
        layoutV.addWidget(self.viewerplus)
        layoutV.addLayout(layoutButtons)
        layoutV.setSpacing(10)
        self.setLayout(layoutV)

        self.viewerplus.setImage(self.qimg_cropped)
        self.preview()

        self.setAutoFillBackground(True)

        self.setWindowTitle("Crack")

    def keyPressEvent(self, event):

        if event.key() == Qt.Key_Escape:

            # RESET CURRENT OPERATION
            self.closeCrackWidget.emit()

    @pyqtSlot()
    def sliderToleranceChanged(self):

        # update tolerance value
        newvalue = self.sliderTolerance.value()
        str1 = "Tolerance {}".format(newvalue)
        self.lblTolerance.setText(str1)
        self.tolerance = newvalue

        # update the preview of the crack segmentation
        self.preview()

    @pyqtSlot()
    def preview(self):

        arr = self.input_arr.copy()
        mask_crack = self.blob.createCrack(arr,
                                           self.xmap,
                                           self.ymap,
                                           self.tolerance,
                                           preview=True)
        self.qimg_crack = utils.maskToQImage(mask_crack)
        self.viewerplus.setOpacity(0.5)
        self.viewerplus.setOverlayImage(self.qimg_crack)

    def apply(self):

        mask_crack = self.blob.createCrack(self.input_arr,
                                           self.xmap,
                                           self.ymap,
                                           self.tolerance,
                                           preview=False)
コード例 #48
0
class miP_MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        uic.loadUi('miP_main.ui', self)  # Загружаем дизайн (надо не забыть в файл переделать)

        # Создаем холст
        self.image = QImage(self.size(), QImage.Format_RGB32)
        self.image.fill(Qt.white)

        self.drawing = False

        # Сразу же выбираем кисть
        self.draw_type = brush
        self.draw_size = 8
        self.draw_color1 = Qt.black
        self.draw_color2 = Qt.white

        self.lastPoint = QPoint()
        self.x = 0
        self.y = 0

        # меню файла
        self.f_create.triggered.connect(self.create_new_file)
        self.f_open.triggered.connect(self.open_file)
        self.f_save.triggered.connect(self.save_file)

        # инструменты
        self.i_brush.dtype = brush
        self.i_brush.triggered.connect(self.choose_draw_type)

        self.i_eraser.dtype = eraser
        self.i_eraser.triggered.connect(self.choose_draw_type)

        self.i_line.dtype = line
        self.i_line.triggered.connect(self.choose_draw_type)

        self.i_rect.dtype = rect
        self.i_rect.triggered.connect(self.choose_draw_type)

        self.i_oval.dtype = oval
        self.i_oval.triggered.connect(self.choose_draw_type)

        # цвет 1 (pen)
        self.c1_black.color = Qt.black
        self.c1_black.triggered.connect(self.choose_color1)
        self.c1_red.color = Qt.red
        self.c1_red.triggered.connect(self.choose_color1)
        self.c1_blue.color = Qt.blue
        self.c1_blue.triggered.connect(self.choose_color1)
        self.c1_yellow.color = Qt.yellow
        self.c1_yellow.triggered.connect(self.choose_color1)
        self.c1_green.color = Qt.green
        self.c1_green.triggered.connect(self.choose_color1)
        self.c1_white.color = Qt.white
        self.c1_white.triggered.connect(self.choose_color1)
        self.c1_other.triggered.connect(self.choose_color1)

        # цвет 2 (brush)
        self.c2_black.color = Qt.black
        self.c2_black.triggered.connect(self.choose_color2)
        self.c2_red.color = Qt.red
        self.c2_red.triggered.connect(self.choose_color2)
        self.c2_blue.color = Qt.blue
        self.c2_blue.triggered.connect(self.choose_color2)
        self.c2_yellow.color = Qt.yellow
        self.c2_yellow.triggered.connect(self.choose_color2)
        self.c2_green.color = Qt.green
        self.c2_green.triggered.connect(self.choose_color2)
        self.c2_white.color = Qt.white
        self.c2_white.triggered.connect(self.choose_color2)
        self.c2_other.triggered.connect(self.choose_color2)

        # выбор размера (толщины) инструмента
        self.c_size.triggered.connect(self.choose_size)

    def create_new_file(self):
        self.image = QImage(self.size(), QImage.Format_RGB32)
        self.image.fill(self.draw_color2)
        self.update()

    def save_file(self):
        fname = QFileDialog.getSaveFileName(
            self, 'Сохранить картинку', '',
            'Картинка (*.jpg);;Картинка (*.png);;Все файлы (*)')[0]
        self.image.save(fname)

    def open_file(self):
        fname = QFileDialog.getOpenFileName(
            self, 'Выбрать картинку', '',
            'Картинка (*.jpg);;Картинка (*.png);;Все файлы (*)')[0]
        im = Image.open(fname)
        im = im.resize((800, 600))
        im.save('res.png')
        self.image.load('res.png')

    def choose_size(self):
        size, ok_pressed = QInputDialog.getInt(
            self, "Введите размер кисти", "Размер кисти",
            self.draw_size, 1, 1000, 1)
        if ok_pressed:
            self.draw_size = size

    def choose_color1(self):  # палитра, все обычно
        if self.sender() != self.c1_other:
            self.draw_color1 = self.sender().color
        else:
            self.draw_color1 = QColorDialog.getColor()

    def choose_color2(self):  # палитра, все обычно
        if self.sender() != self.c2_other:
            self.draw_color2 = self.sender().color
        else:
            self.draw_color2 = QColorDialog.getColor()

    def choose_draw_type(self):
        self.draw_type = self.sender().dtype

    def mousePressEvent(self, event):
        if event.button() == Qt.LeftButton:
            self.drawing = True
            self.lastPoint = event.pos()
            self.x = event.x()
            self.y = event.y()
            self.image.save('res.png')

    def mouseMoveEvent(self, event):
        if (event.buttons() & Qt.LeftButton) & self.drawing:
            if self.draw_type == brush:
                painter = QPainter(self.image)
                painter.setPen(QPen(self.draw_color1, self.draw_size))
                painter.drawLine(self.lastPoint, event.pos())
                self.lastPoint = event.pos()

            if self.draw_type == eraser:
                painter = QPainter(self.image)
                painter.setPen(QPen(self.draw_color2, self.draw_size))
                painter.drawLine(self.lastPoint, event.pos())
                self.lastPoint = event.pos()

            elif self.draw_type == line:
                self.image.load('res.png')
                painter = QPainter(self.image)
                painter.setPen(QPen(self.draw_color1, self.draw_size))
                painter.drawLine(self.lastPoint, event.pos())

            elif self.draw_type == rect:
                self.image.load('res.png')
                painter = QPainter(self.image)
                painter.setPen(QPen(self.draw_color1, self.draw_size))
                painter.setBrush(QBrush(self.draw_color2))
                painter.drawRect(self.x, self.y, event.x() - self.x, event.y() - self.y)

            elif self.draw_type == oval:
                self.image.load('res.png')
                painter = QPainter(self.image)
                painter.setPen(QPen(self.draw_color1, self.draw_size))
                painter.setBrush(QBrush(self.draw_color2))
                painter.drawEllipse(self.x, self.y, event.x() - self.x, event.y() - self.y)

            self.update()

    def mouseReleaseEvent(self, event):
        self.drawing = False
        self.image.save('res.png', 'png')

    def paintEvent(self, event):
        canvasPainter = QPainter(self)
        canvasPainter.drawImage(self.rect(), self.image, self.image.rect())
コード例 #49
0
ファイル: module2.py プロジェクト: kungkingc/SEPlab8
class ScribbleArea(QWidget):
    def __init__(self, parent=None):
        super(ScribbleArea, self).__init__(parent)

        self.setAttribute(Qt.WA_StaticContents)
        self.modified = False
        self.scribbling = False
        self.myPenWidth = 1
        self.myPenColor = Qt.blue
        self.image = QImage()
        self.lastPoint = QPoint()

    def setPenColor(self, newColor):
        self.myPenColor = newColor

    def setPenWidth(self, newWidth):
        self.myPenWidth = newWidth

    def clearImage(self):
        self.image.fill(qRgb(255, 255, 255))
        self.modified = True
        self.update()

    def mousePressEvent(self, event):
        if event.button() == Qt.LeftButton:
            self.lastPoint = event.pos()
            self.scribbling = True

    def mouseMoveEvent(self, event):
        if (event.buttons() & Qt.LeftButton) and self.scribbling:
            self.drawLineTo(event.pos())

    def mouseReleaseEvent(self, event):
        if event.button() == Qt.LeftButton and self.scribbling:
            self.drawLineTo(event.pos())
            self.scribbling = False

    def paintEvent(self, event):
        painter = QPainter(self)
        dirtyRect = event.rect()
        painter.drawImage(dirtyRect, self.image, dirtyRect)

    def resizeEvent(self, event):
        if self.width() > self.image.width() or self.height(
        ) > self.image.height():
            newWidth = max(self.width(), self.image.width())
            newHeight = max(self.height(), self.image.height())
            self.resizeImage(self.image, QSize(newWidth, newHeight))
            self.update()

        super(ScribbleArea, self).resizeEvent(event)

    def drawLineTo(self, endPoint):
        painter = QPainter(self.image)
        painter.setPen(
            QPen(self.myPenColor, self.myPenWidth, Qt.SolidLine, Qt.RoundCap,
                 Qt.RoundJoin))
        painter.drawLine(self.lastPoint, endPoint)
        self.modified = True

        rad = self.myPenWidth / 2 + 2
        self.update(
            QRect(self.lastPoint,
                  endPoint).normalized().adjusted(-rad, -rad, +rad, +rad))
        self.lastPoint = QPoint(endPoint)

    def resizeImage(self, image, newSize):
        if image.size() == newSize:
            return

        newImage = QImage(newSize, QImage.Format_RGB32)
        newImage.fill(qRgb(255, 255, 255))
        painter = QPainter(newImage)
        painter.drawImage(QPoint(0, 0), image)
        self.image = newImage

    def isModified(self):
        return self.modified

    def penColor(self):
        return self.myPenColor

    def penWidth(self):
        return self.myPenWidth
コード例 #50
0
class CheckersPlateWidget(QWidget):
    MARGIN = 10
    MARGIN_CROWN = 25
    TIMER_AI_TURN_MS = 150

    # Init Method
    #   Init plate size and class variables
    def __init__(self, size, container):
        super().__init__()

        self.container = container
        self.highlightPossibilities = True
        self.size = min(size.width(), size.height())
        self.setFixedSize(self.size, self.size)
        self.initSquareDimension()
        self.initGameVariables(False)

    # Init Game Variables
    #   Init the game's variables
    def initGameVariables(self, restart):
        self.pieceSelected = QPoint(-1, -1)
        self.squarePossibilities = []
        self.plate = []
        self.initPlate()
        self.isAnimationRunning = False
        self.currentAnimationIndex = 0
        self.currentAnimationPossibility = None
        self.currentAnimationOldPos = QPoint(-1, -1)
        if restart:
            self.game.setPlate(self.plate)
        else:
            self.game = Game(self.plate, self.container)
        self.initUI()

    # Init UI Method
    #   Create the image where the plate is draw and draw it
    def initUI(self):
        self.image = QImage(QSize(self.size, self.size), QImage.Format_RGB32)
        self.image.fill(Qt.white)
        self.drawPlate()

    # Restart Game
    #   Init back the variables and restart the game
    def restartGame(self):
        self.initGameVariables(True)
        self.game.restartGame(self.plate)

    # Toggle AI
    #   Restart the game et toggle AI
    def toggleAI(self):
        ai = self.game.Ai
        self.container.restartGame()
        self.game.Ai = False if ai else True

    # Init Square Dimension
    #   Calculate squares' dimension
    def initSquareDimension(self):
        self.squareDimension = self.size / Game.NB_PLATE_SQUARES

    # Init Plate
    #   Init the plate in a double array
    def initPlate(self):
        for y in range(0, Game.NB_PLATE_SQUARES):
            self.plate.append([])
            for x in range(0, Game.NB_PLATE_SQUARES):
                self.plate[y].append({})
                compare = 0 if y % 2 == 0 else 1
                self.plate[y][x]["queen"] = False
                if x % 2 == compare:
                    self.plate[y][x]["square"] = Square.WHITE
                    self.plate[y][x]["piece"] = Square.EMPTY
                    self.plate[y][x]["player"] = 0
                elif x < Game.NB_LINE_OCCUPED:
                    self.plate[y][x]["square"] = Square.BLACK
                    self.plate[y][x]["piece"] = Square.WHITE
                    self.plate[y][x]["player"] = 2
                elif x > Game.NB_PLATE_SQUARES - 1 - Game.NB_LINE_OCCUPED:
                    self.plate[y][x]["square"] = Square.BLACK
                    self.plate[y][x]["piece"] = Square.BLACK
                    self.plate[y][x]["player"] = 1
                else:
                    self.plate[y][x]["square"] = Square.BLACK
                    self.plate[y][x]["piece"] = Square.EMPTY
                    self.plate[y][x]["player"] = 0

    # Toggle Highlight Possibilities
    #   Enable or disable show of possibilities
    def toggleHighlightPossibilities(self):
        self.highlightPossibilities = False if self.highlightPossibilities else True

    # Draw Plate
    #   Draw the plate on the image from the double array
    def drawPlate(self):
        for y in range(0, Game.NB_PLATE_SQUARES):
            for x in range(0, Game.NB_PLATE_SQUARES):
                pieceSelected = True if x == self.pieceSelected.x(
                ) and y == self.pieceSelected.y() else False
                squarePossibility = True if self.game.getPointInPossibilities(
                    self.squarePossibilities, QPoint(x, y)) else False
                if self.plate[y][x]["square"] == Square.BLACK:
                    self.drawSquare(x, y, Qt.gray, squarePossibility)
                else:
                    self.drawSquare(x, y, Qt.lightGray, squarePossibility)
                if self.plate[y][x]["piece"] == Square.BLACK:
                    self.drawPiece(x, y, Qt.black, pieceSelected)
                elif self.plate[y][x]["piece"] == Square.WHITE:
                    self.drawPiece(x, y, Qt.white, pieceSelected)
                if self.plate[y][x]["queen"] == True:
                    posX = x * self.squareDimension + self.MARGIN_CROWN
                    posY = y * self.squareDimension + self.MARGIN_CROWN
                    width = self.squareDimension - 2 * self.MARGIN_CROWN
                    self.drawPieceFromFile(posX, posY, width, "./icons/crown")
        self.update()

    # Draw Square
    #   Draw a square on the image
    def drawSquare(self, x, y, color, possibility):
        painter = QPainter(self.image)
        color = Qt.darkGray if possibility and self.highlightPossibilities else QColor(
            color)
        painter.setBrush(color)
        painter.setPen(color)
        painter.drawRect(x * self.squareDimension, y * self.squareDimension,
                         self.squareDimension - 1, self.squareDimension - 1)

    # Draw Piece
    #   Draw a piece on the image
    def drawPiece(self, x, y, color, selected):
        painter = QPainter(self.image)
        color = QColor(color)
        if selected:
            color.setAlpha(120)
        painter.setBrush(color)
        painter.setPen(color)
        posX = x * self.squareDimension + self.MARGIN
        posY = y * self.squareDimension + self.MARGIN
        width = self.squareDimension - 2 * self.MARGIN
        painter.drawEllipse(posX, posY, width, width)

    # Draw Piece From File
    #   Draw a piece from a file on the image
    def drawPieceFromFile(self, posX, posY, width, path):
        piece = QPixmap(path)
        painter = QPainter(self.image)
        painter.drawPixmap(posX, posY, width, width, piece)

    # Paint Event (override method)
    #   Called on window focus or resize
    #   Draw the image on widget
    def paintEvent(self, event):
        canvasPainter = QPainter(self)
        canvasPainter.drawImage(self.rect(), self.image, self.image.rect())

    # Mouse Press Event (override method)
    #   Called when user press a button on mouse
    #   Move a piece or select one
    def mousePressEvent(self, event):
        if event.button() == Qt.LeftButton and not self.game.hasWon():
            if not self.isAnimationRunning and not self.game.isTurnAI():
                x, y = self.getSelectedSquare(event)
                pos = QPoint(x, y)
                # Case cliquée + Clique sur une possibilité
                if self.pieceSelected.x() != -1 and self.pieceSelected.y() != -1\
                        and self.game.getPointInPossibilities(self.squarePossibilities, pos) is not None:
                    possibility = self.game.getPointInPossibilities(
                        self.squarePossibilities, pos)
                    self.startAnimation(possibility, self.pieceSelected)
                    self.pieceSelected = QPoint(-1, -1)
                    self.squarePossibilities = []
                # Clique sur une case du plateau
                else:
                    self.pieceSelected = QPoint(-1, -1)
                    self.squarePossibilities = []
                    player = 1 if self.game.isTurnJ1() else 2
                    if self.plate[y][x]["piece"] != Square.EMPTY and self.plate[
                            y][x]["player"] == player:
                        if not self.game.isGameRunning():
                            self.game.launchGame()
                        self.pieceSelected = pos
                        self.squarePossibilities = self.game.getPossibility(
                            pos)
                self.game.setPlate(self.plate)
                self.drawPlate()
                self.update()

    # Start Animation
    #   Start a piece's move (and/or eat)
    def startAnimation(self, possibility, fromPiece):
        self.isAnimationRunning = True
        self.currentAnimationIndex = 0
        self.currentAnimationPossibility = possibility
        self.currentAnimationOldPos = fromPiece
        QTimer.singleShot(
            self.TIMER_AI_TURN_MS if self.game.isTurnAI() else 10,
            self.doAnimation)

    # Do Animation
    #   Move and/or eat a piece
    def doAnimation(self):
        possibility = self.currentAnimationPossibility
        i = self.currentAnimationIndex
        if i < len(possibility.getPieceMoves()):
            self.game.movePiece(self.currentAnimationOldPos,
                                possibility.getPieceMoves()[i], self.plate,
                                True)
            self.currentAnimationOldPos = possibility.getPieceMoves()[i]
            if i < possibility.getNbPiecesEat():
                self.game.eatPiece(possibility.getPosPiecesEat()[i],
                                   self.plate)
            self.currentAnimationIndex += 1
            self.game.setPlate(self.plate)
            self.drawPlate()
            self.update()
            if self.currentAnimationIndex >= len(possibility.getPieceMoves()):
                self.game.removePieces(possibility.getNbPiecesEat())
                self.isAnimationRunning = False
                self.currentAnimationPossibility = None
                self.currentAnimationIndex = 0
                if not self.checkWin():
                    self.game.toggleTurn()
            else:
                QTimer.singleShot(500, self.doAnimation)

    # Get Selected Square
    #   Convert mouse coordinates to a specific cell
    def getSelectedSquare(self, event):
        for y in range(0, Game.NB_PLATE_SQUARES):
            posYMin = y * self.squareDimension
            posYMax = y * self.squareDimension + self.squareDimension
            if posYMin <= event.pos().y() <= posYMax:
                for x in range(0, Game.NB_PLATE_SQUARES):
                    posXMin = x * self.squareDimension
                    posXMax = x * self.squareDimension + self.squareDimension
                    if posXMin <= event.pos().x() <= posXMax:
                        return x, y
        return -1, -1

    # Check Win
    #   Display a message if someone won
    def checkWin(self):
        if self.checkLoose():
            self.game.stopGame(True)
            player = "Black" if self.game.isTurnJ1() else "White"
            if not self.game.isAi():
                QMessageBox.about(self, "Win !", "Player " + player + " won !")
            elif not self.game.isTurnJ1():
                QMessageBox.about(self, "Loose !", "You loose ... AI won !")
            else:
                QMessageBox.about(self, "Win !", "You win against the AI !")
            return True
        return False

    # Check Loose
    #   Check if a player loose
    def checkLoose(self):
        player = 2 if self.game.isTurnJ1() else 1
        for y in range(0, self.game.NB_PLATE_SQUARES):
            for x in range(0, self.game.NB_PLATE_SQUARES):
                if self.plate[y][x]["player"] == player:
                    return False
        return True

    # Get Game
    #   Return the Game class
    def getGame(self):
        return self.game
コード例 #51
0
class Example(QWidget):
    def __init__(self):
        super().__init__()
        self.initUI()
        

    def fill_invert(self):
        color_fill = self.colormain
        color_background = QColor(255,255,255).rgb()
        for rebr in edges:
            old = -1
            old_sy = -1
            flag = False
            for j in range(len(rebr)-1):
                x1 = rebr[j][0]
                y1 = rebr[j][1]
                x2 = rebr[j+1][0]
                y2 = rebr[j+1][1]

                dx = int(x2 - x1)
                dy = int(y2 - y1)
                sx = sign(dx)
                sy = sign(dy)
                dx = abs(dx)
                dy = abs(dy)

                if (j == 0):
                    first_sy = sy
                elif (j == len(rebr)-2):
                    if (sy < 0 and first_sy < 0 or sy > 0 and first_sy > 0):
                        flag = True

                if (sy == 0):
                    continue

                if (sy < 0 and old_sy > 0 or sy > 0 and old_sy < 0):
                    old = -1
                old_sy = sy

                swap = False
                if (dy <= dx):
                    swap = False
                else:
                    swap = True
                    dx,dy = dy,dx
    
                e = int(2*dy-dx)
                x = int(x1)
                y = int(y1)
            
                color = QColor(0,0,0)

                for i in range(dx+1):
                    slave_x = x
                    if (old != y):
                        if flag and y ==  rebr[0][1]:
                            continue
                        while slave_x < WIDTH:
                                current_color = self.image.pixelColor(slave_x,y)
                                if current_color.rgb() == color_background:
                                    self.image.setPixel(int(slave_x),int(y),color_fill)
                                else:
                                    self.image.setPixel(int(slave_x),int(y),color_background)
                                slave_x += 1
                        old = y
                    QApplication.processEvents()
                    if (e>=0):
                        if (swap):
                            x += sx
                        else:
                            y +=sy
                        e = e-2*dx
                    if (e < 0): 
                        if (swap):
                            y +=sy
                        else:
                            x += sx
                        e = e+2*dy
                    self.repaint()
                main_old =y2
            

    def Bresenham(self,x1,y1,x2,y2,color = QColor(0,0,0).rgb()):
            dx = int(x2 - x1)
            dy = int(y2 - y1)
            sx = sign(dx)
            sy = sign(dy)
            dx = abs(dx)
            dy = abs(dy)    

            swap = False
            if (dy <= dx):
                swap = False
            else:
                swap = True
                dx,dy = dy,dx
        
    
            e = int(2*dy-dx)
            x = int(x1)
            y = int(y1)
            
            for i in range(dx+1):
                self.image.setPixel(x,y,color)
                if (e>=0):
                    if (swap):
                        x += sx
                    else:
                        y +=sy
                    e = e-2*dx
                if (e < 0): 
                    if (swap):
                        y +=sy
                    else:
                        x += sx
                    e = e+2*dy


    def initUI(self):      
        self.setGeometry(100,100, 800, 500)
        self.setWindowTitle('Points')
        self.Group = QHBoxLayout(self)
        self.v = QVBoxLayout()
        self.GraphView = QGraphicsView(self)
        self.scene = QGraphicsScene(self)
        self.image = QImage(WIDTH,HIGHT - 20,QImage.Format_RGB32)

        self.Group.addWidget(self.GraphView)
        self.Group.addLayout(self.v)
        self.image.fill(Qt.white)
        
        self.GraphView.setGeometry(10,10,WIDTH,HIGHT )
        self.GraphView.setStyleSheet("background-color: white")
        self.scene.addPixmap(QPixmap.fromImage(self.image))

        self.GraphView.setScene(self.scene)        

        self.fill_butt = QPushButton('Fill', self)
        self.fill_butt.resize(self.fill_butt.sizeHint())

        self.table = QTableWidget(self)
        self.table.setColumnCount(2)
        self.table.setHorizontalHeaderLabels(["x","y"])
        self.v.addWidget(self.table)

        v1 = QHBoxLayout()
        
        self.clear = QPushButton('Clear', self)
        self.clear.resize(self.fill_butt.sizeHint())
        v1.addWidget(self.clear)
        
        self.Add = QPushButton('Add', self)
        self.Add.resize(self.fill_butt.sizeHint())
        v1.addWidget(self.Add)
        self.v.addLayout(v1)
        self.v.addWidget(self.fill_butt)

        self.color_button = QPushButton(self)
        self.color_button.setGeometry(800,100,40,20)

        self.v.addWidget(self.color_button)
        
        self.colormain = QColor(0,255,0).rgb()
        self.color_button.setStyleSheet('QPushButton{background-color:'+QColor(0,255,0).name()+'}')
        self.capslock = False

        self.color_button.clicked.connect(lambda: self.GetColor())
        self.Add.clicked.connect(lambda: self.ShowDialog())
        self.fill_butt.clicked.connect(lambda: self.Fill())
        self.clear.clicked.connect(lambda: self.Clear())
        self.show()
    

    def keyPressEvent(self, QKeyEvent):
        if QKeyEvent.key() == 16777252:
            self.capslock = not self.capslock
    

    def GetColor(self):
        color = QColorDialog.getColor()
        self.colormain = color.rgb()
        hexcolor = color.name()
        self.color_button.setStyleSheet('QPushButton{background-color:'+hexcolor+'}')


    def Fill(self):
        self.fill_invert()
        self.draw_borders()
        
   
    def ShowDialog(self):
        text, ok = QInputDialog.getText(self, 'Input Dialog', 'Enter X Y:')
        if ok:
            text = text.split()
            x = int(text[0])
            y = int(text[1])
            i = len(edges_slave)
            if i:
                self.Bresenham(edges_slave[i-1][0],edges_slave[i-1][1],x,y)
            edges_slave.append([x,y])
            self.table_appender([x,y])


    def Clear(self):
        edges.clear()
        edges_slave.clear()
        self.table.setRowCount(0)
        self.image.fill(Qt.white)


    def draw_borders(self):
        for j in range(len(edges)):
            for i in range(len(edges[j])-1):
                self.Bresenham(edges[j][i][0],edges[j][i][1],edges[j][i+1][0],edges[j][i+1][1])
        self.repaint()
        

    def mousePressEvent(self, QMouseEvent):
        if (QMouseEvent.button() == Qt.LeftButton):
            cord = QMouseEvent.pos()
            
            y = cord.y()
            x = cord.x()
            if (x >= 10 and y>=10 and y<=HIGHT and x<=WIDTH):
                x -= 10
                y -= 10
                i = len(edges_slave)

                if self.capslock and i:
                    if y != edges_slave[i-1][1]:
                        der = (x - edges_slave[i-1][0])/(y - edges_slave[i-1][1])
                    else:
                        der  = 2
                    if abs(der) <= 1:
                        x = edges_slave[i-1][0]
                    else:
                        y = edges_slave[i-1][1]

                if i:
                    self.Bresenham(edges_slave[i-1][0],edges_slave[i-1][1],x,y)
                edges_slave.append([x,y])
                self.table_appender([x,y])

        elif (QMouseEvent.button() == Qt.RightButton):
            i = len(edges_slave)
            if i:
                x = edges_slave[0][0]
                y = edges_slave[0][1]
                self.Bresenham(edges_slave[i-1][0],edges_slave[i-1][1],x,y)
                edges_slave.append([x,y])
            edges.append(copy.deepcopy(edges_slave))
            edges_slave.clear()
            self.table_appender(['end','end'])
            

    def table_appender(self,coord):
        N = self.table.rowCount()
        self.table.setRowCount(N+1)
        self.table.setItem(N,0,QTableWidgetItem(str(coord[0])))
        self.table.setItem(N,1,QTableWidgetItem(str(coord[1])))


    def paintEvent(self, e):
        self.scene.clear()
        self.scene.addPixmap(QPixmap.fromImage(self.image))
コード例 #52
0
    def overlay_marks(self, img, is_cseed=False, calibration_sheet=False):
        border_color = Qt.white
        base_img = QImage(self.f_size.width(),self.f_size.height(), QImage.Format_ARGB32)
        base_img.fill(border_color)
        img = QImage(img)

        painter = QPainter()
        painter.begin(base_img)

        total_distance_h = round(base_img.width() / self.abstand_v)
        dist_v = round(total_distance_h) / 2
        dist_h = round(total_distance_h) / 2

        img = img.scaledToWidth(base_img.width() - (2 * (total_distance_h)))
        painter.drawImage(total_distance_h,
                          total_distance_h,
                          img)

        #frame around image
        pen = QPen(Qt.black, 2)
        painter.setPen(pen)

        #horz
        painter.drawLine(0, total_distance_h, base_img.width(), total_distance_h)
        painter.drawLine(0, base_img.height()-(total_distance_h), base_img.width(), base_img.height()-(total_distance_h))
        #vert
        painter.drawLine(total_distance_h, 0,  total_distance_h, base_img.height())
        painter.drawLine(base_img.width()-(total_distance_h), 0,  base_img.width()-(total_distance_h), base_img.height())

        #border around img
        border_thick = 6
        Rpath = QPainterPath()
        Rpath.addRect(QRectF((total_distance_h)+(border_thick/2),
                             (total_distance_h)+(border_thick/2),
                             base_img.width()-((total_distance_h)*2)-((border_thick)-1),
                             (base_img.height()-((total_distance_h))*2)-((border_thick)-1)))
        pen = QPen(Qt.black, border_thick)
        pen.setJoinStyle (Qt.MiterJoin)

        painter.setPen(pen)
        painter.drawPath(Rpath)

        Bpath = QPainterPath()
        Bpath.addRect(QRectF((total_distance_h), (total_distance_h),
                             base_img.width()-((total_distance_h)*2), (base_img.height()-((total_distance_h))*2)))
        pen = QPen(Qt.black, 1)
        painter.setPen(pen)
        painter.drawPath(Bpath)

        pen = QPen(Qt.black, 1)
        painter.setPen(pen)
        painter.drawLine(0, base_img.height()/2, total_distance_h, base_img.height()/2)
        painter.drawLine(base_img.width()/2, 0, base_img.width()/2, total_distance_h)

        painter.drawLine(base_img.width()-total_distance_h, base_img.height()/2, base_img.width(), base_img.height()/2)
        painter.drawLine(base_img.width()/2, base_img.height(), base_img.width()/2, base_img.height() - total_distance_h)

        #print code
        f_size = 37
        QFontDatabase.addApplicationFont(os.path.join(os.path.dirname(__file__), 'DejaVuSansMono-Bold.ttf'))
        font = QFont("DejaVu Sans Mono", f_size-11, QFont.Bold)
        font.setPixelSize(35)
        painter.setFont(font)

        if not calibration_sheet:
            if is_cseed: #its a secret
                painter.setPen(QPen(Qt.black, 1, Qt.DashDotDotLine))
                painter.drawLine(0, dist_v, base_img.width(), dist_v)
                painter.drawLine(dist_h, 0,  dist_h, base_img.height())
                painter.drawLine(0, base_img.height()-dist_v, base_img.width(), base_img.height()-(dist_v))
                painter.drawLine(base_img.width()-(dist_h), 0,  base_img.width()-(dist_h), base_img.height())

                painter.drawImage(((total_distance_h))+11, ((total_distance_h))+11,
                                  QImage(icon_path('electrumb.png')).scaledToWidth(2.1*(total_distance_h), Qt.SmoothTransformation))

                painter.setPen(QPen(Qt.white, border_thick*8))
                painter.drawLine(base_img.width()-((total_distance_h))-(border_thick*8)/2-(border_thick/2)-2,
                                (base_img.height()-((total_distance_h)))-((border_thick*8)/2)-(border_thick/2)-2,
                                base_img.width()-((total_distance_h))-(border_thick*8)/2-(border_thick/2)-2 - 77,
                                (base_img.height()-((total_distance_h)))-((border_thick*8)/2)-(border_thick/2)-2)
                painter.setPen(QColor(0,0,0,255))
                painter.drawText(QRect(0, base_img.height()-107, base_img.width()-total_distance_h - border_thick - 11,
                                       base_img.height()-total_distance_h - border_thick), Qt.AlignRight,
                                 self.versioned_seed.version + '_'+self.versioned_seed.checksum)
                painter.end()

            else: # revealer

                painter.setPen(QPen(border_color, 17))
                painter.drawLine(0, dist_v, base_img.width(), dist_v)
                painter.drawLine(dist_h, 0,  dist_h, base_img.height())
                painter.drawLine(0, base_img.height()-dist_v, base_img.width(), base_img.height()-(dist_v))
                painter.drawLine(base_img.width()-(dist_h), 0,  base_img.width()-(dist_h), base_img.height())

                painter.setPen(QPen(Qt.black, 2))
                painter.drawLine(0, dist_v, base_img.width(), dist_v)
                painter.drawLine(dist_h, 0,  dist_h, base_img.height())
                painter.drawLine(0, base_img.height()-dist_v, base_img.width(), base_img.height()-(dist_v))
                painter.drawLine(base_img.width()-(dist_h), 0,  base_img.width()-(dist_h), base_img.height())
                logo = QImage(icon_path('revealer_c.png')).scaledToWidth(1.3*(total_distance_h))
                painter.drawImage((total_distance_h)+ (border_thick), ((total_distance_h))+ (border_thick), logo, Qt.SmoothTransformation)

                #frame around logo
                painter.setPen(QPen(Qt.black, border_thick))
                painter.drawLine(total_distance_h+border_thick, total_distance_h+logo.height()+3*(border_thick/2),
                                 total_distance_h+logo.width()+border_thick, total_distance_h+logo.height()+3*(border_thick/2))
                painter.drawLine(logo.width()+total_distance_h+3*(border_thick/2), total_distance_h+(border_thick),
                                 total_distance_h+logo.width()+3*(border_thick/2), total_distance_h+logo.height()+(border_thick))

                #frame around code/qr
                qr_size = 179

                painter.drawLine((base_img.width()-((total_distance_h))-(border_thick/2)-2)-qr_size,
                                (base_img.height()-((total_distance_h)))-((border_thick*8))-(border_thick/2)-2,
                                 (base_img.width()/2+(total_distance_h/2)-border_thick-(border_thick*8)/2)-qr_size,
                                (base_img.height()-((total_distance_h)))-((border_thick*8))-(border_thick/2)-2)

                painter.drawLine((base_img.width()/2+(total_distance_h/2)-border_thick-(border_thick*8)/2)-qr_size,
                                (base_img.height()-((total_distance_h)))-((border_thick*8))-(border_thick/2)-2,
                                 base_img.width()/2 + (total_distance_h/2)-border_thick-(border_thick*8)/2-qr_size,
                                 ((base_img.height()-((total_distance_h)))-(border_thick/2)-2))

                painter.setPen(QPen(Qt.white, border_thick * 8))
                painter.drawLine(
                    base_img.width() - ((total_distance_h)) - (border_thick * 8) / 2 - (border_thick / 2) - 2,
                    (base_img.height() - ((total_distance_h))) - ((border_thick * 8) / 2) - (border_thick / 2) - 2,
                    base_img.width() / 2 + (total_distance_h / 2) - border_thick - qr_size,
                    (base_img.height() - ((total_distance_h))) - ((border_thick * 8) / 2) - (border_thick / 2) - 2)

                painter.setPen(QColor(0,0,0,255))
                painter.drawText(QRect(((base_img.width()/2) +21)-qr_size, base_img.height()-107,
                                       base_img.width()-total_distance_h - border_thick -93,
                                       base_img.height()-total_distance_h - border_thick), Qt.AlignLeft, self.versioned_seed.get_ui_string_version_plus_seed())
                painter.drawText(QRect(0, base_img.height()-107, base_img.width()-total_distance_h - border_thick -3 -qr_size,
                                       base_img.height()-total_distance_h - border_thick), Qt.AlignRight, self.versioned_seed.checksum)

                # draw qr code
                qr_qt = self.paintQR(self.versioned_seed.get_ui_string_version_plus_seed()
                                     + self.versioned_seed.checksum)
                target = QRectF(base_img.width()-65-qr_size,
                                base_img.height()-65-qr_size,
                                qr_size, qr_size )
                painter.drawImage(target, qr_qt)
                painter.setPen(QPen(Qt.black, 4))
                painter.drawLine(base_img.width()-65-qr_size,
                                base_img.height()-65-qr_size,
                                 base_img.width() - 65 - qr_size,
                                (base_img.height() - ((total_distance_h))) - ((border_thick * 8)) - (border_thick / 2) - 4
                                 )
                painter.drawLine(base_img.width()-65-qr_size,
                                base_img.height()-65-qr_size,
                                 base_img.width() - 65,
                                base_img.height()-65-qr_size
                                 )
                painter.end()

        else: # calibration only
            painter.end()
            cal_img = QImage(self.f_size.width() + 100, self.f_size.height() + 100,
                              QImage.Format_ARGB32)
            cal_img.fill(Qt.white)

            cal_painter = QPainter()
            cal_painter.begin(cal_img)
            cal_painter.drawImage(0,0, base_img)

            #black lines in the middle of border top left only
            cal_painter.setPen(QPen(Qt.black, 1, Qt.DashDotDotLine))
            cal_painter.drawLine(0, dist_v, base_img.width(), dist_v)
            cal_painter.drawLine(dist_h, 0,  dist_h, base_img.height())

            pen = QPen(Qt.black, 2, Qt.DashDotDotLine)
            cal_painter.setPen(pen)
            n=15

            cal_painter.setFont(QFont("DejaVu Sans Mono", 21, QFont.Bold))
            for x in range(-n,n):
                #lines on bottom (vertical calibration)
                cal_painter.drawLine((((base_img.width())/(n*2)) *(x))+ (base_img.width()/2)-13,
                                 x+2+base_img.height()-(dist_v),
                                 (((base_img.width())/(n*2)) *(x))+ (base_img.width()/2)+13,
                                 x+2+base_img.height()-(dist_v))

                num_pos = 9
                if x > 9 : num_pos = 17
                if x < 0 : num_pos = 20
                if x < -9: num_pos = 27

                cal_painter.drawText((((base_img.width())/(n*2)) *(x))+ (base_img.width()/2)-num_pos,
                                 50+base_img.height()-(dist_v),
                                  str(x))

                #lines on the right (horizontal calibrations)

                cal_painter.drawLine(x+2+(base_img.width()-(dist_h)),
                                 ((base_img.height()/(2*n)) *(x))+ (base_img.height()/n)+(base_img.height()/2)-13,
                                 x+2+(base_img.width()-(dist_h)),
                                 ((base_img.height()/(2*n)) *(x))+ (base_img.height()/n)+(base_img.height()/2)+13)


                cal_painter.drawText(30+(base_img.width()-(dist_h)),
                                ((base_img.height()/(2*n)) *(x))+ (base_img.height()/2)+13, str(x))

            cal_painter.end()
            base_img = cal_img

        return base_img
コード例 #53
0
ファイル: neuroapp.py プロジェクト: kacpdeb/paint-ai
class Window(QMainWindow):
    def __init__(self):

        super().__init__()
        title = "Podaj liczbe do odczytania"
        top = 400
        left = 200
        width = 1000
        height = 800

        self.setWindowTitle(title)
        self.setGeometry(top, left, width, height)
        self.image = QImage(self.size(), QImage.Format_RGB32)
        self.image.fill(Qt.black)
        self.drawing = False
        self.brushSize = 80
        self.brushColor = Qt.white
        self.lastPoint = QPoint()

        mainMenu = self.menuBar()
        fileMenu = mainMenu.addMenu("Plik")
        saveAction = QAction(QIcon(), "Zbadaj[E]", self)
        saveAction.setShortcut("E")
        fileMenu.addAction(saveAction)
        saveAction.triggered.connect(self.save)
        clearAction = QAction(QIcon(), "wyczysc[W]", self)
        clearAction.setShortcut("W")
        fileMenu.addAction(clearAction)
        clearAction.triggered.connect(self.clear)

    def mousePressEvent(self, event):
        if event.button() == Qt.LeftButton:
            self.drawing = True
            self.lastPoint = event.pos()

    def mouseMoveEvent(self, event):
        if (event.buttons() & Qt.LeftButton) & self.drawing:
            painter = QPainter(self.image)
            painter.setPen(
                QPen(self.brushColor, self.brushSize, Qt.SolidLine,
                     Qt.RoundCap, Qt.RoundJoin))
            painter.drawLine(self.lastPoint, event.pos())
            self.lastPoint = event.pos()
            self.update()

    def mouseReleaseEvent(self, event):
        if event.button() == Qt.LeftButton:
            self.drawing = False

    def paintEvent(self, event):
        canvasPainter = QPainter(self)
        canvasPainter.drawImage(self.rect(), self.image, self.image.rect())

    def save(self):
        self.image.save(
            str(pathlib.Path(__file__).parent.absolute()) + "/" +
            "epaint_obraz.png")
        image = cv2.imread("epaint_obraz.png")
        image = resize_image(image, 28, 28)
        cv2.imwrite("epaint_obraz.png", image)
        json_file = open('model.json', 'r')
        loaded_model_json = json_file.read()
        json_file.close()
        loaded_model = model_from_json(loaded_model_json)
        loaded_model.load_weights("model.h5")
        img = imread('epaint_obraz.png')

        def rgb2gray(rgb):
            return np.dot(rgb[..., :3], [0.2989, 0.5870, 0.1140])

        gray = rgb2gray(img)
        gray = gray.reshape((1, 28, 28, 1))
        prediction = loaded_model.predict(gray)
        QMessageBox.about(self, "Liczba to:", str(np.argmax(prediction)))

    def clear(self):
        self.image.fill(Qt.black)
        self.update()
コード例 #54
0
ファイル: image_items.py プロジェクト: mercadil/EXtra-foam
class MaskItem(pg.GraphicsObject):
    """Mask item used for drawing mask on an ImageItem."""

    _TRANSPARENT = QColor(0, 0, 0, 0)
    _COLOR_FORMAT = QImage.Format_ARGB32

    def __init__(self, item, parent=None):
        """Initialization.

        :param ImageItem item: a reference to the masked image item.
        """
        super().__init__(parent=parent)
        if not isinstance(item, ImageItem):
            raise TypeError("Input item must be an ImageItem instance.")

        self._image_item = weakref.ref(item)
        item.draw_started_sgn.connect(self.onDrawStarted)
        item.draw_region_changed_sgn.connect(self.onDrawRegionChanged)
        item.draw_finished_sgn.connect(self.onDrawFinished)

        # pen for drawing the bounding box
        self._boundary_color = FColor.mkPen(
            config['GUI_MASK_BOUNDING_BOX_COLOR'])
        self._fill_color = FColor.mkColor(
            config['GUI_MASK_FILL_COLOR'], alpha=180)

        self.state = MaskState.UNMASK
        self._mask = None  # QImage
        self._mask_rect = QRectF(0, 0, 0, 0)
        self._mask_pub = ImageMaskPub()

        self._p1 = None
        self._p2 = None

    def maybeInitializeMask(self, shape):
        h, w = shape
        if self._mask is None:
            self._mask = QImage(w, h, self._COLOR_FORMAT)
            self._mask.fill(self._TRANSPARENT)
            self._mask_rect = QRectF(0, 0, w, h)

    def boundingRect(self):
        """Override."""
        return self._mask_rect

    @pyqtSlot(int, int)
    def onDrawStarted(self, x, y):
        self._p1 = (x, y)

    @pyqtSlot(int, int)
    def onDrawRegionChanged(self, x, y):
        self.prepareGeometryChange()
        self._p2 = (x, y)

    def _selectedRect(self):
        if self._p1 is None or self._p2 is None:
            return QRectF(0, 0, 0, 0)

        rect = QRectF(QPoint(*self._p1), QPoint(*self._p2))
        return rect.intersected(self._mask_rect)

    @pyqtSlot()
    def onDrawFinished(self):
        rect = self._selectedRect()
        x = int(rect.x())
        y = int(rect.y())
        w = int(rect.width())
        h = int(rect.height())

        if self.state == MaskState.MASK:
            self._mask_pub.draw((x, y, w, h))
        elif self.state == MaskState.UNMASK:
            self._mask_pub.erase((x, y, w, h))

        self._p1 = None
        self._p2 = None

        for i in range(x, x+w):
            for j in range(y, y+h):
                if self.state == MaskState.MASK:
                    self._mask.setPixelColor(i, j, self._fill_color)
                elif self.state == MaskState.UNMASK:
                    self._mask.setPixelColor(i, j, self._TRANSPARENT)

        self._updateImageItem()

    def removeMask(self):
        """Completely remove the current mask."""
        # The following sequence ensures that it can be used to rescue if
        # there is discrepancy between ImageTool and the ImageProcessor.

        self._mask_pub.remove()

        if self._mask is None:
            return

        self._mask.fill(self._TRANSPARENT)
        self._updateImageItem()

    def paint(self, p, *args):
        """Override."""
        if self._mask is None:
            return

        p.setRenderHint(QPainter.Antialiasing)
        p.setPen(self._boundary_color)

        p.drawImage(self.boundingRect(), self._mask)
        p.drawRect(self._selectedRect())

    def mask(self):
        w = self._mask.width()
        h = self._mask.height()

        mask_array = np.zeros((h, w), dtype=bool)
        for i in range(w):
            for j in range(h):
                mask_array[j, i] = \
                    self._mask.pixelColor(i, j) == self._fill_color

        return mask_array

    def setMask(self, mask):
        """Set a given image mask.

        :param np.ndarray mask: mask in ndarray. shape = (h, w)
        """
        self._mask_pub.set(mask)

        h, w = mask.shape
        self._mask = QImage(w, h, self._COLOR_FORMAT)

        for i in range(w):
            for j in range(h):
                if mask[j, i]:
                    self._mask.setPixelColor(i, j, self._fill_color)
                else:
                    self._mask.setPixelColor(i, j, self._TRANSPARENT)
        self._mask_rect = QRectF(0, 0, w, h)
        self._updateImageItem()

    def _updateImageItem(self):
        image_item = self._image_item()
        if image_item is not None:
            image_item.update()
コード例 #55
0
ファイル: Annotation.py プロジェクト: kkopecky711/TagLab
class Blob(object):
    """
    Blob data. A blob is a group of pixels.
    A blob can be tagged with the class and other information.
    Both the set of pixels and the corresponding vectorized version are stored.
    """
    def __init__(self, region, offset_x, offset_y, id):

        if region == None:

            # AN EMPTY BLOB IS CREATED..

            self.area = 0.0
            self.perimeter = 0.0
            self.centroid = np.zeros((2))
            self.bbox = np.zeros((4))

            # placeholder; empty contour
            self.contour = np.zeros((2, 2))
            self.inner_contours = []
            self.qpath = None
            self.qpath_gitem = None

            self.instance_name = "noname"
            self.blob_name = "noname"
            self.id = 0

        else:

            # extract properties

            self.centroid = np.array(region.centroid)
            cy = self.centroid[0]
            cx = self.centroid[1]
            self.centroid[0] = cx + offset_x
            self.centroid[1] = cy + offset_y

            # Bounding box (min_row, min_col, max_row, max_col).
            # Pixels belonging to the bounding box are in the half-open
            # interval [min_row, max_row) and [min_col, max_col).
            self.bbox = np.array(region.bbox)

            width = self.bbox[3] - self.bbox[1]
            height = self.bbox[2] - self.bbox[0]

            # BBOX ->  TOP, LEFT, WIDTH, HEIGHT
            self.bbox[0] = self.bbox[0] + offset_y
            self.bbox[1] = self.bbox[1] + offset_x
            self.bbox[2] = width
            self.bbox[3] = height

            # QPainterPath associated with the contours
            self.qpath = None

            # QGraphicsItem associated with the QPainterPath
            self.qpath_gitem = None

            # to extract the contour we use the mask cropped according to the bbox
            input_mask = region.image.astype(int)
            self.contour = np.zeros((2, 2))
            self.inner_contours = []
            self.createContourFromMask(input_mask)
            self.setupForDrawing()

            self.calculatePerimeter()
            self.calculateArea(input_mask)

            # a string with a progressive number to identify the instance
            self.instance_name = "coral" + str(id)

            # a string with a number to identify the blob plus its centroid
            xc = int(self.centroid[0])
            yc = int(self.centroid[1])
            self.blob_name = "blob" + str(id) + "-" + str(xc) + "-" + str(yc)
            self.id = id

        # deep extreme points (for fine-tuning)
        self.deep_extreme_points = np.zeros((4, 2))

        # name of the class
        self.class_name = "Empty"

        # color of the class
        self.class_color = [128, 128, 128]

        # note about the coral, i.e. damage type
        self.note = ""

        # QImage corresponding to the current mask
        self.qimg_mask = None

        # QPixmap associated with the mask (for pixel-level editing operations)
        self.pxmap_mask = None

        # QGraphicsItem associated with the pixmap mask
        self.pxmap_mask_gitem = None

        # membership group (if any)
        self.group = None

    def copy(self):

        blob = Blob()

        blob.centroid = self.centroid.copy()
        blob.bbox = self.bbox.copy()

        blob.classname = self.classname
        blob.classcolor = self.classcolor
        blob.instance_name = self.instance_name
        blob.id = self.id
        blob.note = self.note

        return blob

    def setId(self, id):

        # a string with a number to identify the blob plus its centroid
        xc = int(self.centroid[0])
        yc = int(self.centroid[1])
        self.blob_name = "blob" + str(id) + "-" + str(xc) + "-" + str(yc)
        self.id = id

    def getMask(self):
        """
        It creates the mask from the contour and returns it.
        """

        r = self.bbox[3]
        c = self.bbox[2]

        mask = np.zeros((r, c))

        # main polygon
        [rr, cc] = polygon(self.contour[:, 1], self.contour[:, 0])
        rr = rr - int(self.bbox[0])
        cc = cc - int(self.bbox[1])
        mask[rr, cc] = 1

        # holes
        for inner_contour in self.inner_contours:
            [rr, cc] = polygon(inner_contour[:, 1], inner_contour[:, 0])
            rr = rr - int(self.bbox[0])
            cc = cc - int(self.bbox[1])
            mask[rr, cc] = 0

        return mask

    def updateUsingMask(self, new_bbox, new_mask):

        self.bbox = new_bbox

        self.createContourFromMask(new_mask)
        self.setupForDrawing()

        self.calculatePerimeter()
        self.calculateArea(new_mask)
        self.calculateCentroid(new_mask)

    def snapToBorder(self, points):
        """
        Given a curve specified as a set of points, snap the curve on the blob mask:
          1) the initial segments of the curve are removed until they snap
          2) the end segments of the curve are removed until they snap

        """

        contour = self.contour.copy()
        test = points_in_poly(points, contour)
        jump = np.gradient(test.astype(int))
        ind = np.nonzero(jump)
        ind = np.asarray(ind)

        snappoints = None
        if ind.shape[1] > 2:
            first_el = ind[0, 0] + 1
            last_el = ind[0, -1]
            snappoints = points[first_el:last_el, :].copy()

        return snappoints

    def createFromClosedCurve(self, points):
        """
        It creates a blob starting from a closed curve. If the curve is not closed False is returned.
        If the curve intersect itself many times the first segmented region is created.
        """

        pt_min = np.amin(points, axis=0)
        xmin = pt_min[0]
        ymin = pt_min[1]
        pt_max = np.amax(points, axis=0)
        xmax = pt_max[0]
        ymax = pt_max[1]

        x_left = int(xmin) - 8
        y_top = int(ymin) - 8
        x_right = int(xmax) + 8
        y_bottom = int(ymax) + 8

        bbox = np.array([y_top, x_left, x_right - x_left, y_bottom - y_top])
        mask = np.zeros((bbox[3], bbox[2]))
        mask_area = bbox[3] * bbox[2]

        for i in range(points.shape[0]):

            x = points[i, 0]
            y = points[i, 1]

            yy = int(y) - bbox[0]
            xx = int(x) - bbox[1]

            for offsetx in range(-1, 2):
                for offsety in range(-1, 2):
                    mask[yy + offsety, xx + offsetx] = 1

        mask_flood = flood(mask, (4, 4), tolerance=0).astype(int)

        for i in range(points.shape[0]):

            x = points[i, 0]
            y = points[i, 1]

            yy = int(y) - bbox[0]
            xx = int(x) - bbox[1]

            for offsetx in range(-1, 2):
                for offsety in range(-1, 2):
                    mask_flood[yy + offsety, xx + offsetx] = 1

        for y in range(mask_flood.shape[0]):
            for x in range(mask_flood.shape[1]):
                if mask_flood[y, x] == 1:
                    mask[y, x] = 0
                else:
                    mask[y, x] = 1

        mask = ndi.binary_fill_holes(mask).astype(int)

        # check
        regions = measure.regionprops(mask)

        if len(regions) != 1:
            return False
        else:

            region = regions[0]
            check = region.area / mask_area
            if check > 0.95:
                return False
            else:
                self.updateUsingMask(bbox, mask)
                return True

    def createCrack(self, input_arr, x, y, tolerance, preview=True):
        """
        Given a inner blob point (x,y), the function use it as a seed for a paint butcket tool and create
        a correspondent blob hole
        """

        x_crop = x - self.bbox[1]
        y_crop = y - self.bbox[0]

        input_arr = gaussian(input_arr, 2)
        # input_arr = segmentation.inverse_gaussian_gradient(input_arr, alpha=1, sigma=1)

        blob_mask = self.getMask()

        crack_mask = flood(input_arr, (int(y_crop), int(x_crop)),
                           tolerance=tolerance).astype(int)
        cracked_blob = np.logical_and((blob_mask > 0), (crack_mask < 1))
        cracked_blob = cracked_blob.astype(int)

        if preview:
            return cracked_blob
        else:
            self.updateUsingMask(self.bbox, cracked_blob)
            return cracked_blob

    def addToMask(self, points):
        """
        Given a curve specified as a set of points, the pixels OUTSIDE the blob but inside the handle created
        by the curve are added to the blob.
        """

        # store the original inner contours (i.e. the holes)
        original_inner_contours = []
        for inner_contour in self.inner_contours:
            duplicate_inner_contour = inner_contour.copy()
            original_inner_contours.append(duplicate_inner_contour)

        # enlarge the mask
        y1A = self.bbox[0]
        x1A = self.bbox[1]
        x2A = x1A + self.bbox[2]
        y2A = y1A + self.bbox[3]

        pt_min = np.amin(points, axis=0)
        xmin = pt_min[0]
        ymin = pt_min[1]
        pt_max = np.amax(points, axis=0)
        xmax = pt_max[0]
        ymax = pt_max[1]

        x1B = int(xmin)
        y1B = int(ymin)
        x2B = int(xmax)
        y2B = int(ymax)

        x_left = min(x1A, x1B) - 2
        y_top = min(y1A, y1B) - 2
        x_right = max(x2A, x2B) + 2
        y_bottom = max(y2A, y2B) + 2

        bbox_union = np.array(
            [y_top, x_left, x_right - x_left, y_bottom - y_top])
        mask_union = np.zeros((bbox_union[3], bbox_union[2]))

        blob_mask = self.getMask()
        for y in range(blob_mask.shape[0]):
            for x in range(blob_mask.shape[1]):

                yy = y + (self.bbox[0] - bbox_union[0])
                xx = x + (self.bbox[1] - bbox_union[1])
                mask_union[yy, xx] = blob_mask[y, x]

        for i in range(points.shape[0]):

            x = points[i, 0]
            y = points[i, 1]

            yy = int(y) - bbox_union[0]
            xx = int(x) - bbox_union[1]

            for offsetx in range(-1, 2):
                for offsety in range(-1, 2):
                    mask_union[yy + offsety, xx + offsetx] = 1

        mask_union = ndi.binary_fill_holes(mask_union).astype(int)

        self.updateUsingMask(bbox_union, mask_union)

        # RE-ADD THE ORIGINAL INNER CONTOURS (I.E. THE HOLES)
        if original_inner_contours:
            self.inner_contours.clear()
            for inner_contour in original_inner_contours:

                # recover inner contour list
                self.inner_contours.append(inner_contour)

            # update qpainterpath
            self.setupForDrawing()

    def cutFromMask(self, points):
        """
        Given a curve specified as a set of points, the pixels INSIDE the blob but "cutted" by the curve
        are removed from the blob.
        """

        # enlarge the mask
        y1A = self.bbox[0]
        x1A = self.bbox[1]
        x2A = x1A + self.bbox[2]
        y2A = y1A + self.bbox[3]

        pt_min = np.amin(points, axis=0)
        xmin = pt_min[0]
        ymin = pt_min[1]
        pt_max = np.amax(points, axis=0)
        xmax = pt_max[0]
        ymax = pt_max[1]

        x1B = int(xmin)
        y1B = int(ymin)
        x2B = int(xmax)
        y2B = int(ymax)

        x_left = min(x1A, x1B) - 2
        y_top = min(y1A, y1B) - 2
        x_right = max(x2A, x2B) + 2
        y_bottom = max(y2A, y2B) + 2

        bbox_union = np.array(
            [y_top, x_left, x_right - x_left, y_bottom - y_top])
        mask_union = np.zeros((bbox_union[3], bbox_union[2]))

        blob_mask = self.getMask()
        for y in range(blob_mask.shape[0]):
            for x in range(blob_mask.shape[1]):

                yy = y + (self.bbox[0] - bbox_union[0])
                xx = x + (self.bbox[1] - bbox_union[1])
                mask_union[yy, xx] = blob_mask[y, x]

        for i in range(points.shape[0]):

            x = points[i, 0]
            y = points[i, 1]

            yy = int(y) - bbox_union[0]
            xx = int(x) - bbox_union[1]

            for offsetx in range(-1, 2):
                for offsety in range(-1, 2):
                    mask_union[yy + offsety, xx + offsetx] = 0

        label_image = measure.label(mask_union)
        regions = measure.regionprops(label_image)

        if len(regions) > 1:

            # TENERE SOLO QUELLA CON AREA MASSIMA ??

            area_max = 0
            region_to_remove = None
            for region in regions:

                if region.area > area_max:
                    area_max = region.area

            for region in regions:
                if region.area < area_max:
                    for coords in region.coords:
                        mask_union[coords[0], coords[1]] = 0

        self.updateUsingMask(bbox_union, mask_union)

    def createContourFromMask(self, mask):
        """
        It creates the contour (and the corrisponding polygon) from the blob mask.
        """

        # NOTE: The mask is expected to be cropped around its bbox (!!) (see the __init__)

        self.inner_contours.clear()

        # we need to pad the mask to avoid to break the contour that touchs the borders
        PADDED_SIZE = 2
        img_padded = pad(mask, (PADDED_SIZE, PADDED_SIZE),
                         mode="constant",
                         constant_values=(0, 0))

        contours = measure.find_contours(img_padded, 0.5)

        number_of_contours = len(contours)

        if number_of_contours > 1:

            # search the longest contour
            npoints_max = 0
            index = 0
            for i, contour in enumerate(contours):
                npoints = contour.shape[0]
                if npoints > npoints_max:
                    npoints_max = npoints
                    index = i

            # divide the contours in OUTER contour and INNER contours
            for i, contour in enumerate(contours):
                if i == index:
                    self.contour = np.array(contour)
                else:
                    coordinates = np.array(contour)
                    self.inner_contours.append(coordinates)

            # adjust the coordinates of the outer contour
            # (NOTE THAT THE COORDINATES OF THE BBOX ARE IN THE GLOBAL MAP COORDINATES SYSTEM)
            for i in range(self.contour.shape[0]):
                ycoor = self.contour[i, 0]
                xcoor = self.contour[i, 1]
                self.contour[i, 0] = xcoor - PADDED_SIZE + self.bbox[1]
                self.contour[i, 1] = ycoor - PADDED_SIZE + self.bbox[0]

            # adjust coordinates of the INNER contours
            for j, contour in enumerate(self.inner_contours):
                for i in range(contour.shape[0]):
                    ycoor = contour[i, 0]
                    xcoor = contour[i, 1]
                    self.inner_contours[j][
                        i, 0] = xcoor - PADDED_SIZE + self.bbox[1]
                    self.inner_contours[j][
                        i, 1] = ycoor - PADDED_SIZE + self.bbox[0]

        elif number_of_contours == 1:

            coords = measure.approximate_polygon(contours[0], tolerance=1.2)
            self.contour = np.array(coords)

            # adjust the coordinates of the outer contour
            # (NOTE THAT THE COORDINATES OF THE BBOX ARE IN THE GLOBAL MAP COORDINATES SYSTEM)
            for i in range(self.contour.shape[0]):
                ycoor = self.contour[i, 0]
                xcoor = self.contour[i, 1]
                self.contour[i, 0] = xcoor - PADDED_SIZE + self.bbox[1]
                self.contour[i, 1] = ycoor - PADDED_SIZE + self.bbox[0]
        else:

            print("ZERO CONTOURS -> THERE ARE SOME PROBLEMS HERE !!!!!!)")

    def setupForDrawing(self):
        """
        Create the QPolygon and the QPainterPath according to the blob's contours.
        """

        # QPolygon to draw the blob
        qpolygon = QPolygonF()
        for i in range(self.contour.shape[0]):
            qpolygon << QPointF(self.contour[i, 0], self.contour[i, 1])

        self.qpath = QPainterPath()
        self.qpath.addPolygon(qpolygon)

        for inner_contour in self.inner_contours:
            qpoly_inner = QPolygonF()
            for i in range(inner_contour.shape[0]):
                qpoly_inner << QPointF(inner_contour[i, 0], inner_contour[i,
                                                                          1])

            path_inner = QPainterPath()
            path_inner.addPolygon(qpoly_inner)
            self.qpath = self.qpath.subtracted(path_inner)

    def createQPixmapFromMask(self):

        w = self.bbox[2]
        h = self.bbox[3]
        self.qimg_mask = QImage(w, h, QImage.Format_ARGB32)
        self.qimg_mask.fill(qRgba(0, 0, 0, 0))

        if self.class_name == "Empty":
            rgba = qRgba(255, 255, 255, 255)
        else:
            rgba = qRgba(self.class_color[0], self.class_color[1],
                         self.class_color[2], 100)

        blob_mask = self.getMask()
        for x in range(w):
            for y in range(h):
                if mask[y, x] == 1:
                    self.qimg_mask.setPixel(x, y, rgba)

        self.pxmap_mask = QPixmap.fromImage(self.qimg_mask)

    def calculateCentroid(self, mask):

        sumx = 0.0
        sumy = 0.0
        n = 0

        for y in range(mask.shape[0]):
            for x in range(mask.shape[1]):
                if mask[y, x] == 1:
                    sumx += float(x)
                    sumy += float(y)
                    n += 1

        # NOTE: centroid is (x,y), bbox is [width height]
        self.centroid[0] = int(sumx / n) + self.bbox[1]
        self.centroid[1] = int(sumy / n) + self.bbox[0]

        xc = int(self.centroid[0])
        yc = int(self.centroid[1])
        self.instance_name = "coral-" + str(xc) + "-" + str(yc)

    def calculateContourPerimeter(self, contour):

        # perimeter of the outer contour
        px1 = contour[0, 0]
        py1 = contour[0, 1]
        N = contour.shape[0]
        pxlast = contour[N - 1, 0]
        pylast = contour[N - 1, 1]
        perim = math.sqrt((px1 - pxlast) * (px1 - pxlast) + (py1 - pylast) *
                          (py1 - pylast))
        for i in range(1, contour.shape[0]):
            px2 = contour[i, 0]
            py2 = contour[i, 1]

            d = math.sqrt((px1 - px2) * (px1 - px2) + (py1 - py2) *
                          (py1 - py2))
            perim += d

            px1 = px2
            py1 = py2

        return perim

    def calculatePerimeter(self):

        self.perimeter = self.calculateContourPerimeter(self.contour)

        for contour in self.inner_contours:
            self.perimeter += self.calculateContourPerimeter(self.contour)

    def calculateArea(self, mask):

        self.area = 0.0
        for y in range(mask.shape[0]):
            for x in range(mask.shape[1]):
                if mask[y, x] == 1:
                    self.area += 1.0

    def fromDict(self, dict):
        """
        Set the blob information given it represented as a dictionary.
        """

        self.bbox = np.asarray(dict["bbox"])

        self.centroid = np.asarray(dict["centroid"])
        self.area = dict["area"]
        self.perimeter = dict["perimeter"]

        self.contour = np.asarray(dict["contour"])
        inner_contours = dict["inner contours"]
        self.inner_contours = []
        for c in inner_contours:
            self.inner_contours.append(np.asarray(c))

        self.deep_extreme_points = np.asarray(dict["deep_extreme_points"])
        self.class_name = dict["class name"]
        self.class_color = dict["class color"]
        self.instance_name = dict["instance name"]
        self.blob_name = dict["blob name"]
        self.id = dict["id"]
        self.note = dict["note"]

        # finalize blob
        self.setupForDrawing()

    def toDict(self):
        """
        Get the blob information as a dictionary.
        """

        dict = {}

        dict["bbox"] = self.bbox.tolist()

        dict["centroid"] = self.centroid.tolist()
        dict["area"] = self.area
        dict["perimeter"] = self.perimeter

        dict["contour"] = self.contour.tolist()

        dict["inner contours"] = []
        for c in self.inner_contours:
            dict["inner contours"].append(c.tolist())

        dict["deep_extreme_points"] = self.deep_extreme_points.tolist()

        dict["class name"] = self.class_name
        dict["class color"] = self.class_color

        dict["instance name"] = self.instance_name
        dict["blob name"] = self.blob_name
        dict["id"] = self.id
        dict["note"] = self.note

        return dict
コード例 #56
0
ファイル: MyDrawing.py プロジェクト: IlnurAgl/MyDrawing
class Paint(QMainWindow):  # Создание окна
    def __init__(self):  # Инициализация
        super().__init__()

        try:  # Попытка прочитать файл
            f = open('size.txt', 'r')
            width = int(f.readline())  # Ширина окна
            height = int(f.readline())  # Высота окна
            f.close()
        except Exception:  # Если ошибка
            f = open('size.txt', 'w')  # Создать файл
            f.write('1200' + '\n' + '900')  # Перезапись файла
            f.close()  # Закрытие файла
            width = 1200
            height = 900

        self.coords = QLabel(self)  # Координаты мыши
        self.coords.setText("Координаты:None, None")  # Изначальные координаты
        self.coords.resize(150, 15)  # Изменение размера
        self.coords.move(width - 150, height - 20)  # Перемещение

        self.last = 0  # Количество изображений

        self.setMouseTracking(True)  # Отслеживание мыши без нажатия

        self.copyA = False  # Переменная для области копирования

        icon = 'icons/main.png'  # Ссылка на основную иконку

        os.makedirs('last')  # Создание путой папки

        self.setWindowTitle('MyDrawing')  # Назвние окна
        self.setGeometry(0, 35, width, height)  # Размеры окна
        self.setWindowIcon(QIcon(icon))  # Иконка окна

        # Создание изображения
        self.image = QImage(self.size(), QImage.Format_RGB32)
        self.image.fill(Qt.white)  # Заливка изображения белым цветом

        # Добавление картинки
        self.image.save('last/' + str(self.last) + '.png')
        self.last += 1  # Добавление к количеству картинок

        self.drawing = False  # Переменная для рисования
        self.brushSize = 2  # Размер кисти
        self.brushColor = Qt.black  # Цвет кисти
        self.lastPoint = QPoint()  # Координаты последней точки

        mainMenu = self.menuBar()  # Создание меню
        fileMenu = mainMenu.addMenu('Файл')  # Добавление в меню вкладки "Файл"
        # Добавление в меню кнопки "Размер кисти"
        brushMenu = mainMenu.addMenu('Размер кисти')
        # Добавление в меню кнопки "Цвет кисти"
        brushColor = mainMenu.addMenu('Цвет кисти')
        # Добавление в меню кнопки "Геометричсекие фигуры"
        shapes = mainMenu.addMenu('Геометрические фигуры')

        # Создание кнопки сохранения и добавление иконки
        saveAction = QAction(QIcon('icons/save.jpg'), 'Сохранить', self)
        saveAction.setShortcut('Ctrl+S')  # Добавление комбинации клавиш
        fileMenu.addAction(saveAction)  # Добавление в меню

        # Вызов функции save() при нажатии
        saveAction.triggered.connect(self.save)

        # Создание кнопки очистки и добавление иконки
        clearAction = QAction(QIcon('icons/clear.jpeg'), 'Очистить', self)
        clearAction.setShortcut('Ctrl+A')  # Добавление комбинации клавиш
        fileMenu.addAction(clearAction)  # Добавление в меню
        clearAction.triggered.connect(self.clear)  # Вызов функции при нажатии

        # Создание кнопки для изменения размера окна
        sizeAction = QAction(QIcon('icons/size.png'), 'Изменить размер', self)
        sizeAction.setShortcut('Ctrl+T')  # Добавление комбинации клавиш
        fileMenu.addAction(sizeAction)  # Добавление в меню
        sizeAction.triggered.connect(self.sizeAdd)  # Вызов функции при нажатии

        # Создание кнопки для добавления изображения
        addAction = QAction(QIcon('icons/picture.jpg'), 'Добавить изображение',
                            self)
        addAction.setShortcut('Ctrl+N')  # Добавление комбинации клавиш
        fileMenu.addAction(addAction)  # Добавление в меню

        # При нажатии вызов функции
        addAction.triggered.connect(self.addPicture)

        # Создание кнопки для копирования области
        copyAction = QAction(QIcon('icons/copy.png'), 'Копировать', self)
        copyAction.setShortcut('Ctrl+C')  # Добавление комбинации клавиш
        fileMenu.addAction(copyAction)  # Добавление в меню

        # При нажатии вызов функции
        copyAction.triggered.connect(self.copyArea)

        # Создание кнопки вырезать
        cutAction = QAction(QIcon('icons/cut.jpg'), 'Вырезать', self)
        cutAction.setShortcut('Ctrl+X')  # Добавление комбинации клавиш
        fileMenu.addAction(cutAction)  # Добавление в меню

        # Вызов функции при нажатии
        cutAction.triggered.connect(self.cutArea)

        # Создание кнопки для вставки области
        pasteAction = QAction(QIcon('icons/paste.jpg'), 'Вставить', self)
        pasteAction.setShortcut('Ctrl+V')  # Добавление комбинации клавиш
        fileMenu.addAction(pasteAction)  # Добавление в меню

        # При нажатии вызов функции
        pasteAction.triggered.connect(self.pasteArea)

        # Создание кнопки для заливки
        pourAction = QAction(QIcon('icons/pour.jpg'), 'Залить', self)
        pourAction.setShortcut('Ctrl+H')  # Добавление комбинации клавиш
        fileMenu.addAction(pourAction)  # Добавление в меню

        # Вызов функции при нажатии
        pourAction.triggered.connect(self.fillAll)

        # Создание кнопки отмена
        cancelAction = QAction(QIcon('icons/back.png'), 'Отмена', self)
        cancelAction.setShortcut('Ctrl+Z')  # Добавление комбинации клавиш
        fileMenu.addAction(cancelAction)  # Добавление в меню

        # Вызов функции при нажатии
        cancelAction.triggered.connect(self.returnLast)

        undoAction = QAction(QIcon('icons/undo.png'), 'Вернуть', self)
        undoAction.setShortcut('Ctrl+Shift+Z')  # Добавление комбинации клавиш
        fileMenu.addAction(undoAction)  # Добавление в меню

        # Вызов функции при нажатии
        undoAction.triggered.connect(self.returnUp)

        # Создание кнопки 3 px и добавление иконки
        px3Action = QAction(QIcon('icons/3.jpg'), '3 px', self)
        px3Action.setShortcut('Ctrl+3')  # Добавление комбинации клавиш
        brushMenu.addAction(px3Action)  # Добавление в меню
        px3Action.triggered.connect(self.px3)  # Вызов функции при нажатии

        # Создание кнопки 5 px и добавление иконки
        px5Action = QAction(QIcon('icons/5.jpg'), '5 px', self)
        px5Action.setShortcut('Ctrl+5')  # Добавление комбинации клавиш
        brushMenu.addAction(px5Action)  # Добавление в меню
        px5Action.triggered.connect(self.px5)  # Вызов функции при нажатии

        # Создание кнопки 7 px и добавление иконки
        px7Action = QAction(QIcon('icons/7.jpg'), '7 px', self)
        px7Action.setShortcut('Ctrl+7')  # Добавление комбинации клавиш
        brushMenu.addAction(px7Action)  # Добавление в меню
        px7Action.triggered.connect(self.px7)  # Вызов функции при нажатии

        # Создание кнопки 9 px и добавление иконки
        px9Action = QAction(QIcon('icons/9.jpg'), '9 px', self)
        px9Action.setShortcut('Ctrl+9')  # Добавление комбинации клавиш
        brushMenu.addAction(px9Action)  # Добавление в меню
        px9Action.triggered.connect(self.px9)  # Вызов функции при нажатии

        # Создание кнопки для всех размеров
        pxOtherAction = QAction(QIcon('icons/pxO.jpg'), 'Все размеры', self)
        pxOtherAction.setShortcut('Ctrl+P')  # Добавление комбинации клавиш
        brushMenu.addAction(pxOtherAction)  # Добавление в меню

        # Вызов функции при нажатии
        pxOtherAction.triggered.connect(self.pxOther)

        # Создание кнопки для выбора черного цвета
        blackAction = QAction(QIcon('icons/black.jpg'), 'Черный цвет', self)
        blackAction.setShortcut('Ctrl+B')  # Добавление комбинации клавиш
        brushColor.addAction(blackAction)  # Добавление в меню
        # Вызов функции при нажатии
        blackAction.triggered.connect(self.blackColor)

        # Создание кнопки для выбора белого цвета
        whiteAction = QAction(QIcon('icons/clean.jpg'), 'Ластик', self)
        whiteAction.setShortcut('Ctrl+W')  # Добавление комбинации клавиш
        brushColor.addAction(whiteAction)  # Добавление в меню

        # Вызов функции при нажатии
        whiteAction.triggered.connect(self.whiteColor)

        # Создание кнопки для выбора красного цвета
        redAction = QAction(QIcon('icons/red.png'), 'Красный цвет', self)
        redAction.setShortcut('Ctrl+R')  # Добавление комбинации клавиш
        brushColor.addAction(redAction)  # Добавление в меню
        redAction.triggered.connect(self.redColor)  # Вызов функции при нажатии

        # Создание кнопки для выбора зеленого цвета
        greenAction = QAction(QIcon('icons/green.png'), 'Зеленый цвет', self)
        greenAction.setShortcut('Ctrl+G')  # Добавление комбинации клавиш
        brushColor.addAction(greenAction)  # Добавление в меню

        # Вызов функции при нажатии
        greenAction.triggered.connect(self.greenColor)

        # Создание кнопки для выбора желтого цвета
        yellowAction = QAction(QIcon('icons/yellow.png'), 'Желтый цвет', self)
        yellowAction.setShortcut('Ctrl+Y')  # Добавление комбинации клавиш
        brushColor.addAction(yellowAction)  # Добавление в меню

        # Вызов функции при нажатии
        yellowAction.triggered.connect(self.yellowColor)

        # Создание кнопки для выбора всех цветов
        otherAction = QAction(QIcon('icons/other.jpg'), 'Другие цвета', self)
        otherAction.setShortcut('Ctrl+O')  # Добавление комбинации клавиш
        brushColor.addAction(otherAction)  # Добавление в меню

        # Вызов функции при нажатии
        otherAction.triggered.connect(self.otherColor)

        # Создание кнопки для прямоугольника
        rectangleAction = QAction(QIcon('icons/rectangle.jpg'),
                                  'Прямоугольник', self)
        shapes.addAction(rectangleAction)  # Добавление прямоугольника в меню

        # Вызов функции при нажатии
        rectangleAction.triggered.connect(self.rectangle)

        # Создание кнопки эллипса
        ellipsAction = QAction(QIcon('icons/ellipse.png'), 'Эллипс', self)
        shapes.addAction(ellipsAction)  # Добавление эллипса в меню

        # Вызов функции при нажатии
        ellipsAction.triggered.connect(self.ellips)

        # Создание кнопки для линии
        lineAction = QAction(QIcon('icons/line.jpg'), 'Линия', self)
        shapes.addAction(lineAction)  # Добавление линии в меню

        # Вызов функции при нажатии
        lineAction.triggered.connect(self.line)

        # Создание кнопки для звезды
        starAction = QAction(QIcon('icons/star.png'), 'Звезда', self)
        shapes.addAction(starAction)  # Добавление звезды в меню

        # Вызов функции при нажатии
        starAction.triggered.connect(self.star)

        # Создание кнопки для текста
        textAction = QAction(QIcon('icons/text.png'), 'Текст', self)
        shapes.addAction(textAction)  # # Добавление текста в меню

        # Вызов функции при нажатии
        textAction.triggered.connect(self.writeText)

        # Создание кнопки для треугольник
        triangleAction = QAction(QIcon('icons/triangle.png'), 'Треугольник',
                                 self)
        shapes.addAction(triangleAction)

        # Вызов функции при нажатии
        triangleAction.triggered.connect(self.triangle)

    # Функция нажатия кнопки мыши
    def mousePressEvent(self, event, cord=False):
        if event.button() == Qt.LeftButton:  # Если нажата левая кнопка
            self.drawing = True  # То переменная рисования True
            self.lastPoint = event.pos()  # Координаты послдней точки

    def mouseMoveEvent(self, event):  # Функция перемещения мышки
        # Изменение координаты в QLabel
        self.coords.setText("Координаты:{}, {}".format(event.x(), event.y()))

        # Если нажата левая кнопка и переменная рисования
        if event.buttons() and Qt.LeftButton and self.drawing:
            painter = QPainter(self.image)  # Создание объекта QPainter
            # Цвет и свойства
            painter.setPen(
                QPen(self.brushColor, self.brushSize, Qt.SolidLine,
                     Qt.RoundCap, Qt.RoundJoin))
            painter.drawLine(self.lastPoint, event.pos())  # Рисование линии
            self.lastPoint = event.pos()  # Изменение последней координаты
            self.update()  # Обновление окна

    def mouseReleaseEvent(self, event):  # Функция отжатия кнопки
        self.lastImage()
        self.drawing = False  # переменна рисования False

    def paintEvent(self, event):  # Функция рисовая
        canvasPainter = QPainter(self)  # Создание объекта
        # Рисование линии
        canvasPainter.drawImage(self.rect(), self.image, self.image.rect())

    def save(self):  # Функция сохранения
        # Сохранение пути
        files = 'PNG(*.png);;JPEG(*.jpg *jpeg);; ALL Files(*.*)'
        filePath, _ = QFileDialog.getSaveFileName(self,
                                                  'Сохранить изображение', '',
                                                  files)
        if not filePath:  # Проверка на пустоту пути
            return
        self.image.save(filePath)  # Сохранение

    def clear(self):  # Функция очистки
        self.image.fill(Qt.white)  # Заливка изображения белым
        self.update()  # Обновление изображения

    def px3(self):  # Функция изменения размера
        self.brushSize = 3

    def px5(self):  # Функция изменения размера
        self.brushSize = 5

    def px7(self):  # Функция изменения размера
        self.brushSize = 7

    def px9(self):  # Функция изменения размера
        self.brushSize = 9

    def pxOther(self):  # Функция изменения размера
        i, okBtnPressed = QInputDialog.getInt(self, "Толщина", "Толщина линии",
                                              2, 1, 80, 1)
        self.brushSize = i

    def blackColor(self):  # Функция изменения цвета
        self.brushColor = Qt.black

    def whiteColor(self):  # Функция изменения цвета
        self.brushColor = Qt.white

    def redColor(self):  # Функция изменения цвета
        self.brushColor = Qt.red

    def greenColor(self):  # Функция изменения цвета
        self.brushColor = Qt.green

    def yellowColor(self):  # Функция изменения цвета
        self.brushColor = Qt.yellow

    def otherColor(self):  # Функция изменения цвета
        self.brushColor = QColorDialog.getColor()

    # Функция получения координат от пользователя
    def get_cord(self, title, qustion, _min, _max):
        cord, okBtnPressed = QInputDialog.getInt(self, title, qustion, 0, _min,
                                                 _max, 1)
        return cord

    # Функция для создания прямоугольника
    def rectangle(self):
        # Координата левого верхнего угла по x
        leftX = self.get_cord("Координата x",
                              "Координата левого верхнего угла по x", 0, 1200)
        # Координата левого верхнего угла по y
        leftY = self.get_cord("Координата y",
                              "Координата левого верхнего угла по y", 0, 2000)
        width = self.get_cord("Длина", "Длина", 0, 2000)  # Длина
        height = self.get_cord("Высота", "Высота", 0, 2000)  # высота
        cP = QPainter(self.image)  # Создание объекта класса QPainter
        cP.setPen(self.brushColor)  # Цвет границ
        cP.setBrush(self.brushColor)  # Цвет фигуры
        cP.drawRect(leftX, leftY, width, height)  # Нанесение прямоугольника
        self.lastImage()
        self.update()  # Обновление рисунка

    def ellips(self):  # Функция создания эллипса
        x = self.get_cord('Координата x', 'Координата центра по x', 0,
                          2000)  # Координата центра по x
        y = self.get_cord('Координата по y', 'Координата центра по y', 0,
                          2000)  # Координата центра по y
        w = self.get_cord("Ширина", "Ширина", 0, 2000)  # ширина
        h = self.get_cord("Высота", "Высота", 0, 2000)  # высота
        cP = QPainter(self.image)  # Создание объекта класса QPainter
        cP.setPen(self.brushColor)  # Цвет границ
        cP.setBrush(self.brushColor)  # Цвет фигуры
        cP.drawEllipse(x, y, w, h)  # Рисование эллипса
        self.lastImage()  # Добавление изображения
        self.update()  # обновление рисунка

    def addPicture(self):

        # Выбор разрешений
        files = 'PNG(*.png);;JPEG(*.jpg *jpeg);; ALL Files(*.*)'

        # Выбор файла
        filePath, _ = QFileDialog.getOpenFileName(self, 'Выбрать', '', files)
        img = QImage(filePath)  # Открытие изображения
        painter = QPainter(self.image)  # Создание объекта
        x = self.get_cord('Координата x',
                          'Координата левого верхнего угла по x', 0,
                          2000)  # Координата левого верхнего угла по x
        y = self.get_cord('Координата по y',
                          'Координата левого верхнего угла по y', 0,
                          2000)  # Координата левого верхнего угла по y
        painter.drawImage(x, y, img)  # Вывод изображения
        self.lastImage()  # Добавление изображения
        self.update()  # Обновление окна

    def line(self):
        x1 = self.get_cord('Координата x', 'Координата первой точки по x', 0,
                           2000)  # Координата первой точки по x
        y1 = self.get_cord('Координата по y', 'Координата первой точки по y',
                           0, 2000)  # Координата первой точки по y
        x2 = self.get_cord('Координата x', 'Координата второй точки по x', 0,
                           2000)  # Координата второй точки по x
        y2 = self.get_cord('Координата по y', 'Координата второй точки по y',
                           0, 2000)  # Координата второй точки по y
        cP = QPainter(self.image)
        cP.setPen(QPen(self.brushColor, self.brushSize))  # Цвет границ
        cP.setBrush(self.brushColor)  # Цвет фигуры
        cP.drawLine(x1, y1, x2, y2)  # Рисование линии
        self.lastImage()  # Добавление изображения
        self.update()  # Обновление окна

    def star(self):
        x1 = self.get_cord('Координата x', 'Координата верхней точки по x', 0,
                           2000)  # Координата верхней точки по x
        y1 = self.get_cord('Координата по y', 'Координата верхней точки по y',
                           0, 2000)  # Координата верхней точки по y
        x2 = self.get_cord('Координата x', 'Координата левой точки по x', 0,
                           2000)  # Координата левой точки по x
        y2 = self.get_cord('Координата по y', 'Координата левой точки по y', 0,
                           2000)  # Координата левой точки по y
        x3 = self.get_cord('Координата x',
                           'Координата левой нижней точки по x', 0,
                           2000)  # Координата левой нижней точки по x
        y3 = self.get_cord('Координата по y',
                           'Координата левой нижней точки по y', 0,
                           2000)  # Координата левой нижней точки по y
        cP = QPainter(self.image)
        cP.setPen(self.brushColor)  # Цвет границ
        cP.setBrush(self.brushColor)  # Цвет фигуры
        points = QPolygon([
            QPoint(x2, y2),
            QPoint(x1 + x1 - x2, y2),
            QPoint(x3, y3),
            QPoint(x1, y1),
            QPoint(x1 + x1 - x3, y3)
        ])
        self.lastImage()  # Добавление изображения
        cP.drawPolygon(points)  # Нарисовать полигон

    def triangle(self):  # Функция для рисования треугольника
        x1 = self.get_cord('Координата x', 'Координата первой точки по x', 0,
                           2000)  # Координата первой точки по x
        y1 = self.get_cord('Координата по y', 'Координата первой точки по y',
                           0, 2000)  # Координата первой точки по y
        x2 = self.get_cord('Координата x', 'Координата второй точки по x', 0,
                           2000)  # Координата второй точки по x
        y2 = self.get_cord('Координата по y', 'Координата второй точки по y',
                           0, 2000)  # Координата второй точки по y
        x3 = self.get_cord('Координата x', 'Координата третьей точки по x', 0,
                           2000)  # Координата третьей нижней точки по x
        y3 = self.get_cord('Координата по y', 'Координата третьей точки по y',
                           0, 2000)  # Координата третьей нижней точки по y
        cP = QPainter(self.image)
        cP.setPen(self.brushColor)  # Цвет границ
        cP.setBrush(self.brushColor)  # Цвет фигуры
        points = QPolygon([QPoint(x1, y1), QPoint(x2, y2), QPoint(x3, y3)])
        self.lastImage()  # Добавление изображения
        cP.drawPolygon(points)  # Нарисовать полигон

    def copyArea(self):  # Функция копирования области
        x = self.get_cord('Координата x',
                          'Координата левого верхнего угла по x', 0,
                          2000)  # Координата левого верхнего угла по x
        y = self.get_cord('Координата по y',
                          'Координата левого верхнего угла по y', 0,
                          2000)  # Координата левого верхнего угла по y
        w = self.get_cord("Ширина", "Ширина", 0, 2000)  # ширина
        h = self.get_cord("Высота", "Высота", 0, 2000)  # высота
        self.copyA = QImage.copy(self.image, x, y, w, h)

    def writeText(self):  # Функция для вывода текста
        i, okBtnPressed = QInputDialog.getText(
            self, "Текст", "Введите текст")  # Диалоговое окно для ввода текста
        cP = QPainter(self.image)
        cP.setPen(self.brushColor)
        cP.setFont(QFont('Decorative', self.get_cord('Шрифт', 'Шрифт', 1,
                                                     150)))  # Шрифт
        cP.drawText(
            self.get_cord('Координата x',
                          'Координата левого нижнего угла по x', 0, 2000),
            self.get_cord('Координата y',
                          'Координата левого нижнего угла по y', 0, 2000),
            i)  # Координата
        self.lastImage()  # Добавление изображения
        self.update()  # Обновление страницы

    def fillAll(self):  # Функция для заливки окна
        self.image.fill(self.brushColor)  # Заливка цветом
        self.lastImage()  # Добавление изображения
        self.update()  # Обновление картины

    def cutArea(self):  # Функция для вырезания области
        x = self.get_cord('Координата x',
                          'Координата левого верхнего угла по x', 0,
                          2000)  # Координата левого верхнего угла по x
        y = self.get_cord('Координата по y',
                          'Координата левого верхнего угла по y', 0,
                          2000)  # Координата левого верхнего угла по y
        w = self.get_cord("Ширина", "Ширина", 0, 2000)  # ширина
        h = self.get_cord("Высота", "Высота", 0, 2000)  # высота
        self.copyA = QImage.copy(self.image, x, y, w, h)
        cP = QPainter(self.image)  # Создание объекта класса QPainter
        cP.setPen(Qt.white)
        cP.setBrush(Qt.white)
        cP.drawRect(x, y, w, h)  # Закраска области в белый
        self.update()  # Обновление рисунка

    def pasteArea(self):  # Функция вставки области
        if not self.copyA:  # Если область пустая
            return
        x = self.get_cord('Координата x',
                          'Координата левого верхнего угла по x', 0,
                          2000)  # Координата левого верхнего угла по x
        y = self.get_cord('Координата по y',
                          'Координата левого верхнего угла по y', 0,
                          2000)  # Координата левого верхнего угла по y
        painter = QPainter(self.image)  # Создание объекта
        painter.drawImage(x, y, self.copyA)  # Вывод изображения
        self.lastImage()  # Добавление изображения
        self.update()  # Обновление окна

    def sizeAdd(self):  # Функция изменения размера окна
        w = self.get_cord('Ширина окна', 'Ширина окна', 0, 2000)  # Ширина окна
        h = self.get_cord('Высота окна', 'Высота окна', 0, 2000)  # Высота окна
        f = open('size.txt', 'w')  # Открытие файла с размерами
        f.write(str(w) + '\n' + str(h))  # Перезапись файла
        f.close()  # Закрытие файла
        QMessageBox.about(self, "Перезапустите программу",
                          "Перезапустите программу")  # Сообщение

    def closeEvent(self, event):  # Функция для закрытия
        # Сообщение при закрытии приложения
        reply = QMessageBox.question(self, 'Сообщение',
                                     "Вы уверены, что хотите выйти?",
                                     QMessageBox.Yes | QMessageBox.No,
                                     QMessageBox.No)

        if reply == QMessageBox.Yes:  # Если Да
            try:
                shutil.rmtree('last')
            except Exception:
                pass
            event.accept()  # То выход
        else:
            event.ignore()  # Иначе игнорировать

    def lastImage(self):  # Функция добавления картинки в папку
        self.image.save('last/' + str(self.last) + '.png')  # Сохранение
        self.last += 1
        i = 0
        while len(os.listdir('last/')) > self.last:  # Если картинок больше
            os.remove('last/' + str(self.last + i) + '.png')
            i += 1

    def returnLast(self):  # Функция возвращения последней картинки
        if self.last - 1 >= 0:
            self.image.fill(Qt.white)  # Заливки пустым
            self.last -= 2
            painter = QPainter(self.image)

            # Возвращение последней картинки
            painter.drawImage(0, 0, QImage('last/' + str(self.last) + '.png'))
            self.last += 1
            self.update()  # Обновление картинки

    def returnUp(self):  # Функция возвращения передней картинки
        if self.last != len(os.listdir('last/')):
            self.image.fill(Qt.white)
            painter = QPainter(self.image)

            # Возвращение передней картинки
            painter.drawImage(0, 0, QImage('last/' + str(self.last) + '.png'))
            self.last += 1
            self.update()  # Обновление картинки
コード例 #57
0
 def newImage(self, width, height):
     image = QImage(width, height, QImage.Format_RGB32)
     image.fill(Qt.white)
     self.setImage(image)
コード例 #58
0
class QtMapViewer(QGraphicsView):
    """
    PyQt map viewer widget.
    """

    # Mouse button signals emit image scene (x, y) coordinates.
    leftMouseButtonPressed = pyqtSignal(float, float)
    mouseMoveLeftPressed = pyqtSignal(float, float)

    # custom signal
    viewUpdated = pyqtSignal()

    def __init__(self, preferred_size):
        QGraphicsView.__init__(self)

        self.setStyleSheet("color: rgb(49,51,53)")

        MIN_SIZE = 300
        MAX_SIZE = 500

        self.THUMB_SIZE = preferred_size

        if self.THUMB_SIZE > MAX_SIZE:
            self.THUMB_SIZE = MAX_SIZE

        if self.THUMB_SIZE < MIN_SIZE:
            self.THUMB_SIZE = MIN_SIZE

        self.BORDER_SIZE = 2

        # Image is displayed as a QPixmap in a QGraphicsScene attached to this QGraphicsView.
        self.scene = QGraphicsScene()
        self.setScene(self.scene)

        # Store a local handle to the scene's current image pixmap.
        self._pxmapitem = None

        # Image aspect ratio mode.
        self.aspectRatioMode = Qt.KeepAspectRatio

        # Set scrollbar
        self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)

        # Panning is enabled if and only if the image is greater than the viewport.
        self.panEnabled = False

        # zoom is always active
        self.zoom_factor = 1.0

        # transparency
        self.opacity = 1.0

        self.HIGHLIGHT_RECT_WIDTH = 10
        self.HIGHLIGHT_RECT_HEIGHT = 10
        self.HIGHLIGHT_COLOR = QColor(200, 200, 200)
        self.overlay_image = QImage(self.HIGHLIGHT_RECT_WIDTH,
                                    self.HIGHLIGHT_RECT_HEIGHT,
                                    QImage.Format_ARGB32)
        self.overlay_image.fill(self.HIGHLIGHT_COLOR)

        self.setFixedWidth(self.THUMB_SIZE)
        self.setFixedHeight(self.THUMB_SIZE)

        self.pixmap = QPixmap(self.THUMB_SIZE, self.THUMB_SIZE)
        self.imgwidth = 0
        self.imgheight = 0

    def image(self):
        """ Returns the scene's current image as a QImage.
        """
        if self.hasImage():
            return self._pxmapitem.pixmap().toImage()
        return None

    def hasImage(self):
        """ Returns whether or not the scene contains an image pixmap.
        """
        return self._pxmapitem is not None

    def setImage(self, image):
        """ Set the scene's current image (input image must be a QImage)
        """

        if image is None:

            qimg = QImage(self.THUMB_SIZE, self.THUMB_SIZE,
                          QImage.Format_ARGB32)
            qimg.fill(qRgba(40, 40, 40, 255))
            self.pixmap = QPixmap.fromImage(qimg)
            self.imgwidth = self.THUMB_SIZE
            self.imgheight = self.THUMB_SIZE

        elif type(image) is QImage:
            imageARGB32 = image.convertToFormat(QImage.Format_ARGB32)
            self.pixmap = QPixmap.fromImage(imageARGB32)
            self.imgwidth = image.width()
            self.imgheight = image.height()
        else:
            raise RuntimeError("Argument must be a QImage.")

        if self.hasImage():
            self._pxmapitem.setPixmap(self.pixmap)
        else:
            self._pxmapitem = self.scene.addPixmap(self.pixmap)

        # Set scene size to image size (!)
        self.setSceneRect(QRectF(self.pixmap.rect()))

        if self.imgwidth > self.imgheight:

            aspectratio = self.imgheight / self.imgwidth
            h = (int)(aspectratio * self.width())
            self.setFixedHeight(h)

        # calculate zoom factor
        pixels_of_border = 10
        zf1 = (self.geometry().width() - pixels_of_border) / self.imgwidth
        zf2 = (self.geometry().height() - pixels_of_border) / self.imgheight

        zf = min(zf1, zf2)
        if zf > 1.0:
            zf = 1.0

        self.zoom_factor = zf

        self.updateViewer()

    def setOpacity(self, opacity):
        self.opacity = opacity

    def loadImageFromFile(self, fileName=""):
        """ Load an image from file.
        """
        image = QImage(fileName)
        self.setImage(image)

    def drawOverlayImage(self, top, left, bottom, right):

        W = self.pixmap.width()
        H = self.pixmap.height()

        self.HIGHLIGHT_RECT_WIDTH = (right - left) * W
        self.HIGHLIGHT_RECT_HEIGHT = (bottom - top) * H
        self.HIGHLIGHT_RECT_POSX = left * W
        self.HIGHLIGHT_RECT_POSY = top * H
        self.overlay_image = QImage(self.HIGHLIGHT_RECT_WIDTH,
                                    self.HIGHLIGHT_RECT_HEIGHT,
                                    QImage.Format_ARGB32)
        self.overlay_image.fill(self.HIGHLIGHT_COLOR)

        if self.overlay_image.width() > 1:
            pxmap = self.pixmap.copy()
            p = QPainter()
            p.begin(pxmap)
            p.setOpacity(self.opacity)
            p.drawImage(self.HIGHLIGHT_RECT_POSX, self.HIGHLIGHT_RECT_POSY,
                        self.overlay_image)
            p.end()

            self._pxmapitem.setPixmap(pxmap)

    def updateViewer(self):
        """ Show current zoom (if showing entire image, apply current aspect ratio mode).
        """
        if not self.hasImage():
            return

        self.resetTransform()
        self.setTransformationAnchor(self.AnchorViewCenter)
        self.scale(self.zoom_factor, self.zoom_factor)

        #self.fitInView(self.sceneRect(), self.aspectRatioMode)

    def clipScenePos(self, scenePosition):
        posx = scenePosition.x()
        posy = scenePosition.y()
        if posx < 0:
            posx = 0
        if posy < 0:
            posy = 0
        if posx > self.imgwidth:
            posx = self.imgwidth
        if posy > self.imgheight:
            posy = self.imgheight

        return [posx, posy]

    def resizeEvent(self, event):
        """ Maintain current zoom on resize.
        """

        if self.imgwidth > 0 and self.imgheight > 0:

            pixels_of_border = 10
            zf1 = (self.geometry().width() - pixels_of_border) / self.imgwidth
            zf2 = (self.geometry().height() -
                   pixels_of_border) / self.imgheight
            zf = min(zf1, zf2)
            if zf > 1.0:
                zf = 1.0

            self.zoom_factor = zf

            self.updateViewer()

    def mousePressEvent(self, event):

        scenePos = self.mapToScene(event.pos())
        if event.button() == Qt.LeftButton:
            if self.panEnabled:
                self.setDragMode(QGraphicsView.ScrollHandDrag)

            clippedCoords = self.clipScenePos(scenePos)

            clippedCoords[0] = clippedCoords[0] / self.imgwidth
            clippedCoords[1] = clippedCoords[1] / self.imgheight

            self.leftMouseButtonPressed.emit(clippedCoords[0],
                                             clippedCoords[1])

    def mouseMoveEvent(self, event):

        QGraphicsView.mouseMoveEvent(self, event)

        scenePos = self.mapToScene(event.pos())

        if event.buttons() == Qt.LeftButton:

            clippedCoords = self.clipScenePos(scenePos)

            clippedCoords[0] = clippedCoords[0] / self.imgwidth
            clippedCoords[1] = clippedCoords[1] / self.imgheight

            self.mouseMoveLeftPressed.emit(clippedCoords[0], clippedCoords[1])

    def mouseDoubleClickEvent(self, event):

        QGraphicsView.mouseDoubleClickEvent(self, event)
コード例 #59
0
ファイル: PaintMain.py プロジェクト: pto8913/PyQt5-s-tools
class Canvas(QWidget):
    def __init__(self, parent=None):
        super(Canvas, self).__init__(parent)

        self.myPenWidth = 2
        self.myPenColor = Qt.black
        self.image = QImage()
        self.check = False
        self.back = deque(maxlen=10)
        self.next = deque(maxlen=10)

    def mousePressEvent(self, event):
        if event.button() == Qt.LeftButton:
            self.back.append(self.resizeImage(self.image, self.image.size()))
            self.lastPos = event.pos()
            self.check = True

    def mouseMoveEvent(self, event):
        if event.buttons() and Qt.LeftButton and self.check:
            self.drawLine(event.pos())

    def mouseReleaseEvent(self, event):
        if event.button() == Qt.LeftButton and self.check:
            self.drawLine(event.pos())
            self.check = False

    def drawLine(self, endPos):
        painter = QPainter(self.image)
        painter.setPen(
            QPen(self.myPenColor, self.myPenWidth, Qt.SolidLine, Qt.RoundCap,
                 Qt.RoundJoin))
        painter.drawLine(self.lastPos, endPos)
        self.update()
        self.lastPos = QPoint(endPos)

    def paintEvent(self, event):
        painter = QPainter(self)
        rect = event.rect()
        painter.drawImage(rect, self.image, rect)

    def resizeEvent(self, event):
        if self.image.width() < self.width() or self.image.height(
        ) < self.height():
            changeWidth = max(self.width(), self.image.width())
            changeHeight = max(self.height(), self.image.height())
            self.image = self.resizeImage(self.image,
                                          QSize(changeWidth, changeHeight))
            self.update()

    def resizeImage(self, image, newSize):
        changeImage = QImage(newSize, QImage.Format_RGB32)
        changeImage.fill(qRgb(255, 255, 255))
        painter = QPainter(changeImage)
        painter.drawImage(QPoint(0, 0), image)
        return changeImage

    def saveImage(self, filename):
        if self.image.save(filename):
            return True
        else:
            return False

    def openImage(self, filename):
        image = QImage()
        if not image.load(filename):
            return False

        self.image = image
        self.update()
        return True

    def penColor(self):
        return self.myPenColor

    def penWidth(self):
        return self.myPenWidth

    def setPenColor(self, newColor):
        self.myPenColor = newColor

    def setPenWidth(self, newWidth):
        self.myPenWidth = newWidth

    def resetImage(self):
        self.image.fill(qRgb(255, 255, 255))
        self.update()

    def backImage(self):
        if self.back:
            back_ = self.back.pop()
            self.next.append(back_)
            self.image = QImage(back_)
            self.update()

    def nextImage(self):
        if self.next:
            next_ = self.next.pop()
            self.back.append(next_)
            self.image = QImage(next_)
            self.update()
コード例 #60
0
class DrawWindow(MainDesign):
    contextToolbar = None

    def __init__(self, pix: QPixmap = None):
        super().__init__()

        # set image from desktop screen shot
        self.defaultPix = pix

        self.saveManager = SaveManager(self)

        # create image
        self.image = QImage(350, 380, QImage.Format_RGB32)
        self.image.fill(Qt.white)

        # settings of GUI
        self.setupUI()
        self.addHandlers()

        # current state of programm
        self.state: IState = LineState(self)

        # history of changes and objects
        self.history = History.getInstance()
        self.objects: List[IObject] = []

        self.setWindowIcon(QIcon('./Images/Logo.ico'))
        self.setWindowTitle('Joxi paint')

    def addHandlers(self):
        self.saveAction.triggered.connect(lambda *args: self.saveManager.save(self.image))
        self.saveBufferAction.triggered.connect(lambda *args: self.saveManager.saveBuffer(self.image))
        self.saveServerAction.triggered.connect(lambda *args: self.saveManager.saveServer(self.image))
        self.clearAction.triggered.connect(self.clear)
        self.unExecuteAction.triggered.connect(self.back)
        self.quitAction.triggered.connect(self.quit)

        self.LineAction.triggered.connect(lambda x: self.setState(LineState(self)))
        self.RectAction.triggered.connect(lambda x: self.setState(RectState(self)))
        self.CircleAction.triggered.connect(lambda x: self.setState(EllipseState(self)))
        self.ArrowAction.triggered.connect(lambda x: self.setState(ArrowState(self)))
        self.PenAction.triggered.connect(lambda x: self.setState(PenState(self)))
        self.PencilAction.triggered.connect(lambda x: self.setState(PencilState(self)))
        self.ImageAction.triggered.connect(lambda x: , self.addImage())
        self.TextAction.triggered.connect(lambda x: self.setState(TextState(self)))
        self.EditAction.triggered.connect(lambda x: self.setState(MoveState(self)))

        self.pasteAction.triggered.connect(self.paste)

    def clear(self):
        # clear window
        command = ClearCommand(self)
        command.execute()
        self.history.addCommand(command)
        self.repaint()

    def setToolbar(self, toolbar):
        if self.contextToolbar:
            #delete old toolbar
            self.contextToolbar.destroy()
            self.contextToolbar.hide()

        # set new toolbar
        self.contextToolbar = toolbar
        self.addToolBar(Qt.TopToolBarArea, self.contextToolbar)

    def back(self):
        self.history.removeCommand()
        self.repaint()

    def setState(self, state: IState):
        if not hasattr(state, 'editField'):
            self.setFocus(Qt.NoFocusReason)

        self.state = state

    def select(self, obj: IObject):
        # set edit mode
        self.setState(obj.getEditMode(self))

        # enable actions
        self.deleteAction.triggered.connect(lambda *args: self.delete(obj))
        self.deleteAction.setDisabled(False)

        self.copyAction.triggered.connect(lambda *args: self.copy(obj))
        self.copyAction.setDisabled(False)

    def unSelect(self):
        # set move mode
        self.setState(MoveState(self))
        self.repaint()

        # disable actions
        self.deleteAction.triggered.connect(lambda *args: None)
        self.deleteAction.setDisabled(True)

        self.copyAction.triggered.connect(lambda *args: None)
        self.copyAction.setDisabled(True)

    def delete(self, obj: IObject):
        if obj in self.objects:
            deleteCommand = DeleteCommand(self, obj)
            deleteCommand.execute()

            self.history.addCommand(deleteCommand)
            self.repaint()

    def copy(self, obj: IObject):
        cb: QClipboard = QApplication.clipboard()
        data: str = binascii.hexlify(dumps(obj)).decode('utf-8')

        cb.setText(data, mode=cb.Clipboard)

    def paste(self):
        try:
            data = binascii.unhexlify(QApplication.clipboard().text())
            obj = loads(data)

            command = PasteCommand(self, obj)
            command.execute()

            self.history.addCommand(command)
            self.repaint()
        except binascii.Error:
            pass

    def addImage(self):
        path, f = QFileDialog.getOpenFileName()

        if path:
            imageComm = CreateImage(self, path)
            imageComm.execute()

            self.history.addCommand(imageComm)

    def quit(self):
        app.exit()

    def paintEvent(self, *args, **kwargs):
        # repaint app
        self.image.fill(Qt.white)

        if self.defaultPix:
            qp = QPainter(self.image)
            qp.drawPixmap(self.defaultPix.rect(), self.defaultPix)

            del qp

        for obj in self.objects:
            obj.draw(self.image)

        self.state.paint(self.image)