Example #1
0
def testImage():
    width, height = 100, 100
    im = QImage(width, height, QImage.Format_ARGB32)

    for x in range(im.width()):
        for y in range(im.height()):
            if x % 2 == 0:
                im.setPixel(x, y, QColor('white').rgb())
            else:
                im.setPixel(x, y, QColor('black').rgb())
            # im.setPixel(x, y, QColor(255, x*2.56, y*2.56, 255).rgb())
    im.save('test.png')
class SetPixelFloat(UsesQApplication):
    '''Test case for calling setPixel with float as argument'''
    def setUp(self):
        #Acquire resources
        super(SetPixelFloat, self).setUp()
        self.color = qRgb(255, 0, 0)
        self.image = QImage(200, 200, QImage.Format_RGB32)

    def tearDown(self):
        #Release resources
        del self.color
        del self.image
        super(SetPixelFloat, self).tearDown()

    def testFloat(self):
        #QImage.setPixel(float, float, color) - Implicit conversion
        self.image.setPixel(3.14, 4.2, self.color)
        self.assertEqual(self.image.pixel(3.14, 4.2), self.color)
class SetPixelFloat(UsesQApplication):
    '''Test case for calling setPixel with float as argument'''

    def setUp(self):
        #Acquire resources
        super(SetPixelFloat, self).setUp()
        self.color = qRgb(255, 0, 0)
        self.image = QImage(200, 200, QImage.Format_RGB32)

    def tearDown(self):
        #Release resources
        del self.color
        del self.image
        super(SetPixelFloat, self).tearDown()

    def testFloat(self):
        #QImage.setPixel(float, float, color) - Implicit conversion
        self.image.setPixel(3.14, 4.2, self.color)
        self.assertEqual(self.image.pixel(3.14, 4.2), self.color)
Example #4
0
class SpriteView(QWidget):
    sprite_edited = Signal()

    def __init__(self, parent):
        super().__init__(parent)
        self._scene = QGraphicsScene(self)
        self._graphics_view = QGraphicsView(self._scene, self)

        layout = QVBoxLayout(self)
        layout.addWidget(self._graphics_view)

        self._pixmap_item = SpriteGraphicsItem(self)
        self._scene.addItem(self._pixmap_item)

        self._image = QImage(SPRITE_SIZE, SPRITE_SIZE, QImage.Format_ARGB32)
        self.sprite = [[0] * SPRITE_SIZE] * SPRITE_SIZE

        button_layout = QHBoxLayout(self)
        layout.addLayout(button_layout)
        self._color_button_group = QButtonGroup(self)
        for color in COLORS:
            button = QPushButton(self)
            button.setCheckable(True)
            button.setText(f"{color}")
            self._color_button_group.addButton(button, color)
            button_layout.addWidget(button)

        self._selected_color = 0
        self._color_button_group.button(self._selected_color).setChecked(True)
        QObject.connect(self._color_button_group, SIGNAL("buttonClicked(int)"),
                        self._color_selected)

        self._update_scaling()

    @property
    def sprite(self):
        return self._sprite

    @sprite.setter
    def sprite(self, sprite):
        if len(sprite) != SPRITE_SIZE:
            raise SpriteFormatException("Invalid Row Count")
        for row in sprite:
            if len(row) != SPRITE_SIZE:
                raise SpriteFormatException("Invalid Column Count")
            for value in row:
                if value not in COLORS:
                    raise SpriteFormatException(f"Invalid Color Value {value}")
        self._sprite = sprite
        self._update_image()

    def _update_image(self):
        for row in range(SPRITE_SIZE):
            for column in range(SPRITE_SIZE):
                self._image.setPixel(column, row,
                                     COLORS[self._sprite[row][column]])
        pixmap = QPixmap.fromImage(self._image)
        self._pixmap_item.setPixmap(pixmap)

    def resizeEvent(self, *args, **kwargs):
        super().resizeEvent(*args, **kwargs)
        self._update_scaling()

    def showEvent(self, *args, **kwargs):
        super().showEvent(*args, **kwargs)
        self._update_scaling()

    def _update_scaling(self):
        self._graphics_view.fitInView(self._pixmap_item, Qt.KeepAspectRatio)

    def _color_selected(self, id):
        self._selected_color = id

    def paint_pixel(self, x, y):
        if self._sprite[y][x] == self._selected_color:
            return
        self._sprite[y][x] = self._selected_color
        self._update_image()
        self.sprite_edited.emit()
