コード例 #1
0
def qimage2numpy(qimage: QImage):
    """Convert QImage to numpy.ndarray.  The dtype defaults to uint8
    for QImage.Format_Indexed8 or `bgra_dtype` (i.e. a record array)
    for 32bit color images.  You can pass a different dtype to use, or
    'array' to get a 3D uint8 array for color images."""
    result_shape = (qimage.height(), qimage.width())
    temp_shape = (qimage.height(), int(qimage.bytesPerLine() * 8 / qimage.depth()))
    if qimage.format() in (QImage.Format_ARGB32_Premultiplied,
                           QImage.Format_ARGB32,
                           QImage.Format_RGB32):
        dtype = np.uint8
        result_shape += (4,)
        temp_shape += (4,)
    elif qimage.format() == QtGui.QImage.Format_Indexed8:
        dtype = np.uint8
    else:
        raise ValueError("qimage2numpy only supports 32bit and 8bit images")
        # FIXME: raise error if alignment does not match
    buf = qimage.bits().asstring(qimage.byteCount())
    result = np.frombuffer(buf, dtype).reshape(temp_shape)
    if result_shape != temp_shape:
        result = result[:, :result_shape[1]]
    if qimage.format() == QImage.Format_RGB32 and dtype == np.uint8:
        result = result[..., :3]
    return result
コード例 #2
0
class ImageWidget(QLabel):
    updateRow = pyqtSignal(int, bytearray)
    imageComplete = pyqtSignal()

    def _updateRow(self, i, line):
        print("updateRow {}".format(i))
        lineSize = self.image.width() * 4
        offset = lineSize * i
        self.imagePtr[offset:offset + lineSize] = line
        self._updatePixmap()

    def _updatePixmap(self):
        self.setPixmap(QPixmap.fromImage(self.image))

    def resizeEvent(self, event):
        self._updatePixmap()

    def saveImage(self):
        timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
        self.image.save("scan_{}.png".format(timestamp))

    def __init__(self, imageSize, parent=None):
        super(ImageWidget, self).__init__()
        self.setScaledContents(True)
        self.image = QImage(*imageSize, QImage.Format_ARGB32)
        self.image.fill(0x12345678)
        self.imagePtr = self.image.bits()
        self.imagePtr.setsize(self.image.byteCount())
        self.updateRow.connect(self._updateRow)
        self.imageComplete.connect(self.saveImage)
        self.setMinimumSize(100, 100)
        self.setScaledContents(True)
        self.setCursor(Qt.BlankCursor)
コード例 #3
0
ファイル: image_filter.py プロジェクト: SuicideSin/dirtool
def white_outline(image: QImage, sigma=6, repeat=6) -> QImage:
    if image.format() != QImage.Format_ARGB32:
        image = image.convertToFormat(QImage.Format_ARGB32)

    bits = image.bits()
    bits.setsize(image.byteCount())

    shape = (image.width() * image.height())
    strides = (4,)

    alpha = numpy.ndarray(shape=shape, dtype=numpy.uint8,
                          buffer=bits, strides=strides, offset=3)
    color = numpy.ndarray(shape=shape, dtype=numpy.uint8)
    color.fill(255)

    alpha = alpha.reshape((image.width(), image.height()))
    alpha = alpha.astype(numpy.float)
    alpha = gaussian_filter(alpha, sigma=sigma)
    alpha *= repeat
    numpy.clip(alpha, 0, 255, out=alpha)
    alpha = alpha.astype(numpy.uint8)
    alpha = alpha.reshape(shape)

    arr = numpy.dstack((color, color, color, alpha))

    return QImage(arr, image.width(), image.height(), QImage.Format_ARGB32)
コード例 #4
0
def create_tile_mode7_indexed(data):
    # Each byte is a pixel. 8bit palette.
    tile = array('B', range(64))
    tile = data[:64]
    img = QImage(8, 8, QImage.Format_Indexed8)
    imgbits = img.bits()
    imgbits.setsize(img.byteCount())
    imgbits[:64] = tile
    return img
def pixmap2cv(pixmap):
    qImg = QImage(pixmap)
    qImg = qImg.convertToFormat(4)

    width = qImg.width()
    height = qImg.height()
    ptr = qImg.bits()
    ptr.setsize(qImg.byteCount())
    arr = np.array(ptr).reshape(height, width, 4)  #  Copies the data
    return arr
コード例 #6
0
    def set_colors(data: bin,
                   fg: QColor,
                   bg: QColor,
                   trans: QColor,
                   swap_fg_bg=False) -> bin:  # pylint: disable=too-many-locals
        """
        Burns foreground and background colors into a raster image, and returns
        the results as a PNG binary
        """
        image = QImage()
        image.loadFromData(data)
        if image.isNull():
            raise UnreadablePictureException(
                'Could not read embedded picture data')

        image = image.convertToFormat(QImage.Format_ARGB32)
        ucharptr = image.bits()
        ucharptr.setsize(image.byteCount() * image.height())

        fg_rgba = qRgba(fg.red(), fg.green(), fg.blue(),
                        fg.alpha()) if fg and fg.isValid() else None
        bg_rgba = qRgba(bg.red(), bg.green(), bg.blue(),
                        bg.alpha()) if bg and bg.isValid() else None

        COLOR_TOLERANCE = 40

        fg_comp = 0
        bg_comp = 255

        for y in range(image.height()):
            start = y * image.width() * 4
            for x in range(image.width()):
                x_start = x * 4 + start
                rgba = struct.unpack('I', ucharptr[x_start:x_start + 4])[0]
                if trans and abs(qRed(rgba) - trans.red(
                )) < COLOR_TOLERANCE and abs(qGreen(rgba) - trans.green(
                )) < COLOR_TOLERANCE and abs(qBlue(rgba) -
                                             trans.blue()) < COLOR_TOLERANCE:
                    ucharptr[x_start:x_start + 4] = struct.pack(
                        'I', qRgba(0, 0, 0, 0))
                elif fg_rgba is not None and abs(
                        qRed(rgba) - fg_comp) < COLOR_TOLERANCE and abs(
                            qGreen(rgba) - fg_comp) < COLOR_TOLERANCE and abs(
                                qBlue(rgba) - fg_comp) < COLOR_TOLERANCE:
                    ucharptr[x_start:x_start + 4] = struct.pack('I', fg_rgba)
                elif bg_rgba is not None and abs(
                        qRed(rgba) - bg_comp) < COLOR_TOLERANCE and abs(
                            qGreen(rgba) - bg_comp) < COLOR_TOLERANCE and abs(
                                qBlue(rgba) - bg_comp) < COLOR_TOLERANCE:
                    ucharptr[x_start:x_start + 4] = struct.pack('I', bg_rgba)

        # convert to PNG
        png_data = QBuffer()
        image.save(png_data, "png")
        return png_data.data()
