Exemplo n.º 1
0
 def qimage_to_numpy(self, image: QImage) -> Image:
     image = image.convertToFormat(QImage.Format.Format_RGB32)
     width = image.width()
     height = image.height()
     ptr = image.constBits()
     arr = np.array(ptr).reshape((height, width, 4))[:, :, :3]
     return arr
Exemplo n.º 2
0
def to_qimage(array):
    """Convert NumPy array to QImage object

    Args:
        arr: A numpy array

    Returns:
        An QImage object.
    """
    if array is None:
        raise ValueError("The argument 'arr' can not be 'None'.")

    if len(array.shape) not in (2, 3):
        raise TypeError("Unsupported image format.")

    shape = array.shape[:2][::-1]
    stride = array.strides[0]
    cdim = 0 if len(array.shape) != 3 else array.shape[2]

    formats = {
        0: QImage.Format_Grayscale8,
        3: QImage.Format_RGB888,
        4: QImage.Format_RGBA8888
    }

    if cdim not in formats:
        raise TypeError("Unsupported image format.")

    qimage = QImage(array.data, *shape, stride, formats[cdim])
    return qimage.convertToFormat(QImage.Format_RGBA8888)
Exemplo n.º 3
0
    def readImage(self, filename, sbimage):
        image = QImage()
        if (image.load(filename.getString())):
            # Keep in 8-bits mode if that was what we read
            if (image.depth() == 8 and image.isGrayscale()):
                c = 1
            else:
                # FIXME: consider if we should detect allGrayscale() and alpha (c = 2)
                c = 3
                if image.hasAlphaChannel():
                    c = 4
                    image.convertToFormat(QImage.Format_ARGB32)
                else:
                    image.convertToFormat(QImage.Format_RGB32)

                # FIXME 20080508 jkg: implement when pivy is ready
                #sbimage.setValue(SbVec2s(image.width(), image.height()), c, None)

                return True
        return False
Exemplo n.º 4
0
    def QImageToCV(image: QImage) -> ndarray:
        if image.format() != QImage.Format_RGB888:
            image = image.convertToFormat(QImage.Format_RGB888)

        width = image.width()
        height = image.height()

        ptr = image.bits()
        arr = array(ptr).reshape(height, width, 3)

        return arr
Exemplo n.º 5
0
    def __init__(self,
                 name,
                 baseSize,
                 contourPath,
                 presetFilename=None,
                 image=None):
        """

        @param name:
        @type name: str
        @param baseSize:
        @type baseSize: int
        @param contourPath: base shape of the brush family
        @type contourPath: QPainterPath
        @param presetFilename: preset file
        @type presetFilename: str
        """
        self.name = name
        self.baseSize = baseSize
        # init the brush pixmap
        self.basePixmap = QPixmap(self.baseSize, self.baseSize)
        # to get an alpha channel, we must fill the pixmap a first time with an opacity < 255
        self.basePixmap.fill(QColor(0, 0, 0, 0))
        if self.name == 'eraser':
            self.basePixmap.fill(QColor(0, 0, 0, 255))
        self.contourPath = contourPath
        # init brush cursor
        self.baseCursor = QPixmap(self.baseSize, self.baseSize)
        self.baseCursor.fill(QColor(0, 0, 0, 0))
        qp = QPainter(self.baseCursor)
        pen = qp.pen()
        pen.setWidth(self.baseSize / 20)
        qp.setPen(pen)  # needed!!
        qp.drawPath(contourPath)
        qp.end()
        self.__pxmp = None
        self.bOpacity = 1.0
        self.bFlow = 1.0
        self.bHardness = 1.0
        self.preset = None
        if presetFilename is not None:
            img = QImage(presetFilename)
        elif image is not None:
            img = image
        else:
            return
        img = img.convertToFormat(QImage.Format_ARGB32)
        buf = QImageBuffer(img)
        b = np.sum(buf[..., :3], axis=-1, dtype=np.float)
        b /= 3
        buf[..., 3] = b
        self.preset = QPixmap.fromImage(img)
Exemplo n.º 6
0
def qimg_to_rgb_arr(qimg: QImage) -> RGBArrayF:
    """Convert a :class:`QtGui.QImage` to an :data:`RGBArrayF`
    """
    fmt = QImage.Format_RGB32
    if qimg.format() != fmt:
        qimg = qimg.convertToFormat(fmt)

    width, height = qimg.width(), qimg.height()
    num_pixels = width * height

    bfr = qimg.constBits()
    int_arr = np.frombuffer(bfr, dtype=np.uint8, count=num_pixels * 4)

    bgra_arr = int_arr.reshape((height, width, 4)) / 255

    # Format_RGB32 stored as 0xffRRGGBB
    # so take only the first 3 items but in reverse
    rgb_arr = bgra_arr[..., 2::-1]

    return rgb_arr
