コード例 #1
0
    def __init__(self, original_path, duplicate_path, parent):
        super(ImageCompare, self).__init__(parent)
        layout = QHBoxLayout()
        img1 = QVBoxLayout()
        img2 = QVBoxLayout()
        self.setWindowFlag(Qt.WindowContextHelpButtonHint, False)

        self.setWindowTitle('Image Compare')

        original_label = QLabel('Original Image')
        original_label.setAlignment(Qt.AlignCenter)
        original = QLabel('Original Image')
        original.setAlignment(Qt.AlignCenter)
        pixel1 = QPixmap(QImageReader(original_path).read())
        original.setPixmap(pixel1.scaled(500, 1000, Qt.KeepAspectRatio))
        img1.addWidget(original_label)
        img1.addWidget(original)

        duplicate_label = QLabel('Duplicate Image')
        duplicate_label.setAlignment(Qt.AlignCenter)
        duplicate = QLabel('Duplicate Image')
        duplicate.setAlignment(Qt.AlignCenter)
        pixel2 = QPixmap(QImageReader(duplicate_path).read())
        duplicate.setPixmap(pixel2.scaled(500, 1000, Qt.KeepAspectRatio))
        img2.addWidget(duplicate_label)
        img2.addWidget(duplicate)

        layout.addLayout(img1)
        layout.addLayout(img2)

        self.setLayout(layout)
        self.show()
コード例 #2
0
ファイル: main.py プロジェクト: zv100558snv/pypicview
 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())
コード例 #3
0
    def __init__(self, file_path, make_opengl_textures=True):
        image_reader = QImageReader(file_path)
        self.is_animated = image_reader.supportsAnimation()
        if self.is_animated:
            self.num_frames = image_reader.imageCount()
            # -1 means loop infinitely, 0 means no loop, > 0 is finite # of loops
            self.loop_count = image_reader.loopCount()
            self.loops_remaining = 0
            self.frames = []
            self.delays = []
            while image_reader.currentImageNumber() < image_reader.imageCount() - 1:
                self.frames.append(image_reader.read())
                self.delays.append(image_reader.nextImageDelay())

            if make_opengl_textures:
                self.open_gl_textures = [QOpenGLTexture(this_frame.mirrored()) for this_frame in self.frames]
                self.made_opengl_textures = True

            self.frames_and_delays = zip(self.frames, self.delays)

            self.current_frame = 0
            self.animating = False
        else:
            self.image = image_reader.read()
            assert isinstance(self.image, QImage)
            if make_opengl_textures:
                self.open_gl_texture = QOpenGLTexture(self.image.mirrored())
                self.made_opengl_textures = True
コード例 #4
0
    def __init__(self, parent, files: [], dest_album: AlbumData):
        super().__init__(parent)
        self.setWindowFlag(Qt.WindowCloseButtonHint, False)
        self.setWindowFlag(Qt.WindowContextHelpButtonHint, False)
        self.setWindowTitle('Album Content Importer')
        self.setWindowIcon(QIcon(QPixmap(QImageReader('assets/importAlbumContent.png').read())))

        # Layout setup
        layout = QVBoxLayout()
        layout.addWidget(QLabel('Importing new files...'))
        self.progress = QProgressBar()
        self.progress.setValue(0)
        self.progress.setFormat('Waiting (%p%)')
        layout.addWidget(self.progress)
        self.current_file = QLabel('Waiting...')
        layout.addWidget(self.current_file)
        layout.addStretch()

        # Init thread
        self.progress_signal.connect(self.update_progress)
        self.thread_pool = QThreadPool()
        self.thread_worker = Worker(self.run)
        self.thread_worker.signals.progress.connect(self.progress_signal)
        self.thread_worker.signals.finished.connect(self.update_after_completion)

        self.files = files
        self.dest_album = dest_album

        self.setLayout(layout)
        self.setFixedSize(300, 80)
        self.thread_pool.start(self.thread_worker)
        self.exec()
コード例 #5
0
 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")
    def replaceImage(self, filepath, title):
        self.title = title
        self.filepath = filepath

        # set custom properties
        self.setCustomProperty("title", title)
        self.setCustomProperty("filepath", self.filepath)
        self.setName(title)

        fileInfo = QFileInfo(filepath)
        ext = fileInfo.suffix()
        if ext == "pdf":
            s = QSettings()
            oldValidation = s.value("/Projections/defaultBehavior")
            s.setValue(
                "/Projections/defaultBehavior", "useGlobal"
            )  # for not asking about crs
            path = fileInfo.filePath()
            baseName = fileInfo.baseName()
            layer = QgsRasterLayer(path, baseName)
            self.image = layer.previewAsImage(QSize(layer.width(), layer.height()))
            s.setValue("/Projections/defaultBehavior", oldValidation)
        else:
            reader = QImageReader(filepath)
            self.image = reader.read()
        self.repaint()