コード例 #7
0
def create_tritile(data):
    img = QImage(16, 12, QImage.Format_Indexed8)
    imgbits = img.bits()
    imgbits.setsize(img.byteCount())
    img.setColorTable(const.dialogue_palette)
    tile = array('B', range(192))
    for p, row, b in [(p, j, b) for p in range(2) for j in range(12)
                      for b in reversed(range(8))]:
        tile[(7 - b) + (row * 16) + (p * 8)] = (data[row + (p * 12)] >> b & 1)
    imgbits[:192] = tile
    return QPixmap.fromImage(img)
コード例 #8
0
def QImageTocvmat(img: QImage):
    img = img.convertToFormat(QImage.Format_RGBX8888)
    width = img.width()
    height = img.height()
    ptr = img.bits()
    ptr.setsize(height * width * 4)

    # copy image data from ptr to avoid changes while runtime
    ret = np.fromstring(ptr, np.uint8).reshape((height, width, 4))
    ret.flags.writeable = False
    return ret
コード例 #9
0
 def qimage_to_pil(self, qimage: QImage) -> Image:
     """ Convert QImage (in ARGB32 format) to PIL.Image (in RGBA mode). """
     # In our case QImage uses 0xAARRGGBB format stored in host endian
     # order, we must convert it to [0xRR, 0xGG, 0xBB, 0xAA] sequences
     # used by Pillow.
     buf = qimage.bits().asstring(qimage.byteCount())
     if sys.byteorder != "little":
         buf = swap_byte_order_i32(buf)
     return Image.frombytes(
         self.pillow_image_format,
         qsize_to_tuple(qimage.size()),
         buf, 'raw', self.pillow_decoder_format)
コード例 #10
0
ファイル: sceneView.py プロジェクト: RadWex/LaserEngraver
    def load_graphics(self, path):
        graphics = []
        list_of_files = [f for f in listdir(path) if isfile(join(path, f))]

        for i in list_of_files:
            im = QImage(path + '/' + i)
            im = im.convertToFormat(QImage.Format_RGBA8888)
            ptr = im.bits()
            ptr.setsize(im.byteCount())
            graphics.append(ptr.asstring())

        return graphics
コード例 #11
0
    def getImageBoundaries(image: QImage):
        # Look at the resulting image to get a good crop.
        # Get the pixels as byte array
        pixel_array = image.bits().asarray(image.byteCount())
        width, height = image.width(), image.height()
        # Convert to numpy array, assume it's 32 bit (it should always be)
        pixels = numpy.frombuffer(pixel_array, dtype=numpy.uint8).reshape([height, width, 4])
        # Find indices of non zero pixels
        nonzero_pixels = numpy.nonzero(pixels)
        min_y, min_x, min_a_ = numpy.amin(nonzero_pixels, axis=1)
        max_y, max_x, max_a_ = numpy.amax(nonzero_pixels, axis=1)

        return min_x, max_x, min_y, max_y
コード例 #12
0
ファイル: Snapshot.py プロジェクト: Ultimaker/Cura
    def getImageBoundaries(image: QImage):
        # Look at the resulting image to get a good crop.
        # Get the pixels as byte array
        pixel_array = image.bits().asarray(image.byteCount())
        width, height = image.width(), image.height()
        # Convert to numpy array, assume it's 32 bit (it should always be)
        pixels = numpy.frombuffer(pixel_array, dtype=numpy.uint8).reshape([height, width, 4])
        # Find indices of non zero pixels
        nonzero_pixels = numpy.nonzero(pixels)
        min_y, min_x, min_a_ = numpy.amin(nonzero_pixels, axis=1)
        max_y, max_x, max_a_ = numpy.amax(nonzero_pixels, axis=1)

        return min_x, max_x, min_y, max_y
コード例 #13
0
    def load_image(self, path):
        qim = QImage(path).mirrored()
        qim = qim.convertToFormat(QImage.Format_RGBA8888_Premultiplied)
        ptr = qim.bits()
        ptr.setsize(qim.byteCount())
        image_data = np.asarray(ptr).reshape(qim.width(), qim.height(), 4)

        im = glGenTextures(1)
        glBindTexture(GL_TEXTURE_2D, im)
        glTexImage2D( GL_TEXTURE_2D, 0, 4, qim.width(), qim.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, image_data)
        glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
        glDisable(GL_ALPHA_TEST)
        self.images[path] = im
        self.image_values[path] = QRect(0, 0, qim.width(), qim.height())
        self.imageOrder.append(path)
コード例 #14
0
ファイル: pictures.py プロジェクト: Dan-Eli/test_action
    def colorize_picture(picture, color):
        """
        Applies a color overlay to a picture, emulating the ArcMap
        results
        """
        if issubclass(picture.__class__, StdPicture):
            picture = picture.picture

        image = QImage()
        image.loadFromData(picture.content)
        if image.isNull():
            raise UnreadablePictureException('Could not read embedded picture data')

        image = image.convertToFormat(QImage.Format_ARGB32)
        ucharptr = image.bits()
        ucharptr.setsize(image.byteCount() * image.height())

        # assume top left pixel is transparent?
        c = image.pixelColor(0, 0)
        trans_rgba = qRgba(c.red(), c.green(), c.blue(), c.alpha())
        actual_trans_rgba = qRgba(c.red(), c.green(), c.blue(), 0)

        for y in range(image.height()):
            start = y * image.width() * 4
            for x in range(image.width()):
                x_start = x * 4 + start
                rgba = struct.unpack('I', ucharptr[x_start:x_start + 4])[0]

                if rgba == trans_rgba:
                    ucharptr[x_start:x_start + 4] = struct.pack('I', actual_trans_rgba)

        if color is None or color.is_null:
            return image

        fg_color = ColorConverter.color_to_qcolor(color)
        if not fg_color.isValid():
            return image

        alpha = QImage(image)
        image.detach()
        p = QPainter(image)
        p.setCompositionMode(QPainter.CompositionMode_SourceIn)
        p.setBrush(fg_color)
        p.drawRect(image.rect())
        p.setCompositionMode(QPainter.CompositionMode_Multiply)
        p.drawImage(0, 0, alpha)
        p.end()
        return image