Exemplo n.º 7
0
class Scribble(QWidget):
    def __init__(self, parent=None, scribbleImagePath=""):
        QWidget.__init__(self, parent)
        self.show()
        self.raise_()

        # Available space to display on
        self.imageAreaWidth = 0
        self.imageAreaHeight = 0

        # Real number of pixels (unscaled)
        self.scribbleWidth = 1
        self.scribbleHeight = 1

        # Scaling factor between the real image size and the size after scaling to fit the imageArea
        self.scaleFactor = 1.0

        self.scribbling = False  # if scribbling at this time and moment
        self.penMoved = False  # if the pen already moved while scribbling
        self.myPenWidth = 1
        self.myPenColor = QColor(0, 0, 255, 255)
        self.lastPoint = None

        self.scribbleImagePath = scribbleImagePath
        self.image = None

    def refreshScribble(self, width, height):
        self.imageAreaWidth = width
        self.imageAreaHeight = height
        self.setGeometry(0, 0, self.imageAreaWidth, self.imageAreaHeight)

    def setColor(self, color):  # QColor object
        self.myPenColor = color

    def setPenSize(self, size):
        self.myPenWidth = size

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

    def mouseMoveEvent(self, event):
        if self.scribbling:
            self.drawLineTo(event.pos())
            self.penMoved = True

    def mouseReleaseEvent(self, event):
        if event.button() == Qt.LeftButton and self.scribbling:
            self.drawLineTo(event.pos())
            if self.myPenColor == QColor(255, 0, 0, 255):
                self.drawCircle(event.pos())
            self.scribbling = False
            self.penMoved = False

    def setupScribble(self, width, height):
        self.scribbleWidth = width
        self.scribbleHeight = height
        if self.scribbleImagePath == "":
            self.image = QImage(self.scribbleWidth, self.scribbleHeight,
                                QImage.Format_ARGB32)
            # print(self.image.depth())  # prints 32
            self.image.fill(qRgba(0, 0, 0, 0))
        else:
            self.image = QImage(self.scribbleImagePath)
            self.image = self.image.convertToFormat(QImage.Format_ARGB32)
        self.update()

    def drawCircle(self, point):
        painter = QPainter(self.image)
        painter.setCompositionMode(QPainter.CompositionMode_Source)
        painter.setRenderHint(QPainter.Antialiasing)

        brush = QBrush(QColor(0, 0, 255, 255), Qt.SolidPattern)
        pen = QPen(brush, 0.2 * self.myPenWidth / self.scaleFactor,
                   Qt.SolidLine, Qt.RoundCap, Qt.RoundJoin)
        painter.setPen(pen)
        radius = 1.5 * self.myPenWidth / self.scaleFactor
        rectangle = QRectF((point.x() / self.scaleFactor) - (radius / 2),
                           (point.y() / self.scaleFactor) - (radius / 2),
                           radius, radius)
        painter.drawEllipse(rectangle)

        self.update()

    def drawLineTo(self, endPoint):
        if not self.penMoved:
            endPoint.setX(
                endPoint.x() + 1
            )  # ensures a dot is being drawn if there was just a click and no mouse move
        painter = QPainter(self.image)
        painter.setCompositionMode(QPainter.CompositionMode_Source)
        painter.setRenderHint(QPainter.Antialiasing)

        brush = QBrush(self.myPenColor, Qt.SolidPattern)
        pen = QPen(brush, self.myPenWidth / self.scaleFactor, Qt.SolidLine,
                   Qt.RoundCap, Qt.RoundJoin)
        # pen = QPen(self.myPenColor, self.myPenWidth, Qt.SolidLine, Qt.RoundCap, Qt.RoundJoin)
        painter.setPen(pen)
        painter.drawLine(self.lastPoint / self.scaleFactor,
                         endPoint / self.scaleFactor)

        self.update()

        self.lastPoint = endPoint

    def paintEvent(self, event):
        painter = QPainter(self)
        dirtyRect = event.rect()
        scaledImage = self.image.scaled(self.imageAreaWidth,
                                        self.imageAreaHeight,
                                        Qt.KeepAspectRatio,
                                        Qt.FastTransformation)
        self.scaleFactor = float(scaledImage.width()) / float(
            self.scribbleWidth)
        painter.drawImage(dirtyRect, scaledImage, dirtyRect)
