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()
Exemple #2
0
 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())
Exemple #3
0
def readImageFromFile(fileName):
    reader = QImageReader(fileName)
    reader.setAutoTransform(True)
    reader.setAutoDetectImageFormat(True)

    image = reader.read()
    if not image:
        raise CannotReadImageException()

    return image
Exemple #4
0
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
Exemple #5
0
 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()
Exemple #6
0
 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)
Exemple #7
0
    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
Exemple #8
0
    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()
Exemple #10
0
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
Exemple #11
0
    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
Exemple #12
0
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
Exemple #14
0
 def readImage(self, filename):
     image_reader = QImageReader(filename)
     image_reader.setAutoTransform(True)
     return image_reader.read()
Exemple #15
0
 def _reader(self):
     """Return a QImageReader for the source."""
     reader = QImageReader(self.source)
     reader.setAutoTransform(self.autoTransform)
     return reader
Exemple #16
0
    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)