def run(self): image = QImage() image.load(str(self.filename)) mask = QImage(image.size(), QImage.Format_RGB32) mask.fill(Qt.black) maskfile = self.filename.parent / (self.filename.stem + ".mask") if maskfile.exists(): bitmap = QImage(str(maskfile)) if bitmap.size() != image.size(): raise Exception("Mask %s doesn't match image size" % maskfile) mask.fill(QColor.fromRgbF(1.0, 0.0, 1.0)) p = QPainter(mask) p.setCompositionMode(QPainter.CompositionMode_Multiply) p.drawImage(mask.rect(), bitmap) p.end() self.view.imagefile = self.filename self.view.image = image self.view.mask = mask self.view.maskfile = maskfile self.view.path = list() self.view.changed = False self.view.update()
def save_image_to(self, path, top_margin=50, bottom_margin=50, left_margin=50, right_margin=50): margins = QMarginsF(left_margin, top_margin, right_margin, bottom_margin) oldRect = self.scene().sceneRect() minRect = self.scene().itemsBoundingRect() imgRect = minRect.marginsAdded(margins) image = QImage(imgRect.size().toSize(), QImage.Format_ARGB32) image.fill(Qt.white) painter = QPainter(image) painter.setRenderHints(QPainter.Antialiasing | QPainter.SmoothPixmapTransform | QPainter.HighQualityAntialiasing) # draw the image self.scene().setSceneRect(imgRect) self.scene().render(painter) image.save(path) # cleanup painter.end() # restore the old scene rect self.scene().setSceneRect(oldRect)
def paintEvent(self, event): outerRadius = min(self.width(), self.height()) baseRect = QRectF(1, 1, outerRadius - 2, outerRadius - 2) buffer = QImage(outerRadius, outerRadius, QImage.Format_ARGB32) buffer.fill(0) p = QPainter(buffer) p.setRenderHint(QPainter.Antialiasing) # data brush self.rebuildDataBrushIfNeeded() # background self.drawBackground(p, buffer.rect()) # base circle self.drawBase(p, baseRect) # data circle arcStep = 360.0 / (self.max - self.min) * self.value self.drawValue(p, baseRect, self.value, arcStep) # center circle innerRect, innerRadius = self.calculateInnerRect(baseRect, outerRadius) self.drawInnerBackground(p, innerRect) # text self.drawText(p, innerRect, innerRadius, self.value) # finally draw the bar p.end() painter = QPainter(self) painter.drawImage(0, 0, buffer)
def save_image_to(self, path): TOP_MARGIN = 50 LEFT_MARGIN = 50 # Determine the size of the entire graph graph_size = self._graph_size() image_size = QSize(graph_size.width() + LEFT_MARGIN * 2, graph_size.height() + TOP_MARGIN * 2 ) image = QImage(image_size, QImage.Format_ARGB32) image.fill(Qt.white) # white background painter = QPainter(image) painter.translate(TOP_MARGIN, LEFT_MARGIN) painter.setRenderHint(QPainter.TextAntialiasing) self._paint(painter, QPoint(-TOP_MARGIN, -LEFT_MARGIN), QPoint(image_size.width(), image_size.height()) ) painter.end() image.save(path)
def doubleBufferPaint(self, buffer=None): self.blockSignals(True) #self.drawFrame(painter) if buffer is None: buffer = QImage(self.width(), self.height(), QImage.Format_RGB888) buffer.fill(Qt.black) # calculate offset and scale of droplet image pixmap scale_x, scale_y, offset_x, offset_y = self.get_from_image_transform() db_painter = QPainter(buffer) db_painter.setRenderHints(QPainter.Antialiasing | QPainter.NonCosmeticDefaultPen) db_painter.setBackground(QBrush(Qt.black)) db_painter.setPen(QPen(Qt.black, 0)) db_painter.drawPixmap(offset_x, offset_y, self._pixmap) pen = QPen(Qt.magenta, 1) pen_fine = QPen(Qt.blue, 1) pen.setCosmetic(True) db_painter.setPen(pen) # draw droplet outline and tangent only if evaluate_droplet was successful if self._droplet.is_valid: try: # transforming true image coordinates to scaled pixmap coordinates db_painter.translate(offset_x, offset_y) db_painter.scale(scale_x, scale_y) # drawing tangents and baseline db_painter.drawLine(*self._droplet.line_l) db_painter.drawLine(*self._droplet.line_r) db_painter.drawLine(*self._droplet.int_l, *self._droplet.int_r) # move origin to ellipse origin db_painter.translate(*self._droplet.center) # draw diagnostics # db_painter.setPen(pen_fine) # # lines parallel to coordinate axes # db_painter.drawLine(0,0,20*scale_x,0) # db_painter.drawLine(0,0,0,20*scale_y) # # angle arc # db_painter.drawArc(-5*scale_x, -5*scale_y, 10*scale_x, 10*scale_y, 0, -self._droplet.tilt_deg*16) # rotate coordinates to ellipse tilt db_painter.rotate(self._droplet.tilt_deg) # draw ellipse # db_painter.setPen(pen) db_painter.drawEllipse(-self._droplet.maj / 2, -self._droplet.min / 2, self._droplet.maj, self._droplet.min) # # major and minor axis for diagnostics # db_painter.drawLine(0, 0, self._droplet.maj/2, 0) # db_painter.drawLine(0, 0, 0, self._droplet.min/2) except Exception as ex: logging.error(ex) db_painter.end() self.blockSignals(False) return buffer
def resizeImage(self, image, newSize): if self.image.size() == newSize: return newImage = QImage(newSize, QImage.Format_RGB32) newImage.fill(qRgb(255, 255, 255)) painter = QPainter(newImage) painter.drawImage(QPoint(0, 0), self.image) self.image = newImage
class Layer: canvas_size: QtCore.QSize image: QtGui.QImage def __init__(self, size=QtCore.QSize(128, 128)): self.canvas_size = size self.image = QImage(self.canvas_size, QImage.Format_ARGB32) self.image.size = self.canvas_size self.image.fill(QtCore.Qt.transparent)
def __init__(self, cModel, QImg, target=None, size=0, border=0): """ @param cModel: color model @type cModel: cmConverter @param QImg: color wheel @type QImg: vImage @param target: image to sample @type target: QImage @param size: color wheel diameter @type size: integer @param border: border size @type border: int """ self.QImg = QImg # not a back link !!! self.border = border if size == 0: self.size = min(QImg.width(), QImg.heigth()) - 2 * border else: self.size = size self.origin = 0 # calculate target histogram self.targetHist = None if target is not None: # convert to current color space hsxImg = cModel.rgb2cmVec(QImageBuffer(target)[:, :, :3][:, :, ::-1]) # get polar coordinates relative to the color wheel xyarray = self.QImg.GetPointVec(hsxImg).astype(int) maxVal = self.QImg.width() STEP = 10 # build 2D histogram for xyarray H, xedges, yedges = np.histogram2d(xyarray[:, :, 0].ravel(), xyarray[:,:,1].ravel(), bins=[np.arange(0, maxVal+STEP, STEP), np.arange(0, maxVal + STEP, STEP)], normed=True) w,h = QImg.width(), QImg.height() b = QImage(w, h, QImage.Format_ARGB32) b.fill(0) buf = QImageBuffer(b) # set the transparency of each pixel # proportionally to the height of its bin # get bin indices (u, v) u = xyarray[:,:,0] // STEP v = xyarray[:,:,1] // STEP # get heights of bins tmp = H[u,v] norma = np.amax(H) # color white buf[xyarray[:,:,1], xyarray[:,:,0],...] = 255 # alpha channel buf[xyarray[:, :, 1], xyarray[:, :, 0], 3] = 90 + 128.0 * tmp / norma self.targetHist = b self.showTargetHist = False super().__init__(self.QImg.rPixmap) self.setPixmap(self.QImg.rPixmap) self.setOffset(QPointF(-border, -border)) self.onMouseRelease = lambda p, x, y, z: 0 self.rubberBand = None
def createOffscreenBitmap(self, state: CreateOffscreenBitmap): LOG.debug(state) bmp = QImage(state.cx, state.cy, QImage.Format_ARGB32_Premultiplied) bmp.fill(0) self.surfaces[state.id] = bmp for d in state.delete: if d in self.surfaces: del self.surfaces[d]
def test(self): image = QImage(QSize(200, 200), QImage.Format_ARGB32) image.fill(QColor(Qt.red)) pixelFormat = image.pixelFormat() print(pixelFormat.greenSize()) self.assertEqual(pixelFormat.alphaSize(), 8) self.assertEqual(pixelFormat.redSize(), 8) self.assertEqual(pixelFormat.greenSize(), 8) self.assertEqual(pixelFormat.blueSize(), 8) self.assertEqual(pixelFormat.bitsPerPixel(), 32)
def get_viewport_img(self): self.hide_proxies() img = QImage(self.viewport().rect().width(), self.viewport().height(), QImage.Format_ARGB32) img.fill(Qt.transparent) painter = QPainter(img) painter.setRenderHint(QPainter.Antialiasing) self.render(painter, self.viewport().rect(), self.viewport().rect()) self.show_proxies() return img
def paint_with_opacity(pixmap: QPixmap, opacity: float): transparent_image = QImage(QSize(36, 36), QImage.Format_ARGB32_Premultiplied) transparent_image.fill(Qt.transparent) painter = QPainter(transparent_image) painter.setOpacity(opacity) painter.drawPixmap(18 - pixmap.width() / 2, 18 - pixmap.height() / 2, pixmap) painter.end() return QPixmap.fromImage(transparent_image)
def as_image(self) -> QImage: image = QImage(QSize(self.width * Block.SIDE_LENGTH, self.height * Block.SIDE_LENGTH), QImage.Format_RGBA8888,) image.fill(QColor(0, 0, 0, 0)) painter = QPainter(image) self.draw(painter, Block.SIDE_LENGTH, True) return image
def get_img(self): # pixmap = self.render_view.grab(self.render_view.sceneRect().toRect()) img = QImage(self.scene().sceneRect().size().toSize(), QImage.Format_ARGB32) img.fill(Qt.transparent) painter = QPainter(img) painter.setRenderHint(QPainter.Antialiasing) self.scene().render(painter) # app crashes here for some reason # img.save('H:/Projekte/QT/PySide2/pyScript/pyScript_011/mypic.png') return img
class QMiniMapTargetSceneViewer(QGraphicsItem): """ Widget to render minimized version of the target view's scene on the minimap. For performance, the scene is cached in a QImage and only updated when update_scene_drawing is called. """ def __init__(self, target_view: QGraphicsView, *args, **kwargs): super().__init__(*args, **kwargs) self._view: QGraphicsView = target_view self._minimap_scene_rect: QRectF = QRectF() self._scene_img: QImage = QImage() def set_scene_rect(self, rect: QRectF): """ Define the dimensions of the total minimap scene. """ self.prepareGeometryChange() self._minimap_scene_rect = rect self.update_scene_drawing() self.update() def update_scene_drawing(self): """ Render the target scene in an image to be used for minimap painting. """ scene = self._view.scene() if scene is None: return dpr = self._view.devicePixelRatioF() self._scene_img = QImage(dpr * self._minimap_scene_rect.width(), dpr * self._minimap_scene_rect.height(), QImage.Format_ARGB32) self._scene_img.setDevicePixelRatio(dpr) self._scene_img.fill(Conf.palette_base) self._view.set_extra_render_pass(True) painter = QPainter(self._scene_img) painter.setRenderHints(QPainter.Antialiasing | QPainter.SmoothPixmapTransform | QPainter.HighQualityAntialiasing) scene.render(painter, target=self._minimap_scene_rect) self._view.set_extra_render_pass(False) self.update() def paint(self, painter, option, widget): # pylint: disable=unused-argument """ Paint the minimized scene image. """ painter.drawImage(0, 0, self._scene_img) def boundingRect(self): return self._minimap_scene_rect
def waveFront(self): """ Experimental waveFront. Unused yet @return: @rtype: """ wfi = QImage(QSize(self.width(), 256), QImage.Format_ARGB32) wfi.fill(Qt.black) wfiBuf = QImageBuffer(wfi)[:,:,:3] frameWidth = 1 buf = QImageBuffer(self) for x in range(0, self.width(), frameWidth): bufFrame = buf[:, x:x+frameWidth, 1] hist, bins = np.histogram(bufFrame, bins=128, range=(0, 255), density=True) wfiBuf[::2, x:x+frameWidth, :] = (hist * 256000)[..., np.newaxis, np.newaxis]
class CanvasLabel(QtWidgets.QLabel): redraw = QtCore.Signal((QtCore.QObject,)) def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.setAttribute(QtCore.Qt.WA_NoSystemBackground) self.canvas_scale = QtCore.QSizeF(1, 1) self.setup_overlay() self.setBackgroundRole(QtGui.QPalette.Light) self.setScaledContents(True) def setPixmap(self, pixmap): super().setPixmap(pixmap) if self.pixmap().size() != self.overlay_image.size(): self.setup_overlay() def setup_overlay(self): if self.pixmap(): size = QtCore.QSize(self.pixmap().width(), self.pixmap().height()) else: size = QtCore.QSize(self.size().width(), self.size().height()) self.setup_overlay_image(size) def setup_overlay_image(self, size): self.overlay_image = QImage(size, QImage.Format_ARGB32) self.overlay_image.setDevicePixelRatio(self.devicePixelRatioF()) self.overlay_image.fill(QtGui.QColor(0, 0, 0, 0)) def paintEvent(self, event): image_rect = QtCore.QRectF(QtCore.QPointF(0, 0), QtCore.QSizeF(self.pixmap().size())*self.canvas_scale) self_rect = self.contentsRect() bg_texture = QtGui.QPixmap(':/textures/bg.png') bg_texture.setDevicePixelRatio(self.devicePixelRatioF()) bg_brush = QtGui.QBrush(bg_texture) painter = QtGui.QPainter(self) painter.fillRect(self.contentsRect(), QtGui.QColor(0, 0, 0, 255)) painter.fillRect(image_rect, bg_brush) painter.drawPixmap(image_rect, self.pixmap(), QtCore.QRectF(self.pixmap().rect())) #painter.drawImage(image_rect, self.overlay_image) self.redraw.emit(self) painter.end()
class EntropyWidget(QWidget): def __init__(self, parent, view, data): super(EntropyWidget, self).__init__(parent) self.view = view self.data = data self.raw_data = data.file.raw self.block_size = (len(self.raw_data) / 4096) + 1 if self.block_size < 1024: self.block_size = 1024 self.width = int(len(self.raw_data) / self.block_size) self.image = QImage(self.width, 1, QImage.Format_ARGB32) self.image.fill(QColor(0, 0, 0, 0)) self.thread = EntropyThread(self.raw_data, self.image, self.block_size) self.started = False self.timer = QTimer() self.timer.timeout.connect(self.timerEvent) self.timer.setInterval(100) self.timer.setSingleShot(False) self.timer.start() self.setMinimumHeight(UIContext.getScaledWindowSize(32, 32).height()) def paintEvent(self, event): p = QPainter(self) p.drawImage(self.rect(), self.image) p.drawRect(self.rect()) def sizeHint(self): return QSize(640, 32) def timerEvent(self): if not self.started: self.thread.start() self.started = True if self.thread.updated: self.thread.updated = False self.update() def mousePressEvent(self, event): if event.button() != Qt.LeftButton: return frac = float(event.x()) / self.rect().width() offset = int(frac * self.width * self.block_size) self.view.navigateToFileOffset(offset)
def get_whole_scene_img(self): self.hide_proxies() img = QImage(self.sceneRect().width() / self.total_scale_div, self.sceneRect().height() / self.total_scale_div, QImage.Format_RGB32) img.fill(Qt.transparent) painter = QPainter(img) painter.setRenderHint(QPainter.Antialiasing) rect = QRectF() rect.setLeft(-self.viewport().pos().x()) rect.setTop(-self.viewport().pos().y()) rect.setWidth(img.rect().width()) rect.setHeight(img.rect().height()) # rect is right... but it only renders from the viewport's point down-and rightwards, not from topleft (0,0) ... self.render(painter, rect, rect.toRect()) self.show_proxies() return img
def mergeVisibleLayers(self): """ Merges the visible masked images and returns the resulting QImage, eventually scaled to fit the image size. @return: image @rtype: QImage """ # init a new image img = QImage(self.width(), self.height(), self.format()) # Image may contain transparent pixels, hence we # fill the image with a background color. img.fill(vImage.defaultBgColor) # draw layers with (eventually) masked areas. qp = QPainter(img) qp.drawImage(QRect(0, 0, self.width(), self.height()), self.layersStack[-1].getCurrentMaskedImage()) qp.end() return img
def as_image(self) -> QImage: self.rendered_base_x = 0 self.rendered_base_y = 0 image = QImage( QSize(self.rendered_width * Block.SIDE_LENGTH, self.rendered_height * Block.SIDE_LENGTH), QImage.Format_RGB888, ) bg_color = bg_color_for_object_set(self.object_set.number, 0) image.fill(bg_color) painter = QPainter(image) self.draw(painter, Block.SIDE_LENGTH, True) return image
def setBackgroundImage(self): img = QImage(QSize(256, 256), QImage.Format_ARGB32) img.fill(QColor(100, 100, 100)) a = np.arange(256) buf = np.meshgrid(a, a) buf1 = QImageBuffer(img)[:, :, :3][:, :, ::-1] buf1[:, :, 0], buf1[:, :, 1] = buf buf1[:, :, 2] = 1 buf2 = np.tensordot(buf1, self.invM, axes=(-1, -1)) * 255 np.clip(buf2, 0, 255, out=buf2) buf1[...] = buf2 qp = QPainter(img) qp.drawLine(self.R, self.G) qp.drawLine(self.G, self.B) qp.drawLine(self.B, self.R) b = (self.B + self.R + self.G) / 3.0 qp.drawLine(b - QPointF(10, 0), b + QPointF(10, 0)) qp.drawLine(b - QPointF(0, 10), b + QPointF(0, 10)) qp.end() self.scene().addItem(QGraphicsPixmapItem(QPixmap.fromImage(img)))
class Image(qrcode.image.base.BaseImage): def __init__(self, border, width, box_size): self.border = border self.width = width self.box_size = box_size size = (width + border * 2) * box_size self._image = QImage( size, size, QImage.Format_RGB16) self._image.fill(Qt.white) def pixmap(self): return QPixmap.fromImage(self._image) def drawrect(self, row, col): painter = QPainter(self._image) painter.fillRect( (col + self.border) * self.box_size, (row + self.border) * self.box_size, self.box_size, self.box_size, Qt.black)
def update_widgets(self, cam_id, camera_widget, camera_label): camera_data = self.images_received[cam_id] if cam_id in self.is_sensor_active.keys( ) and self.is_sensor_active[cam_id]: array = np.frombuffer(camera_data.image, dtype=np.dtype("uint8")) array = np.reshape(array, (camera_data.height, camera_data.width, 4)) qImg = QImage(array, array.shape[1], array.shape[0], array.strides[0], QImage.Format_ARGB32) else: qImg = QImage(camera_data.width, camera_data.height, QImage.Format_ARGB32) qImg.fill(qRgb(0, 0, 0)) pixmap = QPixmap(qImg) pixmap = pixmap.scaled(camera_widget.size(), Qt.KeepAspectRatio, Qt.SmoothTransformation) camera_widget.setPixmap(pixmap) camera_label.setText(self.pose_cameras_dict[cam_id]['name'])
def __init__(self, imageHandler: ImageHandler): self.imageHandler = imageHandler self._warned = False # Initialize caches. self.bitmaps = BitmapCache() self.brushes = BrushCache() self.palettes = PaletteCache() self.glyphs = GlyphCache() self.bounds = None screen = self.imageHandler.screen fallback = QImage(self.imageHandler.screen.width(), self.imageHandler.screen.height(), QImage.Format_ARGB32_Premultiplied) fallback.fill(0) self.surfaces = { SCREEN_BITMAP_SURFACE: screen, SUBSTITUTE_SURFACE: fallback, } self.activeSurface = SCREEN_BITMAP_SURFACE
def __init__(self, dc: QRemoteDesktop): self.dc = dc self._warned = False # Initialize caches. self.bitmaps = BitmapCache() self.brushes = BrushCache() self.palettes = PaletteCache() self.glyphs = GlyphCache() self.bounds = None screen = dc.screen fallback = QImage(dc.width(), dc.height(), QImage.Format_ARGB32_Premultiplied) fallback.fill(0) self.surfaces = { SCREEN_BITMAP_SURFACE: screen, SUBSTITUTE_SURFACE: fallback, } self.activeSurface = SCREEN_BITMAP_SURFACE
def copyGuide(self): # This isn't the most efficient way to do this but it just needs to be # reasonably fast self.drawable.clear(self.fgIndex, self.bgIndex, self.palette) guide_copy = QImage(self.screenSize, QImage.Format_RGBA8888) guide_copy.fill(QColor("white")) painter = QPainter(guide_copy) self._paintZoomedGuide(painter) shrunk_guide = guide_copy.smoothScaled(self.canvasSize.width(), self.canvasSize.height()) mono_guide = shrunk_guide.convertToFormat(QImage.Format_Mono) for x in range(0, self.canvasSize.width()): for y in range(0, self.canvasSize.height()): if mono_guide.pixel(x, y) == QColor("black"): self.drawable.setPixel(x, y, self.fgIndex, self.bgIndex, self.palette) painter.end() self.repaint()
class ImageLabel(QtWidgets.QLabel): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.setup_overlay() def resizeEvent(self, event): self.setup_overlay() def setup_overlay(self): size = None if self.pixmap(): size = QtCore.QSize(self.pixmap().width(), self.pixmap().height()) else: size = QtCore.QSize(self.size().width(), self.size().height()) self.setup_overlay_image(size) def setup_overlay_image(self, size): self.overlay_image = QImage(size, QImage.Format_ARGB32_Premultiplied) self.overlay_image.setDevicePixelRatio(self.devicePixelRatioF()) self.overlay_image.fill(QtGui.QColor(255, 0, 0, 128)) def paintEvent(self, event): if self.pixmap(): painter = QtGui.QPainter(self) self.drawFrame(painter) cr = self.contentsRect() painter.drawPixmap(cr, self.pixmap()) painter.drawImage(cr, self.overlay_image) if self.window().show_grid: Grid.draw(self, self.window().grid_spacing) else: super().paintEvent(event)
class Generator(object): def __init__(self): self.tileWidth = 16 self.tileHeight = 16 self.forcePot = False self.isTransparent = True self.bgColor = None self.reorder = False self.padding = 0 self._cols = 0 self._rows = 0 self._gridHeight = 0 self._gridWidth = 0 self._targetHeight = 0 self._targetWidth = 0 self._target = None def create(self, source): self._findSizes(source) self._createTargetImage() self._drawTiles(source) self._drawEdges() return self._target def _drawEdges(self): cols = int(self._targetWidth / self._gridWidth) rows = int(self._targetHeight / self._gridHeight) for offset in range(1, self.padding + 1): for j in range(rows): # horizontally (top) y = j * self._gridHeight + self.padding for x in range(self._targetWidth): self._target.setPixel(x, y - offset, self._target.pixel(x, y)) # horizontally (bottom) y = j * self._gridHeight + self.tileHeight + self.padding - 1 for x in range(self._targetWidth): self._target.setPixel(x, y + offset, self._target.pixel(x, y)) for offset in range(1, self.padding + 1): for j in range(cols): # vertically (left) x = j * self._gridWidth + self.padding for y in range(self._targetHeight): self._target.setPixel(x - offset, y, self._target.pixel(x, y)) # vertically (right) x = j * self._gridWidth + self.tileWidth + self.padding - 1 for y in range(self._targetHeight): self._target.setPixel(x + offset, y, self._target.pixel(x, y)) def _drawTiles(self, source): x = self.padding y = self.padding sx = 0 sy = 0 doReorder = self.forcePot & self.reorder painter = QPainter(self._target) for j in range(self._rows): for i in range(self._cols): painter.drawPixmap(x, y, source, sx, sy, self.tileWidth, self.tileHeight) x += self._gridWidth if doReorder and x >= self._targetWidth - self._gridWidth: x = self.padding y += self._gridHeight sx += self.tileWidth if not doReorder: x = self.padding y += self._gridHeight sx = 0 sy += self.tileHeight def _findSizes(self, source): self._cols = int(source.width() / self.tileWidth) self._rows = int(source.height() / self.tileHeight) self._gridWidth = self.tileWidth + self.padding * 2 self._gridHeight = self.tileHeight + self.padding * 2 self._targetWidth = self._cols * self._gridWidth self._targetHeight = self._rows * self._gridHeight if not self.forcePot: return self._targetHeight, self._targetWidth size = 1 widthOk = False heightOk = False for i in range(1, 31): if not widthOk and self._targetWidth < size: self._targetWidth = size widthOk = True if not heightOk and self._targetHeight < size: self._targetHeight = size heightOk = True if widthOk and heightOk: break size *= 2 return self._targetHeight, self._targetWidth def _createTargetImage(self): self._target = QImage(self._targetWidth, self._targetHeight, QImage.Format_ARGB32) if self.isTransparent: self._target.fill(Qt.transparent) else: self._target.fill(self.bgColor)
class View(QWidget): previous = Signal() next = Signal() def __init__(self, window): super(View, self).__init__(window) self.setFocusPolicy(Qt.StrongFocus) self.shiftKey = False self.ctrlKey = False self.lastMousePos = QPoint() self.lastTabletPos = QPoint() self.mode = 'add' self.maskOnly = False self.refresh = QTimer(self) self.refresh.setSingleShot(True) self.refresh.timeout.connect(self.repaint) self.addCursor = makeCursor('images/cursor-add.png', QColor.fromRgbF(0.5, 0.5, 1.0)) self.delCursor = makeCursor('images/cursor-del.png', QColor.fromRgbF(1.0, 0.5, 0.5)) self.setCursor(self.addCursor) self.imagefile = None self.maskfile = None self.image = QImage() self.mask = QImage(self.image.size(), QImage.Format_RGB32) self.mask.fill(Qt.black) self.changed = False self.update() self.path = list() self.load_threads = QThreadPool() self.load_threads.setMaxThreadCount(4) def load(self, filename): self.load_threads.start(LoadTask(self, filename)) def save(self): if self.maskfile and self.changed: self.load_threads.waitForDone() if self.maskfile and self.changed: bitmap = self.mask.createMaskFromColor( QColor.fromRgbF(1.0, 0.0, 1.0).rgb()) bitmap.save(str(self.maskfile), "PNG") self.changed = False def update(self): widgetRatio = self.width() / self.height() aspectRatio = self.image.width() / max(1, self.image.height()) if aspectRatio >= widgetRatio: width = self.width() height = self.width() / aspectRatio else: width = self.height() * aspectRatio height = self.height() self.rc = QRectF((self.width() - width) / 2.0, (self.height() - height) / 2.0, width, height) self.repaint() def resizeEvent(self, event): self.update() def paintEvent(self, event): p = QPainter(self.mask) for (mode, p1, p2, weight) in self.path: if mode == 'add': p.setPen( QPen(QColor.fromRgbF(1.0, 0.0, 1.0), (weight * 10.0)**2, Qt.SolidLine, Qt.RoundCap, Qt.RoundJoin)) else: p.setPen( QPen(QColor.fromRgbF(0.0, 0.0, 0.0), (weight * 10.0)**2, Qt.SolidLine, Qt.RoundCap, Qt.RoundJoin)) p.drawLine(realCoords(p1, self.mask.rect()), realCoords(p2, self.mask.rect())) self.changed = True self.path = list() p.end() p = QPainter(self) p.setCompositionMode(QPainter.CompositionMode_SourceOver) if not self.maskOnly: p.drawImage(self.rc, self.image) p.setCompositionMode(QPainter.CompositionMode_Plus) p.drawImage(self.rc, self.mask) p.end() def closeEvent(self, event): self.refresh.stop() event.accept() def enterEvent(self, event): self.setFocus(Qt.OtherFocusReason) def keyPressEvent(self, event): k = event.key() if k == Qt.Key_Shift: self.shiftKey = True if k == Qt.Key_Control: self.ctrlKey = True if k == Qt.Key_Space: self.maskOnly = not self.maskOnly self.repaint() def keyReleaseEvent(self, event): k = event.key() mod = event.modifiers() if k == Qt.Key_Shift: self.shiftKey = False if k == Qt.Key_Control: self.ctrlKey = False def mousePressEvent(self, event): x = event.x() y = event.y() self.lastMousePos = event.pos() if event.button() == Qt.ExtraButton1: if self.mode == 'add': self.mode = 'del' self.setCursor(self.delCursor) else: self.mode = 'add' self.setCursor(self.addCursor) elif event.button() == Qt.ExtraButton2: self.maskOnly = not self.maskOnly self.repaint() elif event.button() == Qt.ExtraButton3: self.previous.emit() elif event.button() == Qt.ExtraButton4: self.next.emit() def mouseMoveEvent(self, event): x = event.x() y = event.y() dx = x - self.lastMousePos.x() dy = y - self.lastMousePos.y() self.lastMousePos = event.pos() # if event.buttons() & Qt.LeftButton: # elif event.buttons() & Qt.MiddleButton: # elif event.buttons() & Qt.RightButton: def wheelEvent(self, event): dx = event.angleDelta().x() / 8 dy = event.angleDelta().y() / 8 # self.cameraZoom.emit(dy / 15) def tabletEvent(self, event): if event.device() == QTabletEvent.Stylus and event.pointerType( ) == QTabletEvent.Pen: if event.type() == QEvent.TabletPress: self.tabletPressEvent(event) elif event.type() == QEvent.TabletRelease: self.tabletReleaseEvent(event) elif event.type() == QEvent.TabletMove: if event.pressure() > 0.0: self.tabletMoveEvent(event) else: print('tabletEvent', event.device(), event.type(), event.pointerType()) else: print('tabletEvent', event.device(), event.type(), event.pointerType()) def tabletPressEvent(self, event): if event.buttons() & Qt.LeftButton: self.lastTabletPos = normalizeCoords(event.posF(), self.rc) if event.buttons() & Qt.MiddleButton: if self.mode == 'add': self.mode = 'del' self.setCursor(self.delCursor) else: self.mode = 'add' self.setCursor(self.addCursor) if event.buttons() & Qt.RightButton: self.next.emit() def tabletReleaseEvent(self, event): self.lastTabletPos = normalizeCoords(event.posF(), self.rc) def tabletMoveEvent(self, event): self.path.append((self.mode, self.lastTabletPos, normalizeCoords(event.posF(), self.rc), event.pressure())) self.lastTabletPos = normalizeCoords(event.posF(), self.rc) if not self.refresh.isActive(): self.refresh.start(50)
class ScribbleArea(QWidget): def __init__(self, parent=None): super(ScribbleArea, self).__init__(parent) self.myPenColors = [ QColor("green"), QColor("purple"), QColor("red"), QColor("blue"), QColor("yellow"), QColor("pink"), QColor("orange"), QColor("brown"), QColor("grey"), QColor("black") ] self.setAttribute(Qt.WA_AcceptTouchEvents) self.setAttribute(Qt.WA_StaticContents) self.image = QImage() self.modified = False def s_print(self): pass def clearImage(self): self.image.fill(qRgb(255, 255, 255)) self.modified = True self.update() def openImage(self, fileName): loadedImage = QImage() if not loadedImage.load(fileName): return False newSize = loadedImage.size().expandedTo(self.size()) self.resizeImage(loadedImage, newSize) self.image = loadedImage self.modified = False self.update() return True def saveImage(self, fileName, fileFormat): visibleImage = self.image.copy() self.resizeImage(visibleImage, self.size()) if visibleImage.save(fileName, fileFormat): self.modified = False return True else: return False def paintEvent(self, event): painter = QPainter(self) rect = event.rect() painter.drawImage(rect.topLeft(), self.image, rect) def resizeEvent(self, event): if self.width() > self.image.width() or self.height( ) > self.image.height(): newWidth = max(self.width() + 128, self.image.width()) newHeight = max(self.height() + 128, self.image.height()) self.resizeImage(self.image, QSize(newWidth, newHeight)) self.update() super(ScribbleArea, self).resizeEvent(event) def resizeImage(self, image, newSize): if self.image.size() == newSize: return newImage = QImage(newSize, QImage.Format_RGB32) newImage.fill(qRgb(255, 255, 255)) painter = QPainter(newImage) painter.drawImage(QPoint(0, 0), self.image) self.image = newImage # # def print(self, ) # { # #ifndef QT_NO_PRINTER: # QPrinter printer(QPrinter.HighResolution) # # QPrintDialog *printDialog = new QPrintDialog(&printer, this) # if (printDialog.exec() == QDialog.Accepted) { # QPainter painter(&printer) # QRect rect = painter.viewport() # QSize size = self.image.size() # size.scale(rect.size(), Qt.KeepAspectRatio) # painter.setViewport(rect.x(), rect.y(), size.width(), size.height()) # painter.setWindow(self.image.rect()) # painter.drawImage(0, 0, image) # } # #endif // QT_NO_PRINTER # } # def event(self, event): if event.type() == QEvent.TouchBegin or event.type( ) == QEvent.TouchUpdate or event.type() == QEvent.TouchEnd: touchPoints = event.touchPoints() for touchPoint in touchPoints: if touchPoint.state() == Qt.TouchPointStationary: continue else: rect = touchPoint.rect() if rect.isEmpty(): diameter = 50 * touchPoint.pressure() rect.setSize(QSizeF(diameter, diameter)) painter = QPainter(self.image) painter.setPen(Qt.NoPen) painter.setBrush(self.myPenColors[touchPoint.id() % len(self.myPenColors)]) painter.drawEllipse(rect) painter.end() self.modified = True rad = 2 self.update(rect.toRect().adjusted(-rad, -rad, +rad, +rad)) else: return super(ScribbleArea, self).event(event) return True