コード例 #7
0
def _loadQtImage(path: str) -> QImage:
    reader = QImageReader(path)
    image = QImage(reader.read())
    if not image.isNull():
        return image
    else:
        return None
コード例 #8
0
    def run(self):

        self.sock.bind(('', configs['live']['port']))
        self.sock.settimeout(1)

        print('LiveClient bind in ', self.sock.getsockname())

        while not self.stop_run:

            while self.wait_recv:
                try:
                    receive_data = self.sock.recv(1024 * 100)  # , address
                    self.wait_recv = False
                except:
                    pass
            self.wait_recv = True

            if self.stop_run:
                break

            receive_data = zlib.decompress(receive_data)

            byte_array = QByteArray(receive_data)
            buffer = QBuffer(byte_array)
            buffer.open(QIODevice.ReadOnly)
            # 读取图片
            reader = QImageReader(buffer)
            q_img = reader.read()
            if self.stop_run:
                break
            self._screen.emit(q_img)

        self.sock.close()  # 关闭套接字
コード例 #9
0
    def load(self, source):
        """Load anything that QImageReader or QMovie constructors accept"""

        # Use QImageReader to identify animated GIFs for separate handling
        # (Thanks to https://stackoverflow.com/a/20674469/435253 for this)
        image_reader = QImageReader(source)
        from PyQt5.QtGui import QImageIOHandler
        if image_reader.supportsAnimation() and image_reader.imageCount() > 1:
            movie = QMovie(source)

            # Calculate the aspect ratio and adjust the widget size
            movie.jumpToFrame(0)
            movie_size = movie.currentImage().size()
            self.movie_aspect = movie_size.width() / movie_size.height()
            self.resizeEvent()

            self.label.setMovie(movie)
            movie.start()

            # Free memory if the previous image was non-animated
            self.orig_pixmap = None
        else:
            self.orig_pixmap = QPixmap(image_reader.read())
            self.label.setPixmap(self.orig_pixmap)

            # Fail quickly if our violated invariants result in stale
            # aspect-ratio information getting reused
            self.movie_aspect = None

        # Keep the image from preventing downscaling
        self.setMinimumSize(1, 1)
コード例 #10
0
ファイル: extension.py プロジェクト: eliheuer/simplefont
 def get(self, name, ext='*'):
     for file in os.listdir(self._path):
         if ext == '*' or file.endswith(ext):
             imageReader = QImageReader(file)
             if imageReader:
                 return QPixmap.fromImageReader(imageReader)
             return os.path.join(self._path, file)
     return None
コード例 #11
0
ファイル: img.py プロジェクト: tletnes/calibre
def image_and_format_from_data(data):
    ' Create an image object from the specified data which should be a bytestring and also return the format of the image '
    ba = QByteArray(data)
    buf = QBuffer(ba)
    buf.open(QBuffer.ReadOnly)
    r = QImageReader(buf)
    fmt = bytes(r.format()).decode('utf-8')
    return r.read(), fmt
コード例 #12
0
ファイル: qiconloader.py プロジェクト: erkanisik1/pds
    def findIconHelper(self, size=int, themeName=str, iconName=str):
        pixmap = QPixmap()

        if iconName == '' or self.themeName == '':
            return pixmap

        if themeName == '':
            themeName = self.themeName

        if themeName == self.themeName:
            index = self.themeIndex
        else:
            index = self.readThemeIndex(themeName)

        subDirs = filter(lambda x: x[0] == str(size), index.dirList)

        for iconDir in self.iconDirs:
            if path.exists(path.join(iconDir, themeName)):
                for theme in subDirs:
                    fileName = path.join(iconDir, themeName, theme[1],
                                         '%s.png' % str(iconName))
                    fileName_svg = path.join(iconDir, themeName, theme[1],
                                             '%s.svg' % str(iconName))
                    logging.debug('Looking for : %s' % fileName)
                    if path.exists(fileName):
                        pixmap.load(fileName)
                        logging.debug('Icon: %s found in theme %s' % \
                                (iconName, themeName))
                        return pixmap
                    elif path.exists(fileName_svg):
                        pixmap.load(fileName_svg)
                        logging.debug('Icon: %s found in %s' %
                                      (iconName, iconDir))
                        return pixmap

        for iconDir in self.extraIcons:
            fileName = path.join(iconDir, '%s.png' % str(iconName))
            fileName_svg = path.join(iconDir, '{}.svg'.format(str(iconName)))
            if path.exists(fileName):
                pixmap.load(fileName)
                #print "pixmap ->{}".format(fileName)
                logging.debug('Icon: %s found in %s' % (iconName, iconDir))
                return pixmap
            elif path.exists(fileName_svg):
                image = QImage(size, size, QImage.Format_RGB32)
                reader = QImageReader(fileName)
                reader.read(image)
                pixmap.convertFromImage(image)
                logging.debug('Icon: %s found in %s' % (iconName, iconDir))
                #print "pixmap ->{}".format(fileName)
                return pixmap

        if len(self._themes) > 0:
            self._themes.pop(0)
            if not len(self._themes) == 0 and pixmap.isNull():
                pixmap = self.findIconHelper(size, self._themes[0], iconName)
        return pixmap