Example #5
0
    def run(self):
        while True:
            self.mutex.lock()
            resultSize = self.resultSize
            scaleFactor = self.scaleFactor
            centerX = self.centerX
            centerY = self.centerY
            self.mutex.unlock()

            halfWidth = resultSize.width() // 2
            halfHeight = resultSize.height() // 2
            image = QImage(resultSize, QImage.Format_RGB32)

            NumPasses = 8
            curpass = 0

            while curpass < NumPasses:
                MaxIterations = (1 << (2 * curpass + 6)) + 32
                Limit = 4
                allBlack = True

                for y in range(-halfHeight, halfHeight):
                    if self.restart:
                        break
                    if self.abort:
                        return

                    ay = 1j * (centerY + (y * scaleFactor))

                    for x in range(-halfWidth, halfWidth):
                        c0 = centerX + (x * scaleFactor) + ay
                        c = c0
                        numIterations = 0

                        while numIterations < MaxIterations:
                            numIterations += 1
                            c = c * c + c0
                            if abs(c) >= Limit:
                                break
                            numIterations += 1
                            c = c * c + c0
                            if abs(c) >= Limit:
                                break
                            numIterations += 1
                            c = c * c + c0
                            if abs(c) >= Limit:
                                break
                            numIterations += 1
                            c = c * c + c0
                            if abs(c) >= Limit:
                                break

                        if numIterations < MaxIterations:
                            image.setPixel(
                                x + halfWidth, y + halfHeight,
                                self.colormap[numIterations %
                                              RenderThread.ColormapSize])
                            allBlack = False
                        else:
                            image.setPixel(x + halfWidth, y + halfHeight,
                                           qRgb(0, 0, 0))

                if allBlack and curpass == 0:
                    curpass = 4
                else:
                    if not self.restart:
                        self.renderedImage.emit(image, scaleFactor)
                    curpass += 1

            self.mutex.lock()
            if not self.restart:
                self.condition.wait(self.mutex)
            self.restart = False
            self.mutex.unlock()
Example #6
0
    def run(self):
        while True:
            self.mutex.lock()
            resultSize = self.resultSize
            scaleFactor = self.scaleFactor
            centerX = self.centerX
            centerY = self.centerY
            self.mutex.unlock()

            halfWidth = resultSize.width() // 2
            halfHeight = resultSize.height() // 2
            image = QImage(resultSize, QImage.Format_RGB32)

            NumPasses = 8
            curpass = 0

            while curpass < NumPasses:
                MaxIterations = (1 << (2 * curpass + 6)) + 32
                Limit = 4
                allBlack = True

                for y in range(-halfHeight, halfHeight):
                    if self.restart:
                        break
                    if self.abort:
                        return

                    ay = 1j * (centerY + (y * scaleFactor))

                    for x in range(-halfWidth, halfWidth):
                        c0 = centerX + (x * scaleFactor) + ay
                        c = c0
                        numIterations = 0

                        while numIterations < MaxIterations:
                            numIterations += 1
                            c = c*c + c0
                            if abs(c) >= Limit:
                                break
                            numIterations += 1
                            c = c*c + c0
                            if abs(c) >= Limit:
                                break
                            numIterations += 1
                            c = c*c + c0
                            if abs(c) >= Limit:
                                break
                            numIterations += 1
                            c = c*c + c0
                            if abs(c) >= Limit:
                                break

                        if numIterations < MaxIterations:
                            image.setPixel(x + halfWidth, y + halfHeight,
                                           self.colormap[numIterations % RenderThread.ColormapSize])
                            allBlack = False
                        else:
                            image.setPixel(x + halfWidth, y + halfHeight, qRgb(0, 0, 0))

                if allBlack and curpass == 0:
                    curpass = 4
                else:
                    if not self.restart:
                        self.renderedImage.emit(image, scaleFactor)
                    curpass += 1

            self.mutex.lock()
            if not self.restart:
                self.condition.wait(self.mutex)
            self.restart = False
            self.mutex.unlock()
