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 openFile(self, filepath=False): if not filepath: filefilter = "Image files (*.jpg *.png *.jpeg *.svg *.gif *.tiff *.ppm *.bmp);;JPEG Images (*.jpg *.jpeg);;PNG Images (*.png);;SVG Images (*.svg);;All Files (*)" filepath, sel_filter = QFileDialog.getOpenFileName( self, 'Open Image', self.filepath, filefilter) if filepath == '': return image_reader = QImageReader(filepath) if image_reader.format() == 'gif': # For gif animations anim = QMovie(filepath) self.image.setAnimation(anim) self.adjustWindowSize(True) self.statusbar.showMessage( "Resolution : %ix%i" % (self.image.width(), self.image.height())) self.disableButtons(True) else: # For static images image_reader.setAutoTransform(True) pm = QPixmap.fromImageReader(image_reader) if not pm.isNull(): self.image.scale = self.getOptimumScale(pm) self.image.setImage(pm) self.adjustWindowSize() self.disableButtons(False) else: return self.filepath = filepath self.setWindowTitle(QFileInfo(filepath).fileName())
def readImageFromFile(fileName): reader = QImageReader(fileName) reader.setAutoTransform(True) reader.setAutoDetectImageFormat(True) image = reader.read() if not image: raise CannotReadImageException() return image
def loadImageFile(fname): reader = QImageReader(fname) reader.setAutoTransform(True) newImage = reader.read() if newImage.isNull(): msg = ("couldnt load " + QFileInfo(fname).fileName() + ": " + reader.errorString()) sb_txt.setText(msg) return False else: return newImage
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 addPhoto(self): filefilter = "JPEG Images (*.jpg *jpeg);;PNG Images (*.png);;All Files (*)" filepath, sel_filter = QFileDialog.getOpenFileName(self, 'Open Image', '', filefilter) if filepath == '' : return image_reader = QImageReader(filepath) image_reader.setAutoTransform(True) pm = QPixmap.fromImageReader(image_reader) if not pm.isNull() : thumbnail = Thumbnail(pm, self.frame) self.verticalLayout.addWidget(thumbnail) thumbnail.clicked.connect(self.gridPaper.setPhoto) self.thumbnailGr.append(thumbnail)
def savePascalVocFormat(self, filename, shapes, imagePath, imageData, lineColor=None, fillColor=None, databaseSrc=None): imgFolderPath = os.path.dirname(imagePath) imgFolderName = os.path.split(imgFolderPath)[-1] imgFileName = os.path.basename(imagePath) #imgFileNameWithoutExt = os.path.splitext(imgFileName)[0] # Read from file path because self.imageData might be empty if saving to # Pascal format reader0 = QImageReader(imagePath) reader0.setAutoTransform(True) image = reader0.read() imageShape = [ image.height(), image.width(), 1 if image.isGrayscale() else 3 ] writer = PascalVocWriter(imgFolderName, imgFileName, imageShape, localImgPath=imagePath) writer.verified = self.verified for shape in shapes: points = shape['points'] label = shape['label'] # Add Chris difficult = int(shape['difficult']) direction = shape['direction'] isRotated = shape['isRotated'] extra_text = shape['extra_text'] if not isRotated: bndbox = LabelFile.convertPoints2BndBox(points) writer.addBndBox(bndbox[0], bndbox[1], bndbox[2], bndbox[3], label, difficult, extra_text) else: #if shape is rotated box, save as rotated bounding box robndbox = LabelFile.convertPoints2RotatedBndBox(shape) writer.addRotatedBndBox(robndbox[0], robndbox[1], robndbox[2], robndbox[3], robndbox[4], label, difficult, extra_text) writer.save(targetFile=filename) return
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 onOpenFileAction(self): fileList = QFileDialog.getOpenFileNames(self, 'open', self.workPath, 'Images(*.jpg *.jpeg *.png *.bmp);;All file(*.*)')# type:list[str] if len(fileList)<=0 or len(fileList[0])<=0: return reader = QImageReader(fileList[0][0]) reader.setAutoTransform(True) img = reader.read() if img.isNull(): QMessageBox.information(self, 'error', 'can not open %s as image!'%fileList[0][0], QMessageBox.Ok) return self.opendFile = fileList[0][0] self.__setImage(img, self.zoomList[self.zoomIdx]) if len(fileList[0])>=2: reader1 =QImageReader(fileList[0][1]) reader1.setAutoTransform(True) img1 = reader1.read() if img1.isNull(): QMessageBox.information(self, 'error', 'can not open %s as image!'%fileList[0][0], QMessageBox.Ok) return self.__setImage1(img1, self.zoomList[self.zoomIdx]) self.opendFile1 = fileList[0][1] self.__setTitle()
def load_cr3(path) -> QPixmap: """Extract the thumbnail from the image and initialize QPixmap""" process = QProcess() process.start(f"exiftool -b -JpgFromRaw {path}") process.waitForFinished() if process.exitStatus() != QProcess.NormalExit or process.exitCode() != 0: stderr = process.readAllStandardError() raise ValueError(f"Error calling exiftool: '{stderr.data().decode()}'") handler = QImageReader(process, "jpeg".encode()) handler.setAutoTransform(True) process.closeWriteChannel() process.terminate() # Extract QImage from QImageReader and convert to QPixmap pixmap = QPixmap() pixmap.convertFromImage(handler.read()) return 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
def load_frame(path) -> QPixmap: """Extract the first frame from the video and initialize QPixmap""" process = QProcess() process.start( f"ffmpeg -loglevel quiet -i {path} -vframes 1 -f image2 pipe:1") process.waitForFinished() if process.exitStatus() != QProcess.NormalExit or process.exitCode() != 0: stderr = process.readAllStandardError() raise ValueError(f"Error calling ffmpeg: '{stderr.data().decode()}'") handler = QImageReader(process, "jpeg".encode()) handler.setAutoTransform(True) process.closeWriteChannel() process.terminate() # Extract QImage from QImageReader and convert to QPixmap pixmap = QPixmap() pixmap.convertFromImage(handler.read()) return pixmap
def dropEvent(self, event:QDropEvent): mainWidget_rect = self.mainWidget.geometry() dropPt = event.pos() if dropPt.x()<mainWidget_rect.left() or dropPt.x()>mainWidget_rect.right() or dropPt.y()<mainWidget_rect.top() or dropPt.y()>mainWidget_rect.bottom(): return mData = event.mimeData() if not mData.hasUrls(): return urlList = mData.urls() if len(urlList)==1: scrollArea_rect = self.scrollArea.geometry().translated(mainWidget_rect.topLeft()) scrollArea1_rect = self.scrollArea1.geometry().translated(mainWidget_rect.topLeft()) if dropPt.x()>scrollArea_rect.left() and dropPt.x()<scrollArea_rect.right(): fileName = urlList[0].toLocalFile() if len(fileName)<=0 or fileName==None: return if fileName.endswith(('.jpg', '.JPG', '.jpeg', '.JPEG', '.png', '.PNG', '.bmp', '.BMP')): reader = QImageReader(fileName) reader.setAutoTransform(True) img = reader.read() if img.isNull(): QMessageBox.information(self, 'error', 'can not open %s as image!'%fileName, QMessageBox.Ok) return self.opendFile = fileName self.__setTitle() self.__setImage(img, self.zoomList[self.zoomIdx]) elif dropPt.x()>scrollArea1_rect.left() and dropPt.x()<scrollArea1_rect.right(): fileName = urlList[0].toLocalFile() if len(fileName)<=0 or fileName==None: return if fileName.endswith(('.jpg', '.JPG', '.jpeg', '.JPEG', '.png', '.PNG', '.bmp', '.BMP')): reader = QImageReader(fileName) reader.setAutoTransform(True) img = reader.read() if img.isNull(): QMessageBox.information(self, 'error', 'can not open %s as image!'%fileName, QMessageBox.Ok) return self.opendFile1 = fileName self.__setTitle() self.__setImage1(img, self.zoomList[self.zoomIdx]) else: pass elif len(urlList)>=2: fileName = urlList[0].toLocalFile() fileName1 = urlList[1].toLocalFile() if len(fileName)<=0 or fileName==None or len(fileName1)<=0 or fileName1==None: return if fileName.endswith(('.jpg', '.JPG', '.jpeg', '.JPEG', '.png', '.PNG', '.bmp', '.BMP')) and fileName1.endswith(('.jpg', '.JPG', '.jpeg', '.JPEG', '.png', '.PNG', '.bmp', '.BMP')): reader = QImageReader(fileName) reader.setAutoTransform(True) img = reader.read() reader1 = QImageReader(fileName1) reader1.setAutoTransform(True) img1 = reader1.read() if img.isNull() or img1.isNull(): QMessageBox.information(self, 'error', 'can not open %s %sas image!'%(fileName, fileName1), QMessageBox.Ok) return self.opendFile = fileName self.opendFile1 = fileName1 self.__setTitle() self.__setImage(img, self.zoomList[self.zoomIdx]) self.__setImage1(img1, self.zoomList[self.zoomIdx]) else: pass
def readImage(self, filename): image_reader = QImageReader(filename) image_reader.setAutoTransform(True) return image_reader.read()
def _reader(self): """Return a QImageReader for the source.""" reader = QImageReader(self.source) reader.setAutoTransform(self.autoTransform) return reader
def loadFile(self, filename=None): ''' 根据文件名加载文件 并在canvas中显示 ''' if not filename: return # 如果该文件已经被加载 则直接返回 if filename in self.imageList and self.listWidget_files.currentRow( ) != self.imageList.index(filename): self.listWidget_files.setCurrentRow(self.imageList.index(filename)) self.listWidget_files.repaint() return self.statusbar.showMessage('opening {}'.format(filename)) self.resetState() self.canvas.setEnabled(False) # 使用QIamgeReader读取图像 reader = QImageReader(filename) reader.setAutoTransform(True) image = reader.read() if image.isNull(): self.statusbar.showMessage('Error loading {}'.format(filename)) return # 假设该图像已经被标记 # 那么应该存在同名 Json 文件 label_file = os.path.splitext(filename)[0] + '.json' # 如果存在同名 Json文件 # TODO: 进行 Json 合法性检查 这里直接忽略了 if QFile.exists(label_file): # 从 Json 文件中提取标注区域信息 shapes = loadJsonFile(label_file) # 交给 canvas 类处理 self.canvas.retrieveAndLoadShape(shapes) # 更新右侧的label列表 # labels 记录所有的标注信息 # Python Set 用于去重 labels = list(shape.label for shape in self.canvas.shapes) for label in set(labels): self.listWidget_labels.addItem(label) # 更新 itemToShapes 字典 for shape in self.canvas.shapes: self.itemToShapes[shape.label] = \ self.itemToShapes.get(shape.label, []) + [shape] self.image = image self.filename = filename self.canvas.scale = self.computeScale(image) self.spinbox_scale.setValue(int(self.canvas.scale * 100)) self.canvas.loadPixmap(QPixmap.fromImage(image)) self.canvas.setEnabled(True) self.statusbar.showMessage('{}'.format(filename)) self.setClean() self.actionCreate_Polygons.setEnabled(True) self.actionCreate_Rectangle.setEnabled(True) self.actionCreate_Circle.setEnabled(True)