Exemplo n.º 8
0
    def redoIt(self):
        maya_cmds.undoInfo(stateWithoutFlush=False)
        try:
            image = QImage(self.image)
            if image.format() != QImage.Format_RGBA8888:
                image = image.convertToFormat(QImage.Format_RGBA8888)

            imageBits = image.bits()
            imageWidth = image.width()
            imageHeight = image.height()
            imageWidthM = imageWidth - 1
            imageHeightM = imageHeight - 1

            mFnMesh = OpenMaya.MFnMesh(
                OpenMaya.MGlobal.getSelectionListByName(
                    self.shape).getDagPath(0))
            mPoints = mFnMesh.getPoints(OpenMaya.MSpace.kWorld)
            self.mPoints = OpenMaya.MPointArray(mPoints)

            tmp1, uvIdsFace = mFnMesh.getAssignedUVs(self.uvName)
            tmp2, vertexIdsFace = mFnMesh.getVertices()
            u, v = mFnMesh.getUVs(self.uvName)
            uvs = [0] * len(u)
            for i in xrange(len(uvIdsFace)):
                uvIdFace = uvIdsFace[i]
                uvs[vertexIdsFace[i]] = [u[uvIdFace], v[uvIdFace]]

            if self.matrixIs.X:
                diffX = self.matrixMax.X - self.matrixMin.X
                for i in xrange(len(mPoints)):
                    u = int((uvs[i][0] % 1.0) * imageWidthM)
                    v = int((uvs[i][1] % 1.0) * imageHeightM)
                    mPoints[i].x += ((ord(imageBits[
                        (u + v * imageWidth) * 4 + self.matrixCha.X]) * diffX)
                                     / 255.0) + self.matrixMin.X
            if self.matrixIs.Y:
                diffY = self.matrixMax.Y - self.matrixMin.Y
                for i in xrange(len(mPoints)):
                    u = int((uvs[i][0] % 1.0) * imageWidthM)
                    v = int((uvs[i][1] % 1.0) * imageHeightM)
                    mPoints[i].y += ((ord(imageBits[
                        (u + v * imageWidth) * 4 + self.matrixCha.Y]) * diffY)
                                     / 255.0) + self.matrixMin.Y
            if self.matrixIs.Z:
                diffZ = self.matrixMax.Z - self.matrixMin.Z
                for i in xrange(len(mPoints)):
                    u = int((uvs[i][0] % 1.0) * imageWidthM)
                    v = int((uvs[i][1] % 1.0) * imageHeightM)
                    mPoints[i].z += ((ord(imageBits[
                        (u + v * imageWidth) * 4 + self.matrixCha.Z]) * diffZ)
                                     / 255.0) + self.matrixMin.Z
            if self.matrixIs.N:
                diffN = self.matrixMax.N - self.matrixMin.N
                mNormals = mFnMesh.getVertexNormals(True,
                                                    OpenMaya.MSpace.kWorld)
                for i in xrange(len(mPoints)):
                    u = int((uvs[i][0] % 1.0) * imageWidthM)
                    v = int((uvs[i][1] % 1.0) * imageHeightM)
                    mPoints[i].x += mNormals[i].x * ((
                        (ord(imageBits[
                            (u + v * imageWidth) * 4 + self.matrixCha.N]) *
                         diffN) / 255.0) + self.matrixMin.N)
                    mPoints[i].y += mNormals[i].y * ((
                        (ord(imageBits[
                            (u + v * imageWidth) * 4 + self.matrixCha.N]) *
                         diffN) / 255.0) + self.matrixMin.N)
                    mPoints[i].z += mNormals[i].z * ((
                        (ord(imageBits[
                            (u + v * imageWidth) * 4 + self.matrixCha.N]) *
                         diffN) / 255.0) + self.matrixMin.N)
            mFnMesh.setPoints(mPoints, OpenMaya.MSpace.kWorld)
            mFnMesh.updateSurface()
        except Exception as e:
            print >> stderr, str(e)
        maya_cmds.undoInfo(stateWithoutFlush=True)