Example #7
0
class Canvas(QWidget):
    content_changed = Signal()

    _background_color = QColor.fromRgb(0, 0, 0)
    _foreground_color = QColor.fromRgb(255, 255, 255)

    def __init__(self, parent, w, h, pen_width, scale):
        super().__init__(parent)
        self.w = w
        self.h = h
        self.scaled_w = scale * w
        self.scaled_h = scale * h
        self.scale = scale

        # Set size
        self.setFixedSize(self.scaled_w, self.scaled_h)

        # Create image
        self.small_image = QImage(self.w, self.h, QImage.Format_RGB32)
        self.small_image.fill(self._background_color)
        self.large_image = QImage(self.scaled_w, self.scaled_h,
                                  QImage.Format_RGB32)
        self.large_image.fill(self._background_color)

        # Create pen
        self.pen = QPen()
        self.pen.setColor(self._foreground_color)
        self.pen.setJoinStyle(Qt.RoundJoin)
        self.pen.setCapStyle(Qt.RoundCap)
        self.pen.setWidthF(scale * pen_width)

        # There is currently no path
        self.currentPath = None

        self.content_changed.connect(self.repaint)

    def _get_painter(self, paintee):
        painter = QPainter(paintee)
        painter.setPen(self.pen)
        painter.setRenderHint(QPainter.Antialiasing, True)
        return painter

    def _derive_small_image(self, large_image=None):
        if large_image is None:
            large_image = self.large_image
        # Downsample image
        self.small_image = large_image.scaled(self.w,
                                              self.h,
                                              mode=Qt.SmoothTransformation)
        self.content_changed.emit()

    def _current_path_updated(self, terminate_path=False):
        # Determine whether to draw on the large image directly or whether to make a temporary copy
        paintee = self.large_image if terminate_path else self.large_image.copy(
        )

        # Draw path on the large image of choice
        painter = self._get_painter(paintee)
        if self.currentPath.elementCount() != 1:
            painter.drawPath(self.currentPath)
        else:
            painter.drawPoint(self.currentPath.elementAt(0))
        painter.end()

        # Optionally terminate the path
        if terminate_path:
            self.currentPath = None

        # Downsample image
        self._derive_small_image(paintee)

    def _clear_image(self):
        self.large_image.fill(self._background_color)
        self._derive_small_image()

    def get_content(self):
        return np.asarray(self.small_image.constBits()).reshape(
            (self.h, self.w, -1))

    def set_content(self, image_rgb):
        for row in range(image_rgb.shape[0]):
            for col in range(image_rgb.shape[1]):
                self.small_image.setPixel(col, row, image_rgb[row, col])
        self.large_image = self.small_image.scaled(
            self.scaled_w, self.scaled_h, mode=Qt.SmoothTransformation)
        self._derive_small_image()
        self.content_changed.emit()

    def mousePressEvent(self, event):
        if event.button() == Qt.LeftButton:
            # Create new path
            self.currentPath = QPainterPath()
            self.currentPath.moveTo(event.pos())
            self._current_path_updated()

    def mouseMoveEvent(self, event):
        if (event.buttons() & Qt.LeftButton) and self.currentPath is not None:
            # Add point to current path
            self.currentPath.lineTo(event.pos())
            self._current_path_updated()

    def mouseReleaseEvent(self, event):
        if (event.button() == Qt.LeftButton) and self.currentPath is not None:
            # Add terminal point to current path
            self.currentPath.lineTo(event.pos())
            self._current_path_updated(terminate_path=True)
        elif event.button() == Qt.RightButton:
            self._clear_image()

    def paintEvent(self, event):
        paint_rect = event.rect()  # Only paint the surface that needs painting
        painter = self._get_painter(self)

        # Draw image
        painter.scale(self.scale, self.scale)
        painter.drawImage(paint_rect, self.small_image, paint_rect)

        painter.end()

        painter = self._get_painter(self)

        #if self.currentPath is not None:
        #    painter.drawPath(self.currentPath)

    @Slot()
    def repaint(self):
        super().repaint()