コード例 #13
0
    def __init__(self, parent, album_list, edit: bool = False, current_album: AlbumData = None,
                 prefill_title: str = '', prefill_desc: str = ''):
        super().__init__(parent)
        self.setMinimumWidth(300)
        self.setWindowFlag(Qt.WindowContextHelpButtonHint, False)
        self.album_list = album_list
        self.edit = edit

        buttons = QDialogButtonBox.Ok | QDialogButtonBox.Cancel
        self.button_box = QDialogButtonBox(buttons)
        self.button_box.button(QDialogButtonBox.Ok).setEnabled(False)
        self.button_box.rejected.connect(self.my_reject)
        self.button_box.accepted.connect(self.accept)

        layout = QVBoxLayout()
        self.setLayout(layout)
        t_label = QLabel('Title (Required)')
        self.title = QLineEdit()
        self.title.setText(prefill_title)
        self.title.textChanged.connect(self.check_text)
        d_label = QLabel('Description')
        self.description = QLineEdit()
        self.description.setText(prefill_desc)

        layout.addWidget(t_label)
        layout.addWidget(self.title)
        layout.addWidget(d_label)
        layout.addWidget(self.description)
        layout.addStretch()
        layout.addWidget(self.button_box)

        if edit:
            self.setWindowTitle('Album Edit Tool')
            self.setWindowIcon(QIcon(QPixmap(QImageReader('assets/editAlbum.png').read())))
            self.title.setText(current_album.get_title())
            self.description.setText(current_album.get_description())
        else:
            self.setWindowIcon(QIcon(QPixmap(QImageReader('assets/newAlbum.png').read())))
            self.setWindowTitle('Album Creation Tool')

        if len(prefill_title) > 0:
            self.check_text()

        self.exec()
コード例 #14
0
    def initializeLayer(self, screenExtent=None):
        if self.error or self.initialized or self.initializing:
            return

        if self.filepath is not None:
            # not safe...
            self.initializing = True
            filepath = self.getAbsoluteFilepath()

            if not os.path.exists(filepath):
                # TODO integrate with BadLayerHandler ?
                loadErrorDialog = LoadErrorDialog(filepath)
                result = loadErrorDialog.exec_()
                if result == 1:
                    # absolute
                    filepath = loadErrorDialog.lineEditImagePath.text()
                    # to relative if needed
                    self.filepath = utils.toRelativeToQGS(filepath)
                    self.setCustomProperty("filepath", self.filepath)
                    QgsProject.instance().setDirty(True)
                else:
                    self.error = True

                del loadErrorDialog

            reader = QImageReader(filepath)
            self.image = reader.read()
            self.initialized = True
            self.initializing = False

            self.setupCrs()

            if screenExtent:
                # constructor called from AddLayer action
                # if not, layer loaded from QGS project file

                # check if image already has georef info
                # use GDAL
                dataset = gdal.Open(filepath, gdal.GA_ReadOnly)
                georef = None
                if dataset:
                    georef = dataset.GetGeoTransform()

                if georef and not self.is_default_geotransform(georef):
                    self.initializeExistingGeoreferencing(dataset, georef)
                else:
                    # init to default params
                    self.setCenter(screenExtent.center())
                    self.setRotation(0.0)

                    sw = screenExtent.width()
                    sh = screenExtent.height()

                    self.resetScale(sw, sh)

                    self.commitTransformParameters()
コード例 #15
0
def readImageFromFile(fileName):
    reader = QImageReader(fileName)
    reader.setAutoTransform(True)
    reader.setAutoDetectImageFormat(True)

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

    return image
コード例 #16
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
コード例 #17
0
 def _plat_get_dimensions(self):
     try:
         ir = QImageReader(str(self.path))
         size = ir.size()
         if size.isValid():
             return (size.width(), size.height())
         else:
             return (0, 0)
     except EnvironmentError:
         logging.warning("Could not read image '%s'", str(self.path))
         return (0, 0)