コード例 #15
0
    def get_snapshot(self, bw=None, return_as_array=None):
        qimage = QImage(self.image)
        if return_as_array:
            qimage = qimage.convertToFormat(4)
            ptr = qimage.bits()
            ptr.setsize(qimage.byteCount())

            image_array = np.array(ptr).reshape(qimage.height(), qimage.width(), 4)
            if bw:
                return np.dot(image_array[..., :3], [0.299, 0.587, 0.144])
            else:
                return image_array
        else:
            if bw:
                return qimage.convertToFormat(QImage.Format_Mono)
            else:
                return qimage
コード例 #16
0
    def get_snapshot(self, bw=None, return_as_array=None):
        qimage = QImage(self.image)
        if return_as_array:
            qimage = qimage.convertToFormat(4)
            ptr = qimage.bits()
            ptr.setsize(qimage.byteCount())

            image_array = np.array(ptr).reshape(qimage.height(), qimage.width(), 4)
            if bw:
                return np.dot(image_array[..., :3], [0.299, 0.587, 0.144])
            else:
                return image_array
        else:
            if bw:
                return qimage.convertToFormat(QImage.Format_Mono)
            else:
                return qimage
コード例 #17
0
def create_tile_old(data, palette):
    '''
    Creates a QPixmap of a SNES tile. DO NOT USE OUTSIDE OF QApplication CONTEXT
    '''
    planes = len(data) // 8
    tile = array('B', range(64))
    img = QImage(8, 8, QImage.Format_Indexed8)
    imgbits = img.bits()
    imgbits.setsize(img.byteCount())
    if planes == 0:
        raise ValueError("Empty bytes passed")
    if planes == 1:
        img.setColorTable([0x00000080, 0xFFFFFFFF])
        t_ptr = 0
        for j, x in [(j, x) for j in range(8) for x in reversed(range(8))]:
            tile[t_ptr] = (data[j] >> x & 1)
            t_ptr += 1
    else:
        img.setColorTable(palette)
        t_ptr = 0
        for j, x in [(j, x) for j in range(0, 16, 2)
                     for x in reversed(range(8))]:
            tile[t_ptr] = (data[j] >> x & 1) | ((data[j + 1] >> x & 1) << 1)
            t_ptr += 1
        t_ptr = 0
        if planes == 3:
            for j, x in [(j, x) for j in range(16, 24, 1)
                         for x in reversed(range(8))]:
                tile[t_ptr] |= ((data[j] >> x & 1) << 2)
                t_ptr += 1
        elif planes >= 4:
            for j, x in [(j, x) for j in range(16, 32, 2)
                         for x in reversed(range(8))]:
                tile[t_ptr] |= ((data[j] >> x & 1) << 2) | (
                    (data[j + 1] >> x & 1) << 3)
                t_ptr += 1
        if planes == 8:
            t_ptr = 0
            for j, x in [(j, x) for j in range(32, 48, 2)
                         for x in reversed(range(8))]:
                tile[t_ptr] |= ((data[j] >> x & 1) << 4) | ((data[j+1] >> x & 1) << 5) \
                    | ((data[j+16] >> x & 1) << 6) | ((data[j+17] >> x & 1) << 7)
                t_ptr += 1
    imgbits[:64] = tile
    return QPixmap.fromImage(img)
コード例 #18
0
ファイル: video.py プロジェクト: xlongfeng/bigeye
 def onExtendedDataArrived(self, category, data):
     if category == 'videoFrame' and self._timer.isActive():
         self._nextFrame = True
         image = QImage(data, self._width, self._height,
                        QImage.Format_RGB16)
         if self._filename:
             image.save(self._filename)
             self._filename = None
         self.frame = image
         bits = image.bits()
         bits.setsize(image.byteCount())
         frame = np.array(bits, np.uint8).reshape(self._height, self._width,
                                                  2)
         frame = cv2.cvtColor(frame, cv2.COLOR_BGR5652BGR)
         self._videoWriter.write(frame)
         return True
     else:
         return False
コード例 #19
0
class Canvas_Indexed:
    def __init__(self, cols, rows, color=0, tilesize=8):
        self.image = QImage(tilesize * cols, tilesize * rows,
                            QImage.Format_Indexed8)
        self.width = tilesize * cols
        self.tilesize = tilesize
        self.image.fill(0)
        self.imgbits = self.image.bits()
        self.imgbits.setsize(self.image.byteCount())
        self.max_col = 1
        self.max_row = 1

    def draw_tile(self,
                  col,
                  row,
                  image,
                  h_flip=False,
                  v_flip=False,
                  palette=0):
        image = image.mirrored(h_flip, v_flip)
        imgbits = image.bits()
        imgbits.setsize(image.byteCount())
        if palette:
            p = palette << 4
            imgbits[:] = bytes([int(i[0]) | p for i in imgbits])
        x = col * self.tilesize
        y = row * self.tilesize
        start = x + y * self.width
        for i in range(self.tilesize):
            offset = i * self.width
            self.imgbits[start + offset:start + offset +
                         self.tilesize] = imgbits[i * self.tilesize:(i + 1) *
                                                  self.tilesize]
        self.max_col = max(col, self.max_col)
        self.max_row = max(row, self.max_row)

    def pixmap(self, palette, trim=False):
        if trim:
            img = self.image.copy(0, 0, (self.max_col + 1) * self.tilesize,
                                  (self.max_row + 1) * self.tilesize)
            img.setColorTable(palette)
            return QPixmap.fromImage(img)
        self.image.setColorTable(palette)
        return QPixmap.fromImage(self.image)