Example #8
0
class IconEditor(QWidget):
    def __init__(self):
        super(IconEditor, self).__init__()
        self.setAttribute(Qt.WA_StaticContents)
        self.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Minimum)
        self.curColor = Qt.black
        self.zoom = 8 * 1
        self.image = QImage(16, 16, QImage.Format_ARGB32)
        self.image.fill(qRgba(0, 0, 0, 0))

    def penColor(self):
        return self.curColor

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

    def zoomFactor(self):
        return self.zoom

    def setZoomFactor(self, newZoom):
        if newZoom < 1:
            newZoom = 1

        if newZoom != self.zoom:
            self.zoom = newZoom
            self.update()
            self.updateGeometry()

    def iconImage(self):
        return self.image

    def setIconImage(self, newImage):

        if newImage != self.image:
            print('updating image')
            self.image = newImage.convertToFormat(QImage.Format_ARGB32)
            self.update()
            self.updateGeometry()

    def sizeHint(self):
        size = self.zoom * self.image.size()
        if self.zoom >= 3:
            size += QSize(1, 1)
        return size

    def pixelRect(self, i, j):
        if self.zoom >= 3:
            return QRect(self.zoom * i + 1, self.zoom * j + 1, self.zoom - 1,
                         self.zoom - 1)
        else:
            return QRect(self.zoom * i, self.zoom * j, self.zoom, self.zoom)

    def mousePressEvent(self, event):
        if event.button() == Qt.LeftButton:
            self.setImagePixel(event.pos(), True)
            print('mouse left press')
        elif event.button() == Qt.RightButton:
            self.setImagePixel(event.pos(), False)
            print('mouse right press')

    def mouseMoveEvent(self, event):
        if event.buttons() & Qt.LeftButton:
            self.setImagePixel(event.pos(), True)
        elif event.buttons() & Qt.RightButton:
            self.setImagePixel(event.pos(), False)

    def setImagePixel(self, pos, opaque):
        i = pos.x() // self.zoom
        j = pos.y() // self.zoom
        print(f'setting pixel ({i}, {j})')
        if self.image.rect().contains(i, j):
            if opaque:
                penC = QColor('black')
                self.image.setPixel(i, j, penC.rgba())
                # self.image.setPixel(i, j, QColor(255, i*2.56, j*2.56, 255).rgb())
            else:
                print('#' * 10)
                self.image.setPixel(QPoint(i, j), qRgba(0, 0, 0, 0))
            print(f'Pixel Rect: {self.pixelRect(i,j)}')
            self.update(self.pixelRect(i, j))

    def paintEvent(self, event):
        painter = QPainter(self)
        if self.zoom >= 3:
            painter.setPen(self.palette().foreground().color())
            # painter.setPen(QPen('red'))
            for i in range(0, self.image.width()):
                painter.drawLine(self.zoom * i, 0, self.zoom * i,
                                 self.zoom * self.image.height())
            for j in range(0, self.image.height()):
                painter.drawLine(0, self.zoom * j,
                                 self.zoom * self.image.width(), self.zoom * j)

        for i in range(0, self.image.width()):
            for j in range(0, self.image.height()):
                rect = self.pixelRect(i, j)
                if event.region().intersected(rect):
                    color = QColor.fromRgba(self.image.pixel(i, j))
                    if color.alpha() < 255:
                        painter.fillRect(rect, Qt.white)
                    painter.fillRect(rect, color)

    penColorProperty = property(QColor, penColor, setPenColor)
    iconImageProperty = property(QImage, iconImage, setIconImage)
    zoomFactorProperty = property(int, zoomFactor, setZoomFactor)