コード例 #18
0
ファイル: 3dmacher.py プロジェクト: rottaran/3dmacher
 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 replaceImage(self, filepath, title):
        self.title = title
        self.filepath = filepath

         # set custom properties
        self.setCustomProperty("title", title)
        self.setCustomProperty("filepath", self.filepath)
        self.setName(title)
        reader = QImageReader(filepath)
        self.image = reader.read()
        self.repaint()
コード例 #20
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)
コード例 #21
0
 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()
コード例 #22
0
ファイル: _file_handler.py プロジェクト: kaldown/vimiv-qt
    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))
コード例 #23
0
 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)
コード例 #24
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
コード例 #25
0
    def accept(self):

        for key, field in self.fields.items():
            self.data[key] = field["edit"].text()

        if self.data["name"] == "":
            msgBox = QMessageBox()
            msgBox.setText("Please, enter a name for the map.")
            msgBox.exec()
            return

        # check if the RGB map file exists
        rgb_filename = self.data['rgb_filename']
        if not os.path.exists(rgb_filename):
            msgBox = QMessageBox()
            msgBox.setText("The RGB image file does not seems to exist.")
            msgBox.exec()
            return

        # check if the depth map file exists
        depth_filename = self.data['depth_filename']
        if not os.path.exists(rgb_filename):
            msgBox = QMessageBox()
            msgBox.setText("The depth map file does not seems to exist.")
            msgBox.exec()
            return

        # check validity of the acquisition date
        txt = self.data["acquisition_date"]
        if not utils.isValidDate(txt):
            msgBox = QMessageBox()
            msgBox.setText(
                "Invalid date format. Please, enter the acquisition date as YYYY-MM-DD."
            )
            msgBox.exec()
            return

        # TODO: redundat check, remove it ?
        image_reader = QImageReader(rgb_filename)
        size = image_reader.size()
        if size.width() > 32767 or size.height() > 32767:
            msgBox = QMessageBox()
            msgBox.setText(
                "The image is too big. TagLab is limited to 32767x32767 pixels."
            )
            msgBox.exec()
            return

        self.accepted.emit()
        self.close()
コード例 #26
0
    def load_and_unpickle_image_hash(self, filepath):
        image_hash = {}

        bytearray_hash = pickle.load(open(filepath, "rb"))

        for k in bytearray_hash.keys():
            byte_array = bytearray_hash[k]

            buffer = QBuffer(byte_array)
            buffer.open(QIODevice.ReadOnly)
            reader = QImageReader(buffer)
            img = reader.read()
            image_hash[k] = img
        return image_hash
コード例 #27
0
 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)
コード例 #28
0
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")
コード例 #29
0
 def init_gui(self):
     # Init the basic window frame
     self.setWindowTitle('Jack\'s Photo Utilities v.2.2')
     pix = QPixmap(QImageReader('assets/icon.png').read())
     self.setWindowIcon(QIcon(pix))
     layout = QHBoxLayout()
     tabs = QTabWidget()
     duplicate_detector = DuplicateFinder()
     tabs.addTab(duplicate_detector, 'Duplicate Finder')
     date_sorter = DateSorter()
     tabs.addTab(date_sorter, 'Date Sorter')
     albums = Albums()
     tabs.addTab(albums, 'Albums')
     layout.addWidget(tabs)
     self.setLayout(layout)
     self.show()
コード例 #30
0
    def __init__(self,
                 file_type: str,
                 image,
                 path: str,
                 text='',
                 width=None,
                 height=None,
                 scaled=True,
                 error=False):
        super().__init__()

        self.file_type = file_type
        self.image = image
        self.path = path
        self.text = text

        # Image
        self.holder = QLabel('hold')
        pixmap = QPixmap(QImageReader(image).read())
        self.holder.setAlignment(Qt.AlignCenter)

        # Init sizes
        if width is not None:
            self.holder.setFixedWidth(width)
        if height is not None:
            self.holder.setFixedHeight(height)
        if scaled:
            self.holder.setPixmap(
                pixmap.scaled(self.holder.width(), self.holder.height(),
                              Qt.KeepAspectRatio, Qt.SmoothTransformation))
        else:
            self.holder.setPixmap(pixmap)

        # Image caption
        caption = QLabel(text)
        if error:
            caption.setStyleSheet('color: #FF0000')
        caption.setFixedWidth(self.holder.width())
        caption.setWordWrap(True)
        caption.setAlignment(Qt.AlignCenter)

        layout = QVBoxLayout()
        self.setLayout(layout)
        layout.addWidget(self.holder)
        layout.addWidget(caption)
        self.setToolTip(text)