コード例 #20
0
ファイル: pictures.py プロジェクト: nyalldawson/slyr
    def colorize_picture_data(data, color: QColor, fix_alpha=True):
        """
        Colorizes picture data
        """
        image = QImage()
        image.loadFromData(data)
        if image.isNull():
            raise UnreadablePictureException('Could not read embedded picture data')

        image = image.convertToFormat(QImage.Format_ARGB32)
        ucharptr = image.bits()
        ucharptr.setsize(image.byteCount() * image.height())

        # assume top left pixel is transparent?
        if fix_alpha:
            c = image.pixelColor(0, 0)
            trans_rgba = qRgba(c.red(), c.green(), c.blue(), c.alpha())
            actual_trans_rgba = qRgba(c.red(), c.green(), c.blue(), 0)

            for y in range(image.height()):
                start = y * image.width() * 4
                for x in range(image.width()):
                    x_start = x * 4 + start
                    rgba = struct.unpack('I', ucharptr[x_start:x_start + 4])[0]

                    if rgba == trans_rgba:
                        ucharptr[x_start:x_start + 4] = struct.pack('I', actual_trans_rgba)

        if not color.isValid():
            return image

        alpha = QImage(image)
        image.detach()
        p = QPainter(image)
        p.setCompositionMode(QPainter.CompositionMode_SourceIn)
        p.setBrush(color)
        p.drawRect(image.rect())
        p.setCompositionMode(QPainter.CompositionMode_Multiply)
        p.drawImage(0, 0, alpha)
        p.end()
        return image
コード例 #21
0
    def setImageColor(cls, img, color):
        """Set an image to a single color while preserving the alpha"""
        img = QImage(img)
        modifiedImg = None
        # return img

        red = color.red()
        green = color.green()
        blue = color.blue()
        bits = img.bits()
        bits.setsize(img.byteCount())
        #
        arr = numpy.array(bits).reshape(img.height(), img.width(), 4)
        for line in arr:
            for pix in line:
                pix[0] = blue
                pix[1] = green
                pix[2] = red
        modifiedImg = QImage(arr, img.width(), img.height(),
                             QImage.Format_ARGB32)
        return modifiedImg
コード例 #22
0
ファイル: image_filter.py プロジェクト: SuicideSin/dirtool
def drop_shadow(image: QImage) -> QImage:
    if image.format() != QImage.Format_ARGB32:
        image = image.convertToFormat(QImage.Format_ARGB32)

    bits = image.bits()
    bits.setsize(image.byteCount())

    shape = (image.width() * image.height())
    strides = (4,)

    alpha = numpy.ndarray(shape=shape, dtype=numpy.uint8,
                          buffer=bits, strides=strides, offset=3)
    color = numpy.ndarray(shape=shape, dtype=numpy.uint8)
    color.fill(0)

    alpha = alpha.reshape((image.width(), image.height()))
    alpha = gaussian_filter(alpha, sigma=10)
    alpha = alpha.reshape(shape)

    arr = numpy.dstack((color, color, color, alpha))

    return QImage(arr, image.width(), image.height(), QImage.Format_ARGB32)
