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
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)
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)
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
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()
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)
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
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)
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
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
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
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)
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
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
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
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)
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
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)
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
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
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)
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
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
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()
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))
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)
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))
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))
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
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)
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
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
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))