Exemplo n.º 9
0
class Map(QQuickPaintedItem):

    def __init__(self, parent = None):
        super(Map, self).__init__(parent)

        self.viewport = None

        self.setAcceptedMouseButtons(Qt.AllButtons)
        self.generate()

    clicked = Signal(QPoint)

    @Slot()
    def generate(self):
        # QImage does not work with bits, only with bytes
        self.image = QImage(300, 300, QImage.Format_Grayscale8)
        self.oldImage = None
        self.generateMap()
        self._percentage = 0

        self._pressClick = QPoint()

    def pixel(self, x: int, y: int, image = None) -> bool:
        if not image:
            image = self.image

        # This solves:
        # QImage::pixelIndex: Not applicable for 8-bpp images (no palette)
        return image.bits()[int(x) + int(y) * image.bytesPerLine()] & 0xff

    def setPixel(self, x: int, y: int, value: int, image = None):
        if not image:
            image = self.image

        # This solves:
        # QImage::pixelIndex: Not applicable for 8-bpp images (no palette)
        image.bits()[int(x) + int(y) * image.bytesPerLine()] = value

    def createRandomMap(self):
        for i in range(self.image.byteCount()):
            if random.random() < 0.35:
                self.image.bits()[i] = 255
            else:
                self.image.bits()[i] = 0

    def countNeighbors(self, x: int, y: int, image = None, n = 1) -> int:
        if not image:
            image = self.image

        count = 0
        for i in range(-n , n + 1):
            for u in range(-n , n + 1):
                if not i and not u:
                    continue

                #TODO: pixel function is poor
                # need to use bits()
                if x + i < 0 or y + u < 0 or \
                    x + i >= image.width() or y + u >= image.height():
                    count += 1
                    continue

                if not self.pixel(x + i, y + u, image):
                    count += 1

        return count

    @Slot(int)
    def doStep(self, n = 1):
        if self.image.format() != QImage.Format_Grayscale8:
            print("Wrong file format, generate map again.")
            return

        deathLimit = 14
        self._percentage = 0
        for _ in range(n):
            _image = self.image.copy()
            for x in range(self.image.width()):
                self._percentage += 1.0/(self.image.width()*n)
                if x%10 == 0:
                    # Update percentage
                    self.percentageChanged.emit()
                    # processEvent is necessary
                    QEventLoop().processEvents()
                    # Update map
                    self.update()
                for y in range(self.image.height()):
                    if self.countNeighbors(x, y, _image, 2) > deathLimit or \
                        x == 0 or y == 0 or x == _image.width() - 1 or y == _image.height() - 1:
                        self.setPixel(x, y, 0)
                    else:
                        self.setPixel(x, y, 255)
        # Update percentage
        self.update()
        self.oldImage = self.image.copy()
        self.percentageChanged.emit()
        QEventLoop().processEvents()

    def generateMap(self):
        self.createRandomMap()
        self.update()
        self.oldImage = self.image.copy()

    def paint(self, painter):
        painter.drawImage(QRect(0, 0, self.width(), self.height()), self.image)
        self.viewport = painter.viewport()

    def keyPressEvent(self, event):
        if event.key() == Qt.Key_Space:
            print('Update..')
            start = time.time()
            self.doStep()
            print('Took: %.2fs' % (time.time() - start))
        event.accept()

    def mousePressEvent(self, event):
        a, b = event.pos().x()*self.image.width()/self.width(), event.pos().y()*self.image.height()/self.height()
        self.clicked.emit(QPoint(a, b))

    def mouseMoveEvent(self, event):
        a, b = event.pos().x()*self.image.width()/self.width(), event.pos().y()*self.image.height()/self.height()
        self.clicked.emit(QPoint(a, b))

    def percentage(self):
        return self._percentage

    percentageChanged = Signal()
    percentage = Property(float, percentage, notify=percentageChanged)

    @Slot()
    def addVehicle(self):
        self.image = self.image.convertToFormat(QImage.Format_RGBA8888)
        painter = QPainter(self.image)
        painter.drawImage(QRect(50, 50, 13, 15), QImage("imgs/turtle.png"))
        painter.end()
        self.update()

    @Slot(str)
    def saveMap(self, path: str):
        # Check image encoder
        if(self.image.format() != QImage.Format_Grayscale8):
            print('Wrong map pixel format, create map without vehicle added.')
            return
        ok = self.image.save(path)
        if(not ok):
            print('It was not possible to save Map in:', path)

    @Slot(str)
    def loadMap(self, path: str):
        # Check image encoder
        image = QImage(path)
        if(image.format() != QImage.Format_Grayscale8):
            print('Wrong map pixel format, map should be Grayscale8.')
            return
        self.image = image
        self.oldImage = self.image.copy()
        self.update()