コード例 #23
0
ファイル: facedetect.py プロジェクト: SuicideSin/dirtool
def run_facedetect(filename: str) -> Tuple[QImage, List[Any]]:
    image = QImage(filename)
    if image.format() != QImage.Format_RGB32:
        image = image.convertToFormat(QImage.Format_RGB32)

    image = image.scaled(image.width() * scale_factor,
                         image.height() * scale_factor,
                         Qt.IgnoreAspectRatio,
                         Qt.SmoothTransformation)

    bits = image.bits()
    bits.setsize(image.byteCount())

    array = numpy.ndarray(shape=(image.height(), image.bytesPerLine() // 4, 4), dtype=numpy.uint8,
                          buffer=bits)
    array = array[:image.height(), :image.width(), :3]

    img = cv2.imread(filename, cv2.IMREAD_COLOR)
    print(img.shape)
    print(array.shape)

    print(img)
    print()
    print(array)

    detector = dlib.get_frontal_face_detector()
    results = detector(img)
    print(results)
    results = detector(array)
    print(results)

    print("detected {} faces".format(len(results)))

    image = image.scaled(image.width() // scale_factor,
                         image.height() // scale_factor)

    return image, results
コード例 #24
0
def create_tile_indexed(data):
    '''
  Creates a QImage of a SNES tile. Useful for assigning palettes later.
  DO NOT USE OUTSIDE OF QApplication CONTEXT
  '''
    planes = len(data) // 8
    tile = array('B', range(64))
    img = QImage(8, 8, QImage.Format_Indexed8)
    imgbits = img.bits()
    imgbits.setsize(img.byteCount())
    if planes == 0:
        raise ValueError("Empty bytes passed")
    if planes == 1:
        for i, (j, x) in enumerate([(j, x) for j in range(8)
                                    for x in reversed(range(8))]):
            tile[i] = (data[j] >> x & 1)
    else:
        for i, (j, x) in enumerate([(j, x) for j in range(0, 16, 2)
                                    for x in reversed(range(8))]):
            tile[i] = (data[j] >> x & 1) | ((data[j + 1] >> x & 1) << 1)
        if planes == 3:
            for i, (j, x) in enumerate([(j, x) for j in range(16, 24, 1)
                                        for x in reversed(range(8))]):
                tile[i] |= ((data[j] >> x & 1) << 2)
        elif planes >= 4:
            for i, (j, x) in enumerate([(j, x) for j in range(16, 32, 2)
                                        for x in reversed(range(8))]):
                tile[i] |= ((data[j] >> x & 1) << 2) | (
                    (data[j + 1] >> x & 1) << 3)
        if planes == 8:
            for i, (j, x) in enumerate([(j, x) for j in range(32, 48, 2)
                                        for x in reversed(range(8))]):
                tile[i] |= ((data[j] >> x & 1) << 4) | ((data[j+1] >> x & 1) << 5) \
                    | ((data[j+16] >> x & 1) << 6) | ((data[j+17] >> x & 1) << 7)
    imgbits[:64] = tile
    return img
コード例 #25
0
    def set_colors(data: bin, fg: QColor, bg: QColor, trans: QColor) -> bin:  # pylint: disable=too-many-locals
        """
        Burns foreground and background colors into a raster image, and returns
        the results as a PNG binary
        """
        image = QImage()
        image.loadFromData(data)

        image = image.convertToFormat(QImage.Format_ARGB32)
        ucharptr = image.bits()
        ucharptr.setsize(image.byteCount() * image.height())

        fg_rgba = qRgba(fg.red(), fg.green(), fg.blue(),
                        fg.alpha()) if fg and fg.isValid() else None
        bg_rgba = qRgba(bg.red(), bg.green(), bg.blue(),
                        bg.alpha()) if bg and bg.isValid() else None

        # TODO: what's this even for?
        _ = qRgba(trans.red(), trans.green(), trans.blue(),
                  trans.alpha()) if trans else None

        for y in range(image.height()):
            start = y * image.width() * 4
            for x in range(image.width()):
                x_start = x * 4 + start
                rgba = struct.unpack('I', ucharptr[x_start:x_start + 4])[0]

                if fg_rgba is not None and rgba == 0xff000000:
                    ucharptr[x_start:x_start + 4] = struct.pack('I', fg_rgba)
                elif bg_rgba is not None and rgba == 0xffffffff:
                    ucharptr[x_start:x_start + 4] = struct.pack('I', bg_rgba)

        # convert to PNG
        png_data = QBuffer()
        image.save(png_data, "png")
        return png_data.data()
コード例 #26
0
class Renderer:
    def __init__(self, width, height, ownWindow=False):
        self.width = width
        self.height = height

        self.img = QImage(width, height, QImage.Format_RGB888)
        self.painter = QPainter()

        self.window = None
        if ownWindow:
            self.app = QApplication([])
            self.window = Window()

    def close(self):
        """
        Deallocate resources used
        """
        pass

    def beginFrame(self):
        self.painter.begin(self.img)
        self.painter.setRenderHint(QPainter.Antialiasing, False)

        # Clear the background
        self.painter.setBrush(QColor(0, 0, 0))
        self.painter.drawRect(0, 0, self.width - 1, self.height - 1)

    def endFrame(self):
        self.painter.end()

        if self.window:
            if self.window.closed:
                self.window = None
            else:
                self.window.setPixmap(self.getPixmap())
                self.app.processEvents()

    def getPixmap(self):
        return QPixmap.fromImage(self.img)

    def getArray(self):
        """
        Get a numpy array of RGB pixel values.
        The size argument should be (3,w,h)
        """

        width = self.width
        height = self.height
        shape = (width, height, 3)

        numBytes = self.width * self.height * 3
        buf = self.img.bits().asstring(numBytes)
        output = np.frombuffer(buf, dtype='uint8')
        output = output.reshape(shape)

        return output

    def push(self):
        self.painter.save()

    def pop(self):
        self.painter.restore()

    def rotate(self, degrees):
        self.painter.rotate(degrees)

    def translate(self, x, y):
        self.painter.translate(x, y)

    def scale(self, x, y):
        self.painter.scale(x, y)

    def setLineColor(self, r, g, b, a=255):
        self.painter.setPen(QColor(r, g, b, a))

    def setColor(self, r, g, b, a=255):
        self.painter.setBrush(QColor(r, g, b, a))

    def setLineWidth(self, width):
        pen = self.painter.pen()
        pen.setWidthF(width)
        self.painter.setPen(pen)

    def drawLine(self, x0, y0, x1, y1):
        self.painter.drawLine(x0, y0, x1, y1)

    def drawCircle(self, x, y, r):
        center = QPoint(x, y)
        self.painter.drawEllipse(center, r, r)

    def drawPolygon(self, points):
        """Takes a list of points (tuples) as input"""
        points = map(lambda p: QPoint(p[0], p[1]), points)
        self.painter.drawPolygon(QPolygon(points))

    def fillRect(self, x, y, width, height, r, g, b, a=255):
        self.painter.fillRect(QRect(x, y, width, height), QColor(r, g, b, a))
コード例 #27
0
ファイル: ramps_gui.py プロジェクト: dakoner/heliostat
class Window(QMainWindow):
    def __init__(self, *args, **kwargs):
        super(QMainWindow, self).__init__(*args, **kwargs)
        self.setWindowTitle("My Awesome App")
        self.setFixedSize(*RESOLUTION)

        self.client = MqttClient(self)
        self.client.hostname = "localhost"
        self.client.connectToHost()

        self.label = QLabel(parent=self)
        self.label.show()
        self.qimage = QImage(RESOLUTION[0], RESOLUTION[1],
                             QImage.Format_RGB888)
        self.label.resize(self.qimage.size())

        up_button = QPushButton("Up", parent=self)
        up_button.setAutoRepeat(True)
        up_button.setAutoRepeatInterval(150)
        up_button.move(400, 10)
        up_button.setFixedSize(120, 60)
        up_button.show()
        up_button.clicked.connect(self.on_up_button)

        down_button = QPushButton("Down", parent=self)
        down_button.setAutoRepeat(True)
        down_button.setAutoRepeatInterval(150)
        down_button.move(400, 400)
        down_button.setFixedSize(120, 60)
        down_button.show()
        down_button.clicked.connect(self.on_down_button)

        left_button = QPushButton("Left", parent=self)
        left_button.setAutoRepeat(True)
        down_button.setAutoRepeatInterval(150)
        left_button.move(10, 240)
        left_button.setFixedSize(120, 60)
        left_button.show()
        left_button.clicked.connect(self.on_left_button)

        right_button = QPushButton("Right", parent=self)
        right_button.setAutoRepeat(True)
        right_button.setAutoRepeatInterval(150)
        right_button.move(675, 240)
        right_button.setFixedSize(120, 60)
        right_button.show()
        right_button.clicked.connect(self.on_right_button)

        self.qpicamera_thread = QThread()
        self.qpicamera = QPiCamera()
        self.qpicamera.messageSignal.connect(self.on_qpicameraSignal)
        self.qpicamera.moveToThread(self.qpicamera_thread)
        self.qpicamera_thread.started.connect(self.qpicamera.loop)
        self.qpicamera_thread.start()

    def on_up_button(self):
        p = self.label.pos()
        self.client.publish("heliostat/ramps/command", "G0 Y1")

    def on_down_button(self):
        p = self.label.pos()
        self.client.publish("heliostat/ramps/command", "G0 Y-1")

    def on_left_button(self):
        p = self.label.pos()
        self.client.publish("heliostat/ramps/command", "G0 X-1")

    def on_right_button(self):
        p = self.label.pos()
        self.client.publish("heliostat/ramps/command", "G0 X1")

    @pyqtSlot(bytes)
    def on_qpicameraSignal(self, img):
        b = self.qimage.bits()
        b.setsize(RESOLUTION[0] * RESOLUTION[1] * 3)
        b[:] = img
        pixmap = QPixmap(self.qimage)
        self.label.setPixmap(pixmap)
コード例 #28
0
class Renderer:
    def __init__(self, width, height):
        self.width = width
        self.height = height

        self.img = QImage(width, height, QImage.Format_RGB888)
        self.painter = QPainter()

    def beginFrame(self):
        self.painter.begin(self.img)
        self.painter.setRenderHint(QPainter.Antialiasing, False)

        # Clear the background
        self.painter.setBrush(QColor(0, 0, 0))
        self.painter.drawRect(0, 0, self.width - 1, self.height - 1)

    def endFrame(self):
        self.painter.end()

    def getPixmap(self):
        return QPixmap.fromImage(self.img)

    def getArray(self):
        """
        Get a numpy array of RGB pixel values.
        The size argument should be (3,w,h)
        """

        width = self.width
        height = self.height
        shape = (width, height, 3)

        # Copy the pixel data to a numpy array
        #output = np.ndarray(shape=shape, dtype='uint8')
        #for y in range(0, height):
        #    for x in range(0, width):
        #        pix = self.img.pixel(x, y)
        #        r = (pix >> 16) & 0xFF
        #        g = (pix >>  8) & 0xFF
        #        b = (pix >>  0) & 0xFF
        #        output[x, y, 0] = r
        #        output[x, y, 1] = g
        #        output[x, y, 2] = b

        numBytes = self.width * self.height * 3
        buf = self.img.bits().asstring(numBytes)
        output = np.frombuffer(buf, dtype='uint8')
        output = output.reshape(shape)

        return output

    def push(self):
        self.painter.save()

    def pop(self):
        self.painter.restore()

    def rotate(self, degrees):
        self.painter.rotate(degrees)

    def translate(self, x, y):
        self.painter.translate(x, y)

    def scale(self, x, y):
        self.painter.scale(x, y)

    def setLineColor(self, r, g, b, a=255):
        self.painter.setPen(QColor(r, g, b, a))

    def setColor(self, r, g, b, a=255):
        self.painter.setBrush(QColor(r, g, b, a))

    def drawLine(self, x0, y0, x1, y1):
        self.painter.drawLine(x0, y0, x1, y1)

    def drawCircle(self, x, y, r):
        center = QPoint(x, y)
        self.painter.drawEllipse(center, r, r)

    def drawPolygon(self, points):
        """Takes a list of points (tuples) as input"""
        points = map(lambda p: QPoint(p[0], p[1]), points)
        self.painter.drawPolygon(QPolygon(points))

    def fillRect(self, x, y, width, height, r, g, b, a=255):
        self.painter.fillRect(QRect(x, y, width, height), QColor(r, g, b, a))
コード例 #29
0
class Renderer:
    def __init__(self, width, height, ownWindow=False):
        self.width = width
        self.height = height

        self.img = QImage(width, height, QImage.Format_RGB888)
        self.painter = QPainter()

        self.window = None
        if ownWindow:
            self.app = QApplication([])
            self.window = Window()

    def close(self):
        """
        Deallocate resources used
        """
        pass

    def beginFrame(self, shape_map, positions):
        self.bytesPerLine = 3 * self.im_np.shape[1]
        self.img = QImage(shape_map, shape_map.shape[0], shape_map.shape[1], bytesPerLine, QImage.Format_RGB888)
        self.painter.begin(self.img)
        self.painter.setRenderHint(QPainter.Antialiasing, False)
        # Clear the background
        self.qrect = []
        self.painter.setBrush(QColor(1, 1, 1))
        for p in positions:
            self.qrect.append(QRect(p[0], p[1], 5, 5))
            self.painter.drawRect(self.qrect[-1])

    def endFrame(self):
        self.painter.end()

        if self.window:
            if self.window.closed:
                self.window = None
            else:
                self.window.setPixmap(self.getPixmap())
                self.app.processEvents()

    def getPixmap(self):
        return QPixmap.fromImage(self.img)

    def getArray(self):
        """
        Get a numpy array of RGB pixel values.
        The array will have shape (height, width, 3)
        """

        numBytes = self.width * self.height * 3
        buf = self.img.bits().asstring(numBytes)
        output = np.frombuffer(buf, dtype='uint8')
        output = output.reshape((self.height, self.width, 3))

        return output

    def push(self):
        self.painter.save()

    def pop(self):
        self.painter.restore()

    def rotate(self, degrees):
        self.painter.rotate(degrees)

    def translate(self, ind, x, y):
        self.qrect[ind].translate(x, y)
        self.window.update()

    def scale(self, x, y):
        self.painter.scale(x, y)

    def setLineColor(self, r, g, b, a=255):
        self.painter.setPen(QColor(r, g, b, a))

    def setColor(self, r, g, b, a=255):
        self.painter.setBrush(QColor(r, g, b, a))

    def setLineWidth(self, width):
        pen = self.painter.pen()
        pen.setWidthF(width)
        self.painter.setPen(pen)

    def drawLine(self, x0, y0, x1, y1):
        self.painter.drawLine(x0, y0, x1, y1)

    def drawCircle(self, x, y, r):
        center = QPoint(x, y)
        self.painter.drawEllipse(center, r, r)

    def drawPolygon(self, points):
        """Takes a list of points (tuples) as input"""
        points = map(lambda p: QPoint(p[0], p[1]), points)
        self.painter.drawPolygon(QPolygon(points))

    def drawPolyline(self, points):
        """Takes a list of points (tuples) as input"""
        points = map(lambda p: QPoint(p[0], p[1]), points)
        self.painter.drawPolyline(QPolygon(points))

    def fillRect(self, x, y, width, height, r, g, b, a=255):
        self.painter.fillRect(QRect(x, y, width, height), QColor(r, g, b, a))
コード例 #30
0
class Paint(QMainWindow):
    def __init__(self, update_function):
        super().__init__()

        title = "Aplikacja do rysowania"

        self.setWindowTitle(title)
        self.setGeometry(800, 400, 128, 128)

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

        self.drawing = False
        self.brushSize = 9
        self.brushColor = Qt.white
        self.lastPoint = QPoint()

        mainMenu = self.menuBar()
        fileMenu = mainMenu.addMenu("Plik")
        brushSize = mainMenu.addMenu("Rozmiar pisaka")
        brushColor = mainMenu.addMenu("Kolor pisaka")

        saveAction = QAction("Zapisz", self)
        saveAction.setShortcut("Ctrl+S")
        fileMenu.addAction(saveAction)
        saveAction.triggered.connect(self.save)

        clearAction = QAction("Wyczyść", 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("Czarny", self)
        blackAction.setShortcut("Ctrl+B")
        brushColor.addAction(blackAction)
        blackAction.triggered.connect(self.blackColor)

        whitekAction = QAction("Biały", self)
        whitekAction.setShortcut("Ctrl+W")
        brushColor.addAction(whitekAction)
        whitekAction.triggered.connect(self.whiteColor)

        redAction = QAction("Czerwony", self)
        redAction.setShortcut("Ctrl+R")
        brushColor.addAction(redAction)
        redAction.triggered.connect(self.redColor)

        greenAction = QAction("Zielony", self)
        greenAction.setShortcut("Ctrl+G")
        brushColor.addAction(greenAction)
        greenAction.triggered.connect(self.greenColor)

        yellowAction = QAction("Żółty", self)
        yellowAction.setShortcut("Ctrl+Y")
        brushColor.addAction(yellowAction)
        yellowAction.triggered.connect(self.yellowColor)

        self.update_function = update_function

    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 getNumpyImage(self):
        image = self.image.convertToFormat(4)

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

        ptr = self.image.bits()
        ptr.setsize(self.image.byteCount())
        arr = np.array(ptr).reshape(height, width, 4)
        arr = cv2.resize(arr, (28, 28))
        return arr

    def mouseReleaseEvent(self, event):

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

        numpyImage = self.getNumpyImage()

        # Przekształcenie zdjęcia do skali szarości
        gray = rgb2gray(numpyImage)

        # Przeształcenie zdjęcia do takiej samej stukrtury jak dane uczace, N elementowa lista zdjęć 28x28x1
        gray = gray.reshape((1, 28, 28, 1))

        self.update_function(gray)

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

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

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

    def clear(self):
        self.image.fill(Qt.black)
        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
コード例 #31
0
class EngineOutputFrameView(QWidget):
    def __init__(self):
        super().__init__()
        self._ratio = AspecRatio.Ratio_None
        self._isHorizontal = False
        self._isMousePressed = False
        self._lastMousePt = (0, 0)

        self._tickTimer = QTimer()
        self._tickTimer.timeout.connect(self._onTick)
        self._tickTimer.start()

        self._image = QImage(
            QSize(_MIN_WIDTH, self._getHeightFromWidth(_MIN_WIDTH)),
            QImage.Format_RGBA8888)
        self._image.fill(Qt.black)
        self.setMinimumSize(QSize(_MIN_WIDTH, _MIN_WIDTH))
        self.setMouseTracking(True)

    def _getHeightFromWidth(self, width):
        x = None
        y = None
        if self._ratio == AspecRatio.Ratio_4x3:
            x = 4
            y = 3
        elif self._ratio == AspecRatio.Ratio_16x9:
            x = 16
            y = 9
        elif self._ratio == AspecRatio.Ratio_16x10:
            x = 16
            y = 10
        elif self._ratio == AspecRatio.Ratio_5x3:
            x = 5
            y = 3
        elif self._ratio == AspecRatio.Ratio_18x9:
            x = 18
            y = 9
        elif self._ratio == AspecRatio.Ratio_21x9:
            x = 21
            y = 9
        elif self._ratio == AspecRatio.Ratio_None:
            return self.size().height()
        else:
            raise RuntimeError("Unknown aspect ratio: '{0}'".format(
                self._ratio))
        if self._isHorizontal:
            return int(width * y / x)
        else:
            return int(width * x / y)

    def _onTick(self):
        self.update()

    def resizeEvent(self, event):
        size = event.size()
        height = self._getHeightFromWidth(size.width())
        scaleFactor = 1
        if height > size.height():
            scaleFactor = size.height() / height
        newWidth = int(max(size.width() * scaleFactor, 1))
        newWidth -= newWidth % 2
        newHeight = int(max(height * scaleFactor, 1))
        newHeight -= newHeight % 2
        self._image = self._image.scaled(newWidth, newHeight)
        GetEngineViewManager().onOutputFrameSizeChanged(newWidth, newHeight)

    def _getDrawPoint(self):
        sz = self.size()
        x = (sz.width() - self._image.width()) / 2
        y = (sz.height() - self._image.height()) / 2
        return QPoint(int(x), int(y))

    def paintEvent(self, event):
        w, h = self._image.width(), self._image.height()
        GetEngineViewManager().drawNativeFrameTo(self._image.bits().__int__(),
                                                 w, h)

        painter = QPainter()
        painter.begin(self)
        painter.translate(w / 2, h / 2)
        painter.rotate(180)
        painter.scale(-1.0, 1.0)
        painter.drawImage(-w / 2, -h / 2, self._image)
        painter.end()

    def setAspectRatio(self, ratio):
        self._ratio = ratio
        newHeight = self._getHeightFromWidth(self.size().width())
        self._image = self._image.scaled(self._image.width(), newHeight)
        self._image.fill(Qt.black)
        self.resizeEvent(QResizeEvent(self.size(), QSize()))

    def setOrientation(self, isHorizontal):
        self._isHorizontal = isHorizontal
        self.setAspectRatio(self._ratio)

    def _getPosInside(self, event):
        pt = event.pos()
        x, y = pt.x(), pt.y()
        y = self.size().height() - y
        drawPt = self._getDrawPoint()
        minX = drawPt.x()
        minY = drawPt.y()
        maxX = minX + self._image.width()
        maxY = minY + self._image.height()
        if x < minX or x >= maxX:
            return None, None
        if y < minY or y >= maxY:
            return None, None
        x = x - minX
        y = y - minY
        return x, y

    def mousePressEvent(self, event):
        x, y = self._getPosInside(event)
        if x is None or y is None:
            return
        if event.button() != Qt.LeftButton:
            return
        self._lastMousePt = (x, y)
        self._isMousePressed = True
        GetEngineViewManager().onMouseInputEvent(MouseEventType.Press, x, y)

    def mouseReleaseEvent(self, event):
        x, y = self._getPosInside(event)
        if x is None or y is None:
            return
        if event.button() != Qt.LeftButton:
            return
        if self._isMousePressed == False:
            return
        self._isMousePressed = False
        GetEngineViewManager().onMouseInputEvent(MouseEventType.Release, x, y)
        self._lastMousePt = (0, 0)

    def mouseMoveEvent(self, event):
        if not self._isMousePressed:
            return
        x, y = self._getPosInside(event)
        if x is None or y is None:
            GetEngineViewManager().onMouseInputEvent(MouseEventType.Release,
                                                     self._lastMousePt[0],
                                                     self._lastMousePt[1])
            self._lastMousePt = (0, 0)
            self._isMousePressed = False
        else:
            self._lastMousePt = (x, y)
            GetEngineViewManager().onMouseInputEvent(MouseEventType.Move, x, y)
コード例 #32
0
ファイル: cell-gen-texture.py プロジェクト: sjdv1982/seamless
img = QImage(filename)
img = img.convertToFormat(QImage.Format_RGB888)
assert img.format() == QImage.Format_RGB888
assert img.width()*img.height()*3 == img.byteCount()

if inscription != "":
    img2 = QImage(img.width(), img.height(), QImage.Format_RGB888)

    from PyQt5.QtGui import QPainter
    qp = QPainter()
    try:
        qp.begin(img2) #different results than painting on img!
        qp.drawImage(0,0,img)
        qp.setPen(QColor(255,185,50))
        fx = 2
        fy = 20
        font = QFont("Arial", int(0.7*img.height()/fy))
        qp.setFont(font)
        mx = img.width() / fx
        my = img.height() / fy
        for x in range(fx):
            for y in range(fy):
                qp.drawText(x*mx, y*my, mx, my, Qt.AlignCenter,inscription)
    finally:
        qp.end()
    img = img2

arr = np.array(img.bits().asarray(img.byteCount())).reshape(img.width(),img.height(),3)
arr = arr[::-1,:,:]
return arr
コード例 #33
0
from PyQt5.QtGui import QImage, QFont, QColor
from PyQt5.QtCore import Qt
import os, numpy as np
from scipy.ndimage import sobel, gaussian_filter

arr = np.zeros(texture.shape)

displacement_weight = 2, 1.1
if normal_texture_filename != "":
    img = QImage(normal_texture_filename)
    img = img.convertToFormat(QImage.Format_RGB888)
    assert img.format() == QImage.Format_RGB888
    assert img.width() * img.height() * 3 == img.byteCount()
    tex_arr = np.array(img.bits().asarray(img.byteCount())).reshape(
        img.width(), img.height(), 3)
    arr += tex_arr
else:
    sigma = 1.3

    tex_arr = texture.sum(axis=-1) / 3
    tex_arr2 = np.zeros(arr.shape, dtype=np.float32)
    tex_arr2[:, :,
             0] = 0.5 - sobel(tex_arr, 0) * displacement_weight[0] / 255.0
    tex_arr2[:, :,
             1] = 0.5 - sobel(tex_arr, 1) * displacement_weight[0] / 255.0
    tex_arr2[:, :, 2] = 1
    tex_arr2 /= np.linalg.norm(tex_arr2, axis=2, keepdims=True)
    tex_arr3 = gaussian_filter(tex_arr2, sigma=sigma)
    tex_arr3 /= np.linalg.norm(tex_arr3, axis=2, keepdims=True)
    tex_arr3[:, :, :2] *= displacement_weight[1]
    arr += tex_arr3
コード例 #34
0
ファイル: rendering.py プロジェクト: JACKHAHA363/baby-ai-game
class Renderer:
    def __init__(self, width, height, ownWindow=False):
        self.width = width
        self.height = height

        self.img = QImage(width, height, QImage.Format_RGB888)
        self.painter = QPainter()

        self.window = None
        if ownWindow:
            self.app = QApplication([])
            self.window = Window()

    def close(self):
        """
        Deallocate resources used
        """
        pass

    def beginFrame(self):
        self.painter.begin(self.img)
        self.painter.setRenderHint(QPainter.Antialiasing, False)

        # Clear the background
        self.painter.setBrush(QColor(0, 0, 0))
        self.painter.drawRect(0, 0, self.width - 1, self.height - 1)

    def endFrame(self):
        self.painter.end()

        if self.window:
            if self.window.closed:
                self.window = None
            else:
                self.window.setPixmap(self.getPixmap())
                self.app.processEvents()

    def getPixmap(self):
        return QPixmap.fromImage(self.img)

    def getArray(self):
        """
        Get a numpy array of RGB pixel values.
        The size argument should be (3,w,h)
        """

        width = self.width
        height = self.height
        shape = (width, height, 3)

        numBytes = self.width * self.height * 3
        buf = self.img.bits().asstring(numBytes)
        output = np.frombuffer(buf, dtype='uint8')
        output = output.reshape(shape)

        return output

    def push(self):
        self.painter.save()

    def pop(self):
        self.painter.restore()

    def rotate(self, degrees):
        self.painter.rotate(degrees)

    def translate(self, x, y):
        self.painter.translate(x, y)

    def scale(self, x, y):
        self.painter.scale(x, y)

    def setLineColor(self, r, g, b, a=255):
        self.painter.setPen(QColor(r, g, b, a))

    def setColor(self, r, g, b, a=255):
        self.painter.setBrush(QColor(r, g, b, a))

    def drawLine(self, x0, y0, x1, y1):
        self.painter.drawLine(x0, y0, x1, y1)

    def drawCircle(self, x, y, r):
        center = QPoint(x, y)
        self.painter.drawEllipse(center, r, r)

    def drawPolygon(self, points):
        """Takes a list of points (tuples) as input"""
        points = map(lambda p: QPoint(p[0], p[1]), points)
        self.painter.drawPolygon(QPolygon(points))

    def fillRect(self, x, y, width, height, r, g, b, a=255):
        self.painter.fillRect(QRect(x, y, width, height), QColor(r, g, b, a))