class QtReader(BaseReader): """Image reader using Qt's QImageReader implementation under the hood.""" def __init__(self, path: str, file_format: str): super().__init__(path, file_format) self._handler = QImageReader(path, file_format.encode()) self._handler.setAutoTransform(True) if not self._handler.canRead(): # TODO raise ValueError(f"'{path}' cannot be read as image") @classmethod def supports(cls, file_format: str) -> bool: return file_format in QImageReader.supportedImageFormats() @property def is_animation(self) -> bool: return self._handler.supportsAnimation() def get_pixmap(self) -> QPixmap: """Retrieve the pixmap directly from the image reader.""" pixmap = QPixmap.fromImageReader(self._handler) if self._handler.error(): raise ValueError( f"Error reading image '{self.path}': {self._handler.errorString()}" ) return pixmap def get_image(self, size: int) -> QImage: """Retrieve the down-scaled image directly from the image reader.""" qsize = self._handler.size() qsize.scale(size, size, Qt.KeepAspectRatio) self._handler.setScaledSize(qsize) return self._handler.read()
def sourceFile(self, value): self._sourceFile = value p = QImageReader(self._sourceFile) if (p.canRead()): p.setAutoTransform(True) self._image = p.read() self._transform = QTransform() print("loaded image "+value) else: self._image = None self.changed.emit()
def _can_write(self): """Check if it is possible to save the current path. Raises: WriteError if writing is not possible. """ if not isinstance(self._pixmap, QPixmap): raise WriteError("Cannot write animations") if os.path.exists(self._path): # Override current path reader = QImageReader(self._path) if not reader.canRead(): raise WriteError("Path '%s' exists and is not an image" % (self._path))
def __display_result_image(self, file_path): image_reader = QImageReader(file_path) if image_reader.canRead() is True: widget_height = self.resultView.height() widget_width = self.resultView.width() image = image_reader.read().scaled(widget_width, widget_height, Qt.KeepAspectRatio) item = QGraphicsPixmapItem(QPixmap.fromImage(image)) scene = QGraphicsScene() scene.addItem(item) self.resultView.setScene(scene) else: scene = QGraphicsScene() self.resultView.setScene(scene)
def _can_write(pixmap, path): """Check if it is possible to save the current path. See write_pixmap for the args description. Raises: WriteError if writing is not possible. """ if not isinstance(pixmap, QPixmap): raise WriteError("Cannot write animations") if os.path.exists(path): # Override current path reader = QImageReader(path) if not reader.canRead(): raise WriteError(f"Path '{path}' exists and is not an image")
def __changed_image_line_edit(self): file_path = self.lineEdit_image.text() image_reader = QImageReader(file_path) if image_reader.canRead() is True: widget_height = self.queryView.height() widget_width = self.queryView.width() image = image_reader.read().scaled(widget_width, widget_height, Qt.KeepAspectRatio) item = QGraphicsPixmapItem(QPixmap.fromImage(image)) scene = QGraphicsScene() scene.addItem(item) self.queryView.setScene(scene) else: scene = QGraphicsScene() self.queryView.setScene(scene)
def load_image_data(self) -> QImage: """ Loads the image data from disk. This has to be called when the file content needs to be accessed. :return: """ logger.debug( f"Requested loading image data from the hard disk. File: {self.image_path}" ) image_reader = QImageReader(str(self.image_path)) if image_reader.canRead(): logger.debug("Image data can be read, performing file reading…") self.image_data = image_reader.read() logger.info( f"File reading done. Loaded image dimensions: " f"x={self.image_data.width()}, y={self.image_data.height()}, format={self.image_data.format()}" ) return self.image_data else: raise RuntimeError(f"Image {self.image_path} cannot be read.")
def _load(self, path: str, reload_only: bool): """Load proper displayable QWidget for a path. This reads the image using QImageReader and then emits the appropriate *_loaded signal to tell the image to display a new object. """ # Pass file format explicitly as imghdr does a much better job at this than the # file name based approach of QImageReader file_format = files.imghdr.what(path) if file_format is None: log.error("%s is not a valid image", path) return reader = QImageReader(path, file_format.encode("utf-8")) reader.setAutoTransform(True) # Automatically apply exif orientation if not reader.canRead(): log.error("Cannot read image %s", path) return # SVG if file_format == "svg" and QSvgWidget: # Do not store image and only emit with the path as the # VectorGraphic widget needs the path in the constructor self.original = None api.signals.svg_loaded.emit(path, reload_only) self._image_type = ImageType.Svg # Gif elif reader.supportsAnimation(): movie = QMovie(path) if not movie.isValid() or movie.frameCount() == 0: log.error("Error reading animation %s: invalid data", path) return self.original = movie api.signals.movie_loaded.emit(self.current, reload_only) self._image_type = ImageType.Movie # Regular image else: pixmap = QPixmap.fromImageReader(reader) if reader.error(): log.error("Error reading image %s: %s", path, reader.errorString()) return self.original = pixmap api.signals.pixmap_loaded.emit(self.current, reload_only) self._image_type = ImageType.Pixmap self._path = path
def dropEvent(self, event): # # 方法一:针对小图片 # pixmap = QPixmap(event.mimeData().urls()[0].toLocalFile()) # self.ui.LabPic.setPixmap(pixmap) # # # 方法二:小图片和PNG格式的大图片 # img = QImage() # print(event.mimeData().urls()[0].toLocalFile()) # img.load(event.mimeData().urls()[0].toLocalFile()) # pixmap = QPixmap.fromImage(img.scaled(self.ui.LabPic.size(), Qt.KeepAspectRatio)) # self.ui.LabPic.setPixmap(pixmap) # 方法三:小图片和大图片 reader = QImageReader() print(event.mimeData().urls()[0].toLocalFile()) reader.setFileName(event.mimeData().urls()[0].toLocalFile()) reader.setDecideFormatFromContent(True) if reader.canRead(): img = QImage(reader.read()) pixmap = QPixmap.fromImage( img.scaled(self.ui.LabPic.size(), Qt.KeepAspectRatio)) self.ui.LabPic.setPixmap(pixmap)
def _create_thumbnail(self, path: str, thumbnail_path: str) -> QPixmap: """Create thumbnail for an image. Args: path: Path to the image for which the thumbnail is created. thumbnail_path: Path to which the thumbnail is stored. Returns: The created QPixmap. """ # Cannot access source if not os.access(path, os.R_OK): return self._manager.fail_pixmap size = 256 if self._manager.large else 128 reader = QImageReader(path) reader.setAutoTransform(True) # Automatically apply exif orientation if reader.canRead(): qsize = reader.size() qsize.scale(size, size, Qt.KeepAspectRatio) reader.setScaledSize(qsize) image = reader.read() # Image was deleted in the time between reader.read() and now try: attributes = self._get_thumbnail_attributes(path, image) except FileNotFoundError: return self._manager.fail_pixmap for key, value in attributes.items(): image.setText(key, value) # First create temporary file and then move it. This avoids # problems with concurrent access of the thumbnail cache, since # "move" is an atomic operation handle, tmp_filename = tempfile.mkstemp( dir=self._manager.directory) os.close(handle) os.chmod(tmp_filename, 0o600) image.save(tmp_filename, format="png") os.replace(tmp_filename, thumbnail_path) return QPixmap(image) return self._manager.fail_pixmap