def showPicture(self): fileName = DBConnectSingleton.instance.getPicPath(self.p_id) if (len(fileName) is not 0): print(fileName) img = QImage(fileName) if(img.height() is 0 or img.width() is 0): msg = QMessageBox() msg.setWindowTitle("ERROR") msg.setText("File open ERROR") msg.exec() return h = 155 w = 201 img_h = img.height() img_w = img.width() if (img_h > img_w): scale_factor = h / img_h img_h = h img_w *= scale_factor else: scale_factor = w / img_w img_w = w img_h *= scale_factor image = img.scaledToHeight(img_h) self.lbl_pic_view.setPixmap(QPixmap.fromImage(image))
def showPicture(self): fileName = DBConnectSingleton.instance.getPicPath(self.p_id) self.lbl_photo_loc.setText(fileName) if (len(fileName) is not 0): print(fileName) img = QImage(fileName) if(img.width() is 0 or img.height() is 0): msgBox = QMessageBox() msgBox.setText("The file is not exist."); msgBox.exec(); return h = self.lbl_photo_view.height() w = self.lbl_photo_view.width() img_h = img.height() img_w = img.width() if (img_h > img_w): scale_factor = h / img_h img_h = h img_w *= scale_factor else: scale_factor = w / img_w img_w = w img_h *= scale_factor image = img.scaledToHeight(img_h) self.lbl_photo_view.setPixmap(QPixmap.fromImage(image))
def simgv_load_image_to_viewer(self, index): """ Load an image to viewer. If the show feature points is checked, then load feature points as well. This option can be done only if the user has run a feature point method first. :param index: index of image to load. :return: Nothing """ if self.draw_kp: img_rgb = self.image_list[index].img_get_img_rgb_with_feature_points() feature_point_number = len(self.image_list[index].feature_points.keypoints) self.ui_simple_img_viewer.label_feature_points_number.setText(str(feature_point_number)) else: img_rgb = self.image_list[index].img_get_img_rgb() self.ui_simple_img_viewer.label_feature_points_number.clear() bytes_per_line = 3 * self.image_list[index].info.width q_img = QImage(img_rgb, self.image_list[index].info.width, self.image_list[index].info.height, bytes_per_line, QImage.Format_RGB888) width = self.ui_simple_img_viewer.image_view.width() height = self.ui_simple_img_viewer.image_view.height() if q_img.width() < width or q_img.height() < height: width = q_img.width() height = q_img.height() size = QSize(width, height) pixmap = QPixmap() pixmap = pixmap.fromImage(q_img) pixmap = pixmap.scaled(size, self.Q_ASPECT_RATIO) self.ui_simple_img_viewer.image_view.setPixmap(pixmap) self.ui_simple_img_viewer.image_view.show() self.ui_simple_img_viewer.button_previous.setEnabled(self.UP) self.ui_simple_img_viewer.button_next.setEnabled(self.UP) if index == 0: self.ui_simple_img_viewer.button_previous.setEnabled(self.DOWN) if index == len(self.image_list) - 1: self.ui_simple_img_viewer.button_next.setEnabled(self.DOWN)
class Body(QGraphicsItem): def __init__(self, parent, width, height): super().__init__(parent=parent) self.width = width self.height = height # self.setOpacity(0.0) self.head_img = QImage("resource/a_oryzae.png") def paint(self, paint: QPainter, style: QStyleOptionGraphicsItem, widget=None): qpen = QPen() qpen.setColor(Qt.white) # paint.setBackground() paint.setPen(qpen) aspect = self.head_img.width() / self.head_img.height() ratio = self.height * 0.2 target = QRectF(0, 0, aspect * ratio, ratio) source = QRectF(0, 0, self.head_img.width(), self.head_img.height()) paint.drawImage(target, self.head_img, source) def boundingRect(self): return QRectF(0, 0, self.width, self.height)
def scale_image(data, width=60, height=80, compression_quality=70, as_png=False, preserve_aspect_ratio=True): ''' Scale an image, returning it as either JPEG or PNG data (bytestring). Transparency is alpha blended with white when converting to JPEG. Is thread safe and does not require a QApplication. ''' # We use Qt instead of ImageMagick here because ImageMagick seems to use # some kind of memory pool, causing memory consumption to sky rocket. if isinstance(data, QImage): img = data else: img = QImage() if not img.loadFromData(data): raise ValueError('Could not load image for thumbnail generation') if preserve_aspect_ratio: scaled, nwidth, nheight = fit_image(img.width(), img.height(), width, height) if scaled: img = img.scaled(nwidth, nheight, Qt.KeepAspectRatio, Qt.SmoothTransformation) else: if img.width() != width or img.height() != height: img = img.scaled(width, height, Qt.IgnoreAspectRatio, Qt.SmoothTransformation) if not as_png and img.hasAlphaChannel(): nimg = QImage(img.size(), QImage.Format_RGB32) nimg.fill(Qt.white) p = QPainter(nimg) p.drawImage(0, 0, img) p.end() img = nimg ba = QByteArray() buf = QBuffer(ba) buf.open(QBuffer.WriteOnly) fmt = 'PNG' if as_png else 'JPEG' if not img.save(buf, fmt, quality=compression_quality): raise ValueError('Failed to export thumbnail image to: ' + fmt) return img.width(), img.height(), ba.data()
def generate_cover(mi, prefs=None, as_qimage=False): init_environment() prefs = prefs or cprefs prefs = {k: prefs.get(k) for k in cprefs.defaults} prefs = Prefs(**prefs) color_theme = random.choice(load_color_themes(prefs)) style = random.choice(load_styles(prefs))(color_theme, prefs) title, subtitle, footer = format_text(mi, prefs) img = QImage(prefs.cover_width, prefs.cover_height, QImage.Format_ARGB32) title_block, subtitle_block, footer_block = layout_text( prefs, img, title, subtitle, footer, img.height() // 3, style) p = QPainter(img) rect = QRect(0, 0, img.width(), img.height()) colors = style(p, rect, color_theme, title_block, subtitle_block, footer_block) for block, color in zip((title_block, subtitle_block, footer_block), colors): p.setPen(color) block.draw(p) p.end() img.setText('Generated cover', '%s %s' % (__appname__, __version__)) if as_qimage: return img return pixmap_to_data(img)
def calibre_cover2(title, author_string='', series_string='', prefs=None, as_qimage=False, logo_path=None): init_environment() title, subtitle, footer = '<b>' + escape_formatting( title), '<i>' + escape_formatting( series_string), '<b>' + escape_formatting(author_string) prefs = prefs or cprefs prefs = {k: prefs.get(k) for k in cprefs.defaults} scale = 800. / prefs['cover_height'] scale_cover(prefs, scale) prefs = Prefs(**prefs) img = QImage(prefs.cover_width, prefs.cover_height, QImage.Format.Format_ARGB32) img.fill(Qt.GlobalColor.white) # colors = to_theme('ffffff ffffff 000000 000000') color_theme = theme_to_colors(fallback_colors) class CalibeLogoStyle(Style): NAME = GUI_NAME = 'calibre' def __call__(self, painter, rect, color_theme, title_block, subtitle_block, footer_block): top = title_block.position.y + 10 extra_spacing = subtitle_block.line_spacing // 2 if subtitle_block.line_spacing else title_block.line_spacing // 3 height = title_block.height + subtitle_block.height + extra_spacing + title_block.leading top += height + 25 bottom = footer_block.position.y - 50 logo = QImage(logo_path or I('library.png')) pwidth, pheight = rect.width(), bottom - top scaled, width, height = fit_image(logo.width(), logo.height(), pwidth, pheight) x, y = (pwidth - width) // 2, (pheight - height) // 2 rect = QRect(x, top + y, width, height) painter.setRenderHint(QPainter.RenderHint.SmoothPixmapTransform) painter.drawImage(rect, logo) return self.ccolor1, self.ccolor1, self.ccolor1 style = CalibeLogoStyle(color_theme, prefs) title_block, subtitle_block, footer_block = layout_text( prefs, img, title, subtitle, footer, img.height() // 3, style) p = QPainter(img) rect = QRect(0, 0, img.width(), img.height()) colors = style(p, rect, color_theme, title_block, subtitle_block, footer_block) for block, color in zip((title_block, subtitle_block, footer_block), colors): p.setPen(color) block.draw(p) p.end() img.setText('Generated cover', '%s %s' % (__appname__, __version__)) if as_qimage: return img return pixmap_to_data(img)
def render_html(self, ok): try: if not ok: return cwidth, cheight = self.page.mainFrame().contentsSize().width( ), self.page.mainFrame().contentsSize().height() self.page.setViewportSize(QSize(cwidth, cheight)) factor = float(self.width) / cwidth if cwidth > self.width else 1 cutoff_height = int(self.height / factor) - 3 image = QImage(self.page.viewportSize(), QImage.Format_ARGB32) image.setDotsPerMeterX(self.dpi * (100 / 2.54)) image.setDotsPerMeterY(self.dpi * (100 / 2.54)) painter = QPainter(image) self.page.mainFrame().render(painter) painter.end() cheight = image.height() cwidth = image.width() pos = 0 while pos < cheight: img = image.copy(0, pos, cwidth, min(cheight - pos, cutoff_height)) pos += cutoff_height - 20 if cwidth > self.width: img = img.scaledToWidth(self.width, Qt.SmoothTransform) f = os.path.join(self.tdir, '%d.png' % pos) img.save(f) self.images.append((f, img.width(), img.height())) finally: QApplication.quit()
def __init__ (self,database,progressBar,parent=None): super(Univers,self).__init__(parent) self.progress = progressBar self.factions = {} self.temples = {} self.database = database self.list_actions = {} self.cancelled_heros_id = [] self.modifications = [] self.loadFromFile() self.currentFaction = None self.currentEmpire = None self.currentKingdom= None self.currentGroupe= None self.selected_Warriors = [[],[]] self.filtered_Warriors = [] self.settings = Config().instance.settings colors = self.settings.value ("global/groupe_color").split(",") self.groupe_color_icons = {} self.groupe_color_value = {} for color in colors : icon = QIcon(":textures/"+color) self.groupe_color_icons[color] = icon image = QImage(":textures/"+color) value = image.pixel(image.width()/2.0,image.height()/2.0) # pour view map donner une couleur a item warrior self.groupe_color_value[color] = QColor(value)
def render_html(self, ok): try: if not ok: return cwidth, cheight = self.page.mainFrame().contentsSize().width(), self.page.mainFrame().contentsSize().height() self.page.setViewportSize(QSize(cwidth, cheight)) factor = float(self.width)/cwidth if cwidth > self.width else 1 cutoff_height = int(self.height/factor)-3 image = QImage(self.page.viewportSize(), QImage.Format_ARGB32) image.setDotsPerMeterX(self.dpi*(100/2.54)) image.setDotsPerMeterY(self.dpi*(100/2.54)) painter = QPainter(image) self.page.mainFrame().render(painter) painter.end() cheight = image.height() cwidth = image.width() pos = 0 while pos < cheight: img = image.copy(0, pos, cwidth, min(cheight-pos, cutoff_height)) pos += cutoff_height-20 if cwidth > self.width: img = img.scaledToWidth(self.width, Qt.SmoothTransform) f = os.path.join(self.tdir, '%d.png'%pos) img.save(f) self.images.append((f, img.width(), img.height())) finally: QApplication.quit()
def render_cover(self, book_id): if self.ignore_render_requests.is_set(): return tcdata, timestamp = self.thumbnail_cache[book_id] use_cache = False if timestamp is None: # Not in cache has_cover, cdata, timestamp = self.model( ).db.new_api.cover_or_cache(book_id, 0) else: has_cover, cdata, timestamp = self.model( ).db.new_api.cover_or_cache(book_id, timestamp) if has_cover and cdata is None: # The cached cover is fresh cdata = tcdata use_cache = True if has_cover: p = QImage() p.loadFromData(cdata, CACHE_FORMAT if cdata is tcdata else 'JPEG') dpr = self.device_pixel_ratio p.setDevicePixelRatio(dpr) if p.isNull() and cdata is tcdata: # Invalid image in cache self.thumbnail_cache.invalidate((book_id, )) self.update_item.emit(book_id) return cdata = None if p.isNull() else p if not use_cache: # cache is stale if cdata is not None: width, height = p.width(), p.height() scaled, nwidth, nheight = fit_image( width, height, int(dpr * self.delegate.cover_size.width()), int(dpr * self.delegate.cover_size.height())) if scaled: if self.ignore_render_requests.is_set(): return p = p.scaled(nwidth, nheight, Qt.IgnoreAspectRatio, Qt.SmoothTransformation) p.setDevicePixelRatio(dpr) cdata = p # update cache if cdata is None: self.thumbnail_cache.invalidate((book_id, )) else: try: self.thumbnail_cache.insert(book_id, timestamp, image_to_data(cdata)) except EncodeError as err: self.thumbnail_cache.invalidate((book_id, )) prints(err) except Exception: import traceback traceback.print_exc() elif tcdata is not None: # Cover was removed, but it exists in cache, remove from cache self.thumbnail_cache.invalidate((book_id, )) self.delegate.cover_cache.set(book_id, cdata) self.update_item.emit(book_id)
def calibre_cover2(title, author_string='', series_string='', prefs=None, as_qimage=False, logo_path=None): init_environment() title, subtitle, footer = '<b>' + escape_formatting(title), '<i>' + escape_formatting(series_string), '<b>' + escape_formatting(author_string) prefs = prefs or cprefs prefs = {k:prefs.get(k) for k in cprefs.defaults} scale = 800. / prefs['cover_height'] scale_cover(prefs, scale) prefs = Prefs(**prefs) img = QImage(prefs.cover_width, prefs.cover_height, QImage.Format_ARGB32) img.fill(Qt.white) # colors = to_theme('ffffff ffffff 000000 000000') color_theme = theme_to_colors(fallback_colors) class CalibeLogoStyle(Style): NAME = GUI_NAME = 'calibre' def __call__(self, painter, rect, color_theme, title_block, subtitle_block, footer_block): top = title_block.position.y + 10 extra_spacing = subtitle_block.line_spacing // 2 if subtitle_block.line_spacing else title_block.line_spacing // 3 height = title_block.height + subtitle_block.height + extra_spacing + title_block.leading top += height + 25 bottom = footer_block.position.y - 50 logo = QImage(logo_path or I('library.png')) pwidth, pheight = rect.width(), bottom - top scaled, width, height = fit_image(logo.width(), logo.height(), pwidth, pheight) x, y = (pwidth - width) // 2, (pheight - height) // 2 rect = QRect(x, top + y, width, height) painter.setRenderHint(QPainter.SmoothPixmapTransform) painter.drawImage(rect, logo) return self.ccolor1, self.ccolor1, self.ccolor1 style = CalibeLogoStyle(color_theme, prefs) title_block, subtitle_block, footer_block = layout_text( prefs, img, title, subtitle, footer, img.height() // 3, style) p = QPainter(img) rect = QRect(0, 0, img.width(), img.height()) colors = style(p, rect, color_theme, title_block, subtitle_block, footer_block) for block, color in zip((title_block, subtitle_block, footer_block), colors): p.setPen(color) block.draw(p) p.end() img.setText('Generated cover', '%s %s' % (__appname__, __version__)) if as_qimage: return img return pixmap_to_data(img)
def render_cover(self, book_id): if self.ignore_render_requests.is_set(): return dpr = self.device_pixel_ratio page_width = int(dpr * self.delegate.cover_size.width()) page_height = int(dpr * self.delegate.cover_size.height()) tcdata, timestamp = self.thumbnail_cache[book_id] use_cache = False if timestamp is None: # Not in cache has_cover, cdata, timestamp = self.model().db.new_api.cover_or_cache(book_id, 0) else: has_cover, cdata, timestamp = self.model().db.new_api.cover_or_cache(book_id, timestamp) if has_cover and cdata is None: # The cached cover is fresh cdata = tcdata use_cache = True if has_cover: p = QImage() p.loadFromData(cdata, CACHE_FORMAT if cdata is tcdata else 'JPEG') p.setDevicePixelRatio(dpr) if p.isNull() and cdata is tcdata: # Invalid image in cache self.thumbnail_cache.invalidate((book_id,)) self.update_item.emit(book_id) return cdata = None if p.isNull() else p if not use_cache: # cache is stale if cdata is not None: width, height = p.width(), p.height() scaled, nwidth, nheight = fit_image( width, height, page_width, page_height) if scaled: if self.ignore_render_requests.is_set(): return p = p.scaled(nwidth, nheight, Qt.IgnoreAspectRatio, Qt.SmoothTransformation) p.setDevicePixelRatio(dpr) cdata = p # update cache if cdata is None: self.thumbnail_cache.invalidate((book_id,)) else: try: self.thumbnail_cache.insert(book_id, timestamp, image_to_data(cdata)) except EncodeError as err: self.thumbnail_cache.invalidate((book_id,)) prints(err) except Exception: import traceback traceback.print_exc() elif tcdata is not None: # Cover was removed, but it exists in cache, remove from cache self.thumbnail_cache.invalidate((book_id,)) self.delegate.cover_cache.set(book_id, cdata) self.update_item.emit(book_id)
def add_image(self, img, cache_key): ref = self.get_image(cache_key) if ref is not None: return ref fmt = img.format() image = QImage(img) if (image.depth() == 1 and img.colorTable().size() == 2 and img.colorTable().at(0) == QColor(Qt.black).rgba() and img.colorTable().at(1) == QColor(Qt.white).rgba()): if fmt == QImage.Format_MonoLSB: image = image.convertToFormat(QImage.Format_Mono) fmt = QImage.Format_Mono else: if (fmt != QImage.Format_RGB32 and fmt != QImage.Format_ARGB32): image = image.convertToFormat(QImage.Format_ARGB32) fmt = QImage.Format_ARGB32 w = image.width() h = image.height() d = image.depth() if fmt == QImage.Format_Mono: bytes_per_line = (w + 7) >> 3 data = image.constBits().asstring(bytes_per_line * h) return self.write_image(data, w, h, d, cache_key=cache_key) has_alpha = False soft_mask = None if fmt == QImage.Format_ARGB32: tmask = image.constBits().asstring(4*w*h)[self.alpha_bit::4] sdata = bytearray(tmask) vals = set(sdata) vals.discard(255) # discard opaque pixels has_alpha = bool(vals) if has_alpha: # Blend image onto a white background as otherwise Qt will render # transparent pixels as black background = QImage(image.size(), QImage.Format_ARGB32_Premultiplied) background.fill(Qt.white) painter = QPainter(background) painter.drawImage(0, 0, image) painter.end() image = background ba = QByteArray() buf = QBuffer(ba) image.save(buf, 'jpeg', 94) data = ba.data() if has_alpha: soft_mask = self.write_image(tmask, w, h, 8) return self.write_image(data, w, h, 32, dct=True, soft_mask=soft_mask, cache_key=cache_key)
def add_image(self, img, cache_key): ref = self.get_image(cache_key) if ref is not None: return ref fmt = img.format() image = QImage(img) if (image.depth() == 1 and img.colorTable().size() == 2 and img.colorTable().at(0) == QColor(Qt.black).rgba() and img.colorTable().at(1) == QColor(Qt.white).rgba()): if fmt == QImage.Format_MonoLSB: image = image.convertToFormat(QImage.Format_Mono) fmt = QImage.Format_Mono else: if (fmt != QImage.Format_RGB32 and fmt != QImage.Format_ARGB32): image = image.convertToFormat(QImage.Format_ARGB32) fmt = QImage.Format_ARGB32 w = image.width() h = image.height() d = image.depth() if fmt == QImage.Format_Mono: bytes_per_line = (w + 7) >> 3 data = image.constBits().asstring(bytes_per_line * h) return self.write_image(data, w, h, d, cache_key=cache_key) has_alpha = False soft_mask = None if fmt == QImage.Format_ARGB32: tmask = image.constBits().asstring(4*w*h)[self.alpha_bit::4] sdata = bytearray(tmask) vals = set(sdata) vals.discard(255) # discard opaque pixels has_alpha = bool(vals) if has_alpha: # Blend image onto a white background as otherwise Qt will render # transparent pixels as black background = QImage(image.size(), QImage.Format_ARGB32_Premultiplied) background.fill(Qt.white) painter = QPainter(background) painter.drawImage(0, 0, image) painter.end() image = background ba = QByteArray() buf = QBuffer(ba) image.save(buf, 'jpeg', 94) data = bytes(ba.data()) if has_alpha: soft_mask = self.write_image(tmask, w, h, 8) return self.write_image(data, w, h, 32, dct=True, soft_mask=soft_mask, cache_key=cache_key)
def generate_cover(mi, prefs=None, as_qimage=False): init_environment() prefs = prefs or cprefs prefs = {k:prefs.get(k) for k in cprefs.defaults} prefs = Prefs(**prefs) color_theme = random.choice(load_color_themes(prefs)) style = random.choice(load_styles(prefs))(color_theme, prefs) title, subtitle, footer = format_text(mi, prefs) img = QImage(prefs.cover_width, prefs.cover_height, QImage.Format_ARGB32) title_block, subtitle_block, footer_block = layout_text( prefs, img, title, subtitle, footer, img.height() // 3, style) p = QPainter(img) rect = QRect(0, 0, img.width(), img.height()) colors = style(p, rect, color_theme, title_block, subtitle_block, footer_block) for block, color in zip((title_block, subtitle_block, footer_block), colors): p.setPen(color) block.draw(p) p.end() img.setText('Generated cover', '%s %s' % (__appname__, __version__)) if as_qimage: return img return pixmap_to_data(img)
def __call__(self, painter, rect, color_theme, title_block, subtitle_block, footer_block): top = title_block.position.y + 10 extra_spacing = subtitle_block.line_spacing // 2 if subtitle_block.line_spacing else title_block.line_spacing // 3 height = title_block.height + subtitle_block.height + extra_spacing + title_block.leading top += height + 25 bottom = footer_block.position.y - 50 logo = QImage(logo_path or I('library.png')) pwidth, pheight = rect.width(), bottom - top scaled, width, height = fit_image(logo.width(), logo.height(), pwidth, pheight) x, y = (pwidth - width) // 2, (pheight - height) // 2 rect = QRect(x, top + y, width, height) painter.setRenderHint(QPainter.SmoothPixmapTransform) painter.drawImage(rect, logo) return self.ccolor1, self.ccolor1, self.ccolor1
def qimage_to_magick(img): ans = Image() fmt = get_pixel_map() if not img.hasAlphaChannel(): if img.format() != img.Format_RGB32: img = QImage(img) img.setFormat(QImage.Format_RGB32) fmt = fmt.replace('A', 'P') else: if img.format() != img.Format_ARGB32: img = QImage(img) img.setFormat(img.Format_ARGB32) raw = img.constBits().ascapsule() ans.constitute(img.width(), img.height(), fmt, raw) return ans
def update (self,warrior): self.warrior = warrior groupe_name = warrior.groupe().name if warrior.masterGroupe() != None : groupe_name = warrior.masterGroupe().name+"/"+groupe_name kingdom_name = warrior.kingdom().name empire_name = warrior.empire().name faction_name = warrior.faction().name path = os.path.join(Config().instance.path_to_pic(),faction_name,empire_name,kingdom_name,'Picture',groupe_name,warrior.name) picture = QPixmap(path+"/portrait.jpg").scaledToWidth(self.picture.width()) self.warrior_name.setText(warrior.name.replace("_"," ")) self.warrior_name.setObjectName("Warrior_name") couleur = warrior.groupe().attribs['color'] if warrior.masterGroupe() != None : couleur = warrior.masterGroupe().attribs['color'] self.picture.setPixmap(picture) self.progressBar_life.setStyleSheet(" QProgressBar{ background-color: red;}") #self.ui.progressBar_life.setAlignment(QtCore.Qt.AlignCenter) #self.progressBar_energy.setStyleSheet(" QProgressBar::chunk { background-color: #05B8CC;width: 20px;}") #self.ui.progressBar_MP.setAlignment(QtCore.Qt.AlignCenter) try: hp_percent = float(self.warrior.attribs['HP'] / self.warrior.attribs['HP_max'])* 100 mp_percent = float(self.warrior.attribs['MP'] / self.warrior.attribs['MP_max'])* 100 except (ZeroDivisionError,KeyError) as e : hp_percent =0 mp_percent =0 self.progressBar_life.setValue(int(hp_percent)) self.progressBar_energy.setValue(int(mp_percent)) self.profil_completion.setPixmap(QPixmap(":/icons/128x128/state_"+str(warrior.attribs['complete']+1)).scaledToHeight(32)) self.profil_completion.setStyleSheet("#"+self.profil_completion.objectName()+"{background-color:transparent;}") pal = QPalette(self.rank_text.palette()) image = QImage(os.path.join(Config().instance.path_to_icons(),"rank")+"/star_"+warrior.groupe().attribs["color"]+".png") value = image.pixel(image.width()/2.0,image.height()/2.0) pal.setColor(QPalette.WindowText, QColor(value)) self.rank_text.setPalette(pal) self.rank_text.setText(str(warrior.attribs["rank"])) #Boutton Faction path = os.path.join(Config().instance.path_to_icons(),"faction","32x32",faction_name) self.iconFaction.setIcon(QIcon(path)) self.iconFaction.setToolTip(warrior.faction().name) #Boutton Empire path = os.path.join(Config().instance.path_to_icons(),"empire","32x32",empire_name) self.iconEmpire.setIcon(QIcon(path)) self.iconEmpire.setToolTip(warrior.empire().name) self.iconEmpire.clicked.connect(self.onEmpireClicked) #Boutton Kingdom path = os.path.join(Config().instance.path_to_icons(),"kingdom","32x32",kingdom_name) self.iconKingdom.setIcon(QIcon(path)) self.iconKingdom.setToolTip(self.warrior.kingdom().name) self.iconKingdom.clicked.connect(self.onKingdomClicked) #Boutton Groupe self.iconGroupe.setText(groupe_name.replace("_"," ")) groupe_color = self.warrior.groupe().attribs['color'] if self.warrior.masterGroupe() != None : groupe_color = self.warrior.masterGroupe().attribs['color'] self.iconGroupe.setStyleSheet("#"+self.iconGroupe.objectName()+"{background-image:url(:/textures/"+groupe_color+");}") self.iconGroupe.clicked.connect(self.onGroupClicked) path = os.path.join(Config().instance.path_to_icons(),"actions",warrior.attribs['status']) # Icone d etat self.iconState.setPixmap(QPixmap(path).scaledToHeight(64))
class ToolButton(QToolButton): _MultiIconOption = 1 _ShowMenuInsideOption = 2 _ToolBarLookOption = 4 _ShowMenuOnRightClick = 8 def __init__(self, parent=None): super(ToolButton, self).__init__(parent) self._multiIcon = QImage() self._themeIcon = '' self._pressTimer = QTimer() self._menu = None # QMenu self._options = 0 self.setMinimumWidth(16) opt = QStyleOptionToolButton() self.initStyleOption(opt) self._pressTimer.setSingleShot(True) self._pressTimer.setInterval(QApplication.style().styleHint( QStyle.SH_ToolButton_PopupDelay, opt, self )) self._pressTimer.timeout.connect(self._showMenu) def size(self): return super().size() def setFixedSize(self, size): return super().setFixedSize(size) fixedsize = pyqtProperty(QSize, size, setFixedSize) def width(self): return super().width() def setFixedWidth(self, width): return super().setFixedWidth(width) fixedwidth = pyqtProperty(int, width, setFixedWidth) def height(self): return super().height() def setFixedHeight(self, height): return super().setFixedHeight(height) fixedheight = pyqtProperty(int, height, setFixedHeight) def multiIcon(self): ''' @brief: MultiIcon - Image containing pixmaps for all button states @return: QImage ''' return self._multiIcon def setMultiIcon(self, image): ''' @param: image QImage ''' self._options |= self._MultiIconOption self._multiIcon = image self.setFixedSize(self._multiIcon.width(), self._multiIcon.height()) self.update() multiIcon = pyqtProperty(QImage, multiIcon, setMultiIcon) def icon(self): ''' @brief: Icon - Standard QToolButton with icon @return: QIcon ''' return super().icon() def setIcon(self, icon): ''' @param: QIcon ''' if self._options & self._MultiIconOption: self.setFixedSize(self.sizeHint()) self._options &= ~self._MultiIconOption if not isinstance(icon, QIcon): icon = QIcon(icon) super().setIcon(icon) icon = pyqtProperty(QIcon, icon, setIcon) def themeIcon(self): ''' @brief: ThemeIcon - Standard QToolButton with theme icon @return: QString ''' return self._themeIcon def setThemeIcon(self, icon): ''' @param: icon QString ''' # QIcon ic ic = QIcon.fromTheme(icon) if not ic.isNull(): self._themeIcon = icon self.setIcon(QIcon.fromTheme(self._themeIcon)) themeIcon = pyqtProperty(str, themeIcon, setThemeIcon) def fallbackIcon(self): ''' @brief: FallbackIcon - In case theme doesn't contain ThemeIcon @return: QIcon ''' return self.icon def setFallbackIcon(self, fallbackIcon): ''' @param: fallbackIcon QIcon ''' if self.icon.isNull(): self.setIcon(fallbackIcon) fallbackIcon = pyqtProperty(QIcon, fallbackIcon, setFallbackIcon) def menu(self): ''' @note: Menu - Menu is handled in ToolButton and is not passed to QToolButton There won't be menu indicator shown in the button QToolButton::MenuButtonPopup is not supported @return: QMenu ''' return self._menu def setMenu(self, menu): ''' @param: menu QMenu ''' assert(menu) if self._menu: self._menu.aboutToHide.disconnect(self._menuAboutToHide) self._menu = menu self._menu.aboutToHide.connect(self._menuAboutToHide) def showMenuInside(self): ''' @brief: Align the right corner of menu to the right corner of button ''' return self._options & self._ShowMenuInsideOption def setShowMenuInside(self, enable): if enable: self._options |= self._ShowMenuInsideOption else: self._options &= ~self._ShowMenuInsideOption def showMenuOnRightClick(self): ''' @brief: Show button menu on right click ''' return self._options & self._ShowMenuOnRightClick def setShowMenuOnRightClick(self, enable): if enable: self._options |= self._ShowMenuOnRightClick else: self._options &= ~self._ShowMenuOnRightClick def toolbarButtonLook(self): ''' @brief: Set the button to look as it was in toolbar (it now only sets the correct icon size) @return: bool ''' return self._options & self._ToolBarLookOption def setToolbarButtonLook(self, enable): if enable: self._options |= self._ToolBarLookOption opt = QStyleOption() opt.initFrom(self) size = self.style().pixelMetric(QStyle.PM_ToolBarIconSize, opt, self) self.setIconSize(QSize(size, size)) else: self._options &= ~self._ToolBarLookOption self.setProperty('toolbar-look', enable) self.style().unpolish(self) self.style().polish(self) # Q_SIGNALS middleMouseClicked = pyqtSignal() controlClicked = pyqtSignal() doubleClicked = pyqtSignal() # It is needed to use these signals with ShowMenuInside aboutToShowMenu = pyqtSignal() aboutToHideMenu = pyqtSignal() # private Q_SLOTS def _menuAboutToHide(self): self.setDown(False) self.aboutToHideMenu.emit() def _showMenu(self): if not self._menu or self._menu.isVisible(): return self.aboutToShowMenu.emit() pos = QPoint() if self._options & self._ShowMenuInsideOption: pos = self.mapToGlobal(self.rect().bottomRight()) if QApplication.layoutDirection() == Qt.RightToLeft: pos.setX(pos.x() - self.rect().width()) else: pos.setX(pos.x() - self._menu.sizeHint().width()) else: pos = self.mapToGlobal(self.rect().bottomLeft()) self._menu.popup(pos) # protected: # override def mousePressEvent(self, event): ''' @param: event QMouseEvent ''' buttons = event.buttons() if buttons == Qt.LeftButton and self.popupMode() == QToolButton.DelayedPopup: self._pressTimer.start() if buttons == Qt.LeftButton and self.menu() and self.popupMode() == QToolButton.InstantPopup: self.setDown(True) self._showMenu() elif buttons == Qt.RightButton and self.menu() and self._options & self.showMenuOnRightClick: self.setDown(True) self._showMenu() else: super().mousePressEvent(event) # override def mouseReleaseEvent(self, event): ''' @param: event QMouseEvent ''' self._pressTimer.stop() button = event.button() if button == Qt.MiddleButton and self.rect().contains(event.pos()): self.middleMouseClicked.emit() self.setDown(False) elif button == Qt.LeftButton and self.rect().contains(event.pos()) and \ event.modifiers() == Qt.ControlModifier: self.controlClicked.emit() self.setDown(False) else: super().mouseReleaseEvent(event) # override def mouseDoubleClickEvent(self, event): ''' @param: event QMouseEvent ''' super().mouseDoubleClickEvent(event) self._pressTimer.stop() if event.buttons() == Qt.LeftButton: self.doubleClicked.emit() # override def contextMenuEvent(self, event): ''' @param: event QContextMenuEvent ''' # Block to prevent showing both context menu and button menu if self.menu() and self._options & self._ShowMenuOnRightClick: return super().contextMenuEvent(event) # override def paintEvent(self, event): ''' @param: event QPaintEvent ''' if not (self._options & self._MultiIconOption): super().paintEvent(event) return p = QPainter(self) w = self._multiIcon.width() h4 = self._multiIcon.height() / 4 if not self.isEnabled(): p.drawImage(0, 0, self._multiIcon, 0, h4 * 3, w, h4) elif self.isDown(): p.drawImage(0, 0, self._multiIcon, 0, h4 * 2, w, h4) elif self.underMouse(): p.drawImage(0, 0, self._multiIcon, 0, h4 * 1, w, h4) else: p.drawImage(0, 0, self._multiIcon, 0, h4 * 0, w, h4)
class Window: def __init__(self): # ------------------------ # Set flags # ------------------------ self.UP = True self.DOWN = False self.ALL_IMG_FORMAT = "All Supported (*.jpg *.jpeg *.jpe *.png *.bmp *.tif *.tiff " \ "*.dib *.pbm *.pgm *.ppm *.sr *.ras)" self.JPG_FORMAT = "JPG (*.jpg *.jpeg *.jpe)" self.PNG_FORMAT = "PNG (*.png)" self.BMP_FORMAT = "BMP (*.bmp)" self.TIF_FORMAT = "TIFF (*.tif *.tiff)" self.DIB_FORMAT = "DIB (*.dib)" self.PBM_FORMAT = "PBM (*.pbm)" self.PGM_FORMAT = "PGM (*.pgm)" self.PPM_FORMAT = "PPM (*.ppm)" self.SR__FORMAT = "SR (*.sr)" self.RAS_FORMAT = "RAS (*.ras)" self.DD = ";;" self.IMG_FILTER = self.ALL_IMG_FORMAT + self.DD + self.JPG_FORMAT + self.DD + self.PNG_FORMAT + self.DD + \ self.BMP_FORMAT + self.DD + self.TIF_FORMAT + self.DD + self.DIB_FORMAT + self.DD + \ self.PBM_FORMAT + self.DD + self.PGM_FORMAT + self.DD + self.PPM_FORMAT + self.DD + \ self.SR__FORMAT + self.DD + self.RAS_FORMAT self.DIALOG_FLAG = QFileDialog.DontUseNativeDialog self.Q_ASPECT_RATIO = Qt.KeepAspectRatio # ------------------------ # Flags Section ends here # ---------------------------------------------------------------------------------------------------------- # # ------------------------ # Set class items # ------------------------ self.q_img = QImage() self.img_view_timer = QTimer() self.img = Image() self.is_img_Open = False self.is_img_Save = False # ------------------------ # Class items ends here # ---------------------------------------------------------------------------------------------------------- # # ------------------------ # Set up the ui # ------------------------ self.app = QtWidgets.QApplication(sys.argv) self.ui = Ui_MainWindow() self.MainWindow = QtWidgets.QMainWindow() self.ui.setupUi(self.MainWindow) # ------------------------ # Setting up ends here # ---------------------------------------------------------------------------------------------------------- # # ------------------------ # Actions list starts here # ------------------------ self.ui.actionOpen.triggered.connect(self.open) self.ui.actionSave.triggered.connect(self.save) self.ui.actionExit.triggered.connect(self.exit_window) self.img_view_timer.timeout.connect(self.update_img_view) self.img_view_timer.start(250) # ------------------------ # Actions list ends here # ---------------------------------------------------------------------------------------------------------- # # ------------------------ # Main loop and exit app # ------------------------ self.MainWindow.show() sys.exit(self.app.exec_()) # ------------------------ # END OF APPLICATION # ---------------------------------------------------------------------------------------------------------- # def update_img_view(self): if self.is_img_Open: #print(self.ui.img_view.size()) width = self.ui.img_view.width() height = self.ui.img_view.height() if self.img.width < width or self.img.height < height: width = self.q_img.width() height = self.q_img.height() size = QSize(width, height) pixmap = QPixmap() pixmap = pixmap.fromImage(self.q_img) pixmap = pixmap.scaled(size, self.Q_ASPECT_RATIO) self.ui.img_view.setPixmap(pixmap) self.ui.img_view.show() def open_img_path(self): """ Open the dialog and take the path. :return: True/False, path_string/empty_string """ file_dialog = QFileDialog() f_path = file_dialog.getOpenFileName(parent=None, caption="Open Image", directory=QDir.homePath(), filter=self.IMG_FILTER, initialFilter="", options=self.DIALOG_FLAG)[0] if f_path: return True, f_path return False, "" def save_img_path(self): """ Open the dialog and take the path. :return: True/False, path_string/empty_string """ file_dialog = QFileDialog() f_path = file_dialog.getSaveFileName(parent=None, caption="Save Image as", directory=QDir.homePath(), filter=self.IMG_FILTER, initialFilter="", options=self.DIALOG_FLAG)[0] if f_path: return True, f_path return False, "" def open(self): """ Open an image and create a QImage() item for view. :return: Nothing """ self.is_img_Open, f_path = self.open_img_path( ) # Open dialog and take the path if self.is_img_Open: # Check if user gave a path or not (aka pressed "Open" or "Cancel" self.img.open_image_from(f_path) # Open image self.img.print_img_info() # Print info for debugging # Transform Image() to QImage() bytes_per_line = 3 * self.img.width self.q_img = QImage(self.img.img_RGB(), self.img.width, self.img.height, bytes_per_line, QImage.Format_RGB888) self.ui.actionSave.setEnabled( self.UP) # Enable save (currently not so useful) def save(self): """ Save an image to a given path :return: Nothing """ self.is_img_Save, f_path = self.save_img_path( ) # Open dialog and take the path if self.is_img_Save: # Check if user gave a path or not (aka pressed "Open" or "Cancel" self.img.save_image_as(f_path) def exit_window(self): """ Signal exit application :return: Nothing """ self.MainWindow.close() # Close The window
def _fetch_marvin_cover(border_width=0): ''' Retrieve LargeCoverJpg from cache ''' #self._log_location('border_width: {0}'.format(border_width)) con = sqlite3.connect(self.marvin_db_path) with con: con.row_factory = sqlite3.Row # Fetch Hash from mainDb cover_cur = con.cursor() cover_cur.execute('''SELECT Hash FROM Books WHERE ID = '{0}' '''.format(self.book_id)) row = cover_cur.fetchone() book_hash = row[b'Hash'] large_covers_subpath = self.connected_device._cover_subpath( size="large") cover_path = '/'.join([large_covers_subpath, '%s.jpg' % book_hash]) stats = self.parent.ios.exists(cover_path) if stats: self._log("fetching large cover from cache") #self._log("cover size: {:,} bytes".format(int(stats['st_size']))) cover_bytes = self.parent.ios.read(cover_path, mode='rb') m_image = QImage() m_image.loadFromData(cover_bytes) if border_width: # Construct a QPixmap with oversized yellow background m_image = m_image.scaledToHeight( self.COVER_ICON_SIZE - border_width * 2, Qt.SmoothTransformation) self.m_pixmap = QPixmap( QSize(m_image.width() + border_width * 2, m_image.height() + border_width * 2)) m_painter = QPainter(self.m_pixmap) m_painter.setRenderHints(m_painter.Antialiasing) m_painter.fillRect(self.m_pixmap.rect(), self.MISMATCH_COLOR) m_painter.drawImage(border_width, border_width, m_image) else: m_image = m_image.scaledToHeight(self.COVER_ICON_SIZE, Qt.SmoothTransformation) self.m_pixmap = QPixmap( QSize(m_image.width(), m_image.height())) m_painter = QPainter(self.m_pixmap) m_painter.setRenderHints(m_painter.Antialiasing) m_painter.drawImage(0, 0, m_image) self.marvin_cover.setPixmap(self.m_pixmap) else: # No cover available, use generic self._log("No cached cover, using generic") pixmap = QPixmap() pixmap.load(I('book.png')) pixmap = pixmap.scaled(self.COVER_ICON_SIZE, self.COVER_ICON_SIZE, aspectRatioMode=Qt.KeepAspectRatio, transformMode=Qt.SmoothTransformation) self.marvin_cover.setPixmap(pixmap)
def _populate_covers(self): ''' Display calibre cover for both unless mismatch ''' def _fetch_marvin_cover(border_width=0): ''' Retrieve LargeCoverJpg from cache ''' #self._log_location('border_width: {0}'.format(border_width)) con = sqlite3.connect(self.marvin_db_path) with con: con.row_factory = sqlite3.Row # Fetch Hash from mainDb cover_cur = con.cursor() cover_cur.execute('''SELECT Hash FROM Books WHERE ID = '{0}' '''.format(self.book_id)) row = cover_cur.fetchone() book_hash = row[b'Hash'] large_covers_subpath = self.connected_device._cover_subpath( size="large") cover_path = '/'.join([large_covers_subpath, '%s.jpg' % book_hash]) stats = self.parent.ios.exists(cover_path) if stats: self._log("fetching large cover from cache") #self._log("cover size: {:,} bytes".format(int(stats['st_size']))) cover_bytes = self.parent.ios.read(cover_path, mode='rb') m_image = QImage() m_image.loadFromData(cover_bytes) if border_width: # Construct a QPixmap with oversized yellow background m_image = m_image.scaledToHeight( self.COVER_ICON_SIZE - border_width * 2, Qt.SmoothTransformation) self.m_pixmap = QPixmap( QSize(m_image.width() + border_width * 2, m_image.height() + border_width * 2)) m_painter = QPainter(self.m_pixmap) m_painter.setRenderHints(m_painter.Antialiasing) m_painter.fillRect(self.m_pixmap.rect(), self.MISMATCH_COLOR) m_painter.drawImage(border_width, border_width, m_image) else: m_image = m_image.scaledToHeight(self.COVER_ICON_SIZE, Qt.SmoothTransformation) self.m_pixmap = QPixmap( QSize(m_image.width(), m_image.height())) m_painter = QPainter(self.m_pixmap) m_painter.setRenderHints(m_painter.Antialiasing) m_painter.drawImage(0, 0, m_image) self.marvin_cover.setPixmap(self.m_pixmap) else: # No cover available, use generic self._log("No cached cover, using generic") pixmap = QPixmap() pixmap.load(I('book.png')) pixmap = pixmap.scaled(self.COVER_ICON_SIZE, self.COVER_ICON_SIZE, aspectRatioMode=Qt.KeepAspectRatio, transformMode=Qt.SmoothTransformation) self.marvin_cover.setPixmap(pixmap) self.calibre_cover.setMaximumSize( QSize(self.COVER_ICON_SIZE, self.COVER_ICON_SIZE)) self.calibre_cover.setText('') self.calibre_cover.setScaledContents(False) self.marvin_cover.setMaximumSize( QSize(self.COVER_ICON_SIZE, self.COVER_ICON_SIZE)) self.marvin_cover.setText('') self.marvin_cover.setScaledContents(False) if self.cid: db = self.opts.gui.current_db if 'cover_hash' not in self.mismatches: mi = db.get_metadata(self.cid, index_is_id=True, get_cover=True, cover_as_data=True) c_image = QImage() if mi.has_cover: c_image.loadFromData(mi.cover_data[1]) c_image = c_image.scaledToHeight(self.COVER_ICON_SIZE, Qt.SmoothTransformation) self.c_pixmap = QPixmap( QSize(c_image.width(), c_image.height())) c_painter = QPainter(self.c_pixmap) c_painter.setRenderHints(c_painter.Antialiasing) c_painter.drawImage(0, 0, c_image) else: c_image.load(I('book.png')) c_image = c_image.scaledToWidth(135, Qt.SmoothTransformation) # Construct a QPixmap with dialog background self.c_pixmap = QPixmap( QSize(c_image.width(), c_image.height())) c_painter = QPainter(self.c_pixmap) c_painter.setRenderHints(c_painter.Antialiasing) bgcolor = self.palette().color(QPalette.Background) c_painter.fillRect(self.c_pixmap.rect(), bgcolor) c_painter.drawImage(0, 0, c_image) # Set calibre cover self.calibre_cover.setPixmap(self.c_pixmap) if self.opts.prefs.get('development_mode', False): # Show individual covers _fetch_marvin_cover() else: # Show calibre cover on both sides self.marvin_cover.setPixmap(self.c_pixmap) else: # Covers don't match - render with border # Construct a QImage with the cover sized to fit inside border c_image = QImage() cdata = db.cover(self.cid, index_is_id=True) if cdata is None: c_image.load(I('book.png')) self.calibre_cover.setScaledContents(True) else: c_image.loadFromData(cdata) c_image = c_image.scaledToHeight( self.COVER_ICON_SIZE - self.BORDER_WIDTH * 2, Qt.SmoothTransformation) # Construct a QPixmap with yellow background self.c_pixmap = QPixmap( QSize(c_image.width() + self.BORDER_WIDTH * 2, c_image.height() + self.BORDER_WIDTH * 2)) c_painter = QPainter(self.c_pixmap) c_painter.setRenderHints(c_painter.Antialiasing) c_painter.fillRect(self.c_pixmap.rect(), self.MISMATCH_COLOR) c_painter.drawImage(self.BORDER_WIDTH, self.BORDER_WIDTH, c_image) self.calibre_cover.setPixmap(self.c_pixmap) # Render Marvin cover with small border if different covers, # large cover if no cover hash (loaded via OPDS) border_width = self.BORDER_WIDTH if self.mismatches['cover_hash']['Marvin'] is None: border_width = self.BORDER_WIDTH * 3 _fetch_marvin_cover(border_width=border_width) else: _fetch_marvin_cover()
def run(self): time.sleep(0.5) # create hash dict of current list self._hash_item_dict = {} for item in self._item_list: self._hash_item_dict[item.hash] = item # compare and swap between lists if new item is not generated for new_hash in self._hash_item_dict.keys(): if new_hash in self._old_hash_item_dict.keys(): # swap to avoid generating uselessly : self._hash_item_dict[new_hash] = self._old_hash_item_dict[ new_hash] else: # generate _ = self._hash_item_dict[new_hash].image # append generated images # images_list.append() pix_list = [] for new_item in self._item_list: usable_item = self._hash_item_dict[new_item.hash] pix_list.append(usable_item.image) # draw pixmaps in one : image = QImage(20, 20, QImage.Format_ARGB32_Premultiplied) image.fill(Qt.white) point = QPoint(0, 0) width_list = [pix.width() for pix in pix_list] max_width = max(width_list) self._max_width_found = max([max_width, self._max_width_found]) for pix in pix_list: last_image = image image = QImage(self._max_width_found, image.height() + pix.height(), QImage.Format_ARGB32_Premultiplied) pix_paint = QPainter(image) image.fill(Qt.white) pix_paint.drawImage(0, 0, last_image) pix_paint.drawImage(point, pix) point = QPoint(0, point.y() + pix.height()) pix_paint.end() ''' pixmap = QImage(21,21, QImage.Format_ARGB32_Premultiplied) # temp pixPaint = QPainter(pixmap) myPen = QPen( Qt.black) pixPaint.setPen(myPen) pixPaint.drawRect(0,0, 20,20); pixPaint.end() image = pixmap painter.drawImage(point, pix) point = QPoint(0, point.y() + pix.height()) painter.end() ''' final_pixmap = QPixmap.fromImage(image, Qt.AutoColor) self.image_generated.emit(final_pixmap) self._old_item_list = self._item_list self._old_hash_item_dict = self._hash_item_dict
class Window: def __init__(self): # ------------------------ # Set flags # ------------------------ self.UP = True self.DOWN = False self.ALL_IMG_FORMAT = "All Supported (*.jpg *.jpeg *.jpe *.png *.bmp *.tif *.tiff " \ "*.dib *.pbm *.pgm *.ppm *.sr *.ras)" self.JPG_FORMAT = "JPG (*.jpg *.jpeg *.jpe)" self.PNG_FORMAT = "PNG (*.png)" self.BMP_FORMAT = "BMP (*.bmp)" self.TIF_FORMAT = "TIFF (*.tif *.tiff)" self.DIB_FORMAT = "DIB (*.dib)" self.PBM_FORMAT = "PBM (*.pbm)" self.PGM_FORMAT = "PGM (*.pgm)" self.PPM_FORMAT = "PPM (*.ppm)" self.SR__FORMAT = "SR (*.sr)" self.RAS_FORMAT = "RAS (*.ras)" self.DD = ";;" self.IMG_FILTER = self.ALL_IMG_FORMAT + self.DD + self.JPG_FORMAT + self.DD + self.PNG_FORMAT + self.DD + \ self.BMP_FORMAT + self.DD + self.TIF_FORMAT + self.DD + self.DIB_FORMAT + self.DD + \ self.PBM_FORMAT + self.DD + self.PGM_FORMAT + self.DD + self.PPM_FORMAT + self.DD + \ self.SR__FORMAT + self.DD + self.RAS_FORMAT self.DIALOG_FLAG = QFileDialog.DontUseNativeDialog self.Q_ASPECT_RATIO = Qt.KeepAspectRatio # ------------------------ # Flags Section ends here # ---------------------------------------------------------------------------------------------------------- # # ------------------------ # Set class items # ------------------------ self.q_img = QImage() self.img_view_timer = QTimer() self.img = Image() self.img_proc = ImageProcessing() self.is_img_Open = False self.is_img_Save = False # ------------------------ # Class items ends here # ---------------------------------------------------------------------------------------------------------- # # ------------------------ # Set up the ui # ------------------------ self.app = QtWidgets.QApplication(sys.argv) self.ui = Ui_MainWindow() self.MainWindow = QtWidgets.QMainWindow() self.ui.setupUi(self.MainWindow) self.DialogColor = QtWidgets.QDialog() self.ui_color = Ui_DialogColoring() self.ui_color.setupUi(self.DialogColor) # ------------------------ # Setting up ends here # ---------------------------------------------------------------------------------------------------------- # # ------------------------ # Actions list starts here # ------------------------ self.ui.actionOpen.triggered.connect(self.open) self.ui.actionSave.triggered.connect(self.save) self.ui.actionSave_as.triggered.connect(self.save_as) self.ui.actionExit.triggered.connect(self.exit_window) self.ui.actionLight_Contrast.triggered.connect( self.open_color_light_dialog) self.ui.light_spinbox.valueChanged.connect( self.light_spinbox_value_changed) self.ui.contrast_spinbox.valueChanged.connect( self.contrast_spinbox_value_changed) self.img_view_timer.timeout.connect(self.update_img_view) self.img_view_timer.start(250) self.ui_color.l_radio_all_bands.clicked.connect( self.dialog_color_light_all_checked) self.ui_color.l_radio_rgb.clicked.connect( self.dialog_color_light_rgb_checked) self.ui_color.c_radio_all_bands.clicked.connect( self.dialog_color_contrast_all_checked) self.ui_color.c_radio_rgb.clicked.connect( self.dialog_color_contrast_rgb_checked) self.ui_color.cancel_button.clicked.connect(self.dialog_color_cancel) self.ui_color.compute_button.clicked.connect(self.dialog_color_compute) # ------------------------ # Actions list ends here # ---------------------------------------------------------------------------------------------------------- # # ------------------------ # Main loop and exit app # ------------------------ self.MainWindow.show() sys.exit(self.app.exec_()) # ------------------------ # END OF APPLICATION # ---------------------------------------------------------------------------------------------------------- # def enable_options(self): # Enable Menu/Actions self.ui.actionSave.setEnabled(self.UP) self.ui.actionSave_as.setEnabled(self.UP) self.ui.menuFilters.setEnabled(self.UP) self.ui.menuTransformations.setEnabled(self.UP) # Enable Spinbox self.ui.light_spinbox.setEnabled(self.UP) self.ui.light_spinbox.setValue(0) self.ui.contrast_spinbox.setEnabled(self.UP) self.ui.contrast_spinbox.setValue(1.0) def update_img_view(self): if self.is_img_Open: #print(self.ui.img_view.size()) width = self.ui.img_view.width() height = self.ui.img_view.height() if self.img.width < width or self.img.height < height: width = self.q_img.width() height = self.q_img.height() size = QSize(width, height) pixmap = QPixmap() pixmap = pixmap.fromImage(self.q_img) pixmap = pixmap.scaled(size, self.Q_ASPECT_RATIO) self.ui.img_view.setPixmap(pixmap) self.ui.img_view.show() def open_img_path(self): """ Open the dialog and take the path. :return: True/False, path_string/empty_string """ file_dialog = QFileDialog() f_path = file_dialog.getOpenFileName(parent=None, caption="Open Image", directory=QDir.homePath(), filter=self.IMG_FILTER, initialFilter="", options=self.DIALOG_FLAG)[0] if f_path: return True, f_path return False, "" def save_img_path(self): """ Open the dialog and take the path. :return: True/False, path_string/empty_string """ file_dialog = QFileDialog() f_path = file_dialog.getSaveFileName(parent=None, caption="Save Image as", directory=QDir.homePath(), filter=self.IMG_FILTER, initialFilter="", options=self.DIALOG_FLAG)[0] if f_path: return True, f_path return False, "" def open(self): """ Open an image and create a QImage() item for view. :return: Nothing """ self.is_img_Open, f_path = self.open_img_path( ) # Open dialog and take the path if self.is_img_Open: # Check if user gave a path or not (aka pressed "Open" or "Cancel" self.img.open_image_from(f_path) # Open image self.img.print_img_info() # Print info for debugging # Transform Image() to QImage() bytes_per_line = 3 * self.img.width self.img.set_img_tmp(self.img.img) self.q_img = QImage(self.img.img_tmp_RGB(), self.img.width, self.img.height, bytes_per_line, QImage.Format_RGB888) self.enable_options() # Enable all image processing utilities def save(self): """ Save an image to a given path. (If image has already been saved to a path reuses this path) :return: Nothing """ if not self.is_img_Save: self.save_as() # Open dialog and take the path else: # Check if user gave a path or not (aka pressed "Open" or "Cancel") self.img.set_img_from_img_tmp() self.img.save_image() def save_as(self): """ Save an image to a given path. (Asks every time the user to specify a path) :return: Nothing """ self.is_img_Save, f_path = self.save_img_path( ) # Open dialog and take the path if self.is_img_Save: # Check if user gave a path or not (aka pressed "Open" or "Cancel" self.img.set_img_from_img_tmp() self.img.save_image_as(f_path) def exit_window(self): """ Signal exit application :return: Nothing """ self.MainWindow.close() # Close The window def light_spinbox_value_changed(self): self.img_proc.set_light(self.ui.light_spinbox.value()) self.ui_color.l_spin_light_for_all.setValue( self.ui.light_spinbox.value()) img_rgb = self.img.img_RGB() img_rgb = self.img_proc.compute_light_contrast(img_rgb) self.img.set_img_tmp(self.img.img_RGB2BGR(img_rgb)) bytes_per_line = 3 * self.img.width self.q_img = QImage(self.img.img_tmp_RGB(), self.img.width, self.img.height, bytes_per_line, QImage.Format_RGB888) def contrast_spinbox_value_changed(self): self.img_proc.set_contrast(self.ui.contrast_spinbox.value()) self.ui_color.c_contrast_for_all.setValue( self.ui.contrast_spinbox.value()) img_rgb = self.img.img_RGB() img_rgb = self.img_proc.compute_light_contrast(img_rgb) self.img.set_img_tmp(self.img.img_RGB2BGR(img_rgb)) bytes_per_line = 3 * self.img.width self.q_img = QImage(self.img.img_tmp_RGB(), self.img.width, self.img.height, bytes_per_line, QImage.Format_RGB888) def open_color_light_dialog(self): self.DialogColor.show() def dialog_color_cancel(self): self.DialogColor.close() def dialog_color_light_all_checked(self): self.ui_color.l_all_bands_widget.setEnabled(self.UP) self.ui_color.l_rgb_widget.setEnabled(self.DOWN) def dialog_color_light_rgb_checked(self): self.ui_color.l_all_bands_widget.setEnabled(self.DOWN) self.ui_color.l_rgb_widget.setEnabled(self.UP) self.img_proc.set_default_light_contrast_rgb() def dialog_color_contrast_all_checked(self): self.ui_color.c_all_bands_widget.setEnabled(self.UP) self.ui_color.c_rgb_widget.setEnabled(self.DOWN) def dialog_color_contrast_rgb_checked(self): self.ui_color.c_all_bands_widget.setEnabled(self.DOWN) self.ui_color.c_rgb_widget.setEnabled(self.UP) def dialog_color_compute(self): if self.ui_color.l_radio_all_bands.isChecked(): self.img_proc.set_light(self.ui_color.l_spin_light_for_all.value()) self.ui_color.l_spin_red.setValue( self.ui_color.l_spin_light_for_all.value()) self.ui_color.l_spin_green.setValue( self.ui_color.l_spin_light_for_all.value()) self.ui_color.l_spin_blue.setValue( self.ui_color.l_spin_light_for_all.value()) self.ui.light_spinbox.setValue( self.ui_color.l_spin_light_for_all.value()) img_rgb = self.img.img_RGB() img_rgb = self.img_proc.compute_light_contrast(img_rgb) self.img.set_img_tmp(self.img.img_RGB2BGR(img_rgb)) if self.ui_color.c_radio_all_bands.isChecked(): self.img_proc.set_contrast(self.ui.contrast_spinbox.value()) self.ui.contrast_spinbox.setValue( self.ui_color.c_contrast_for_all.value()) self.ui_color.c_double_spin_red.setValue( self.ui_color.c_contrast_for_all.value()) self.ui_color.c_double_spin_green.setValue( self.ui_color.c_contrast_for_all.value()) self.ui_color.c_double_spin_blue.setValue( self.ui_color.c_contrast_for_all.value()) img_rgb = self.img.img_RGB() img_rgb = self.img_proc.compute_light_contrast(img_rgb) self.img.set_img_tmp(self.img.img_RGB2BGR(img_rgb)) if self.ui_color.l_radio_rgb.isChecked( ) or self.ui_color.c_radio_rgb.isChecked(): self.img_proc.set_light_contrast_rgb( self.ui_color.l_spin_red.value(), self.ui_color.l_spin_green.value(), self.ui_color.l_spin_blue.value(), self.ui_color.c_double_spin_red.value(), self.ui_color.c_double_spin_green.value(), self.ui_color.c_double_spin_blue.value()) img_rgb = self.img.img_RGB() img_rgb = self.img_proc.compute_light_contrast_per_channel(img_rgb) self.img.set_img_tmp(self.img.img_RGB2BGR(img_rgb)) bytes_per_line = 3 * self.img.width self.q_img = QImage(self.img.img_tmp_RGB(), self.img.width, self.img.height, bytes_per_line, QImage.Format_RGB888) self.img_proc.compute_light_contrast_per_channel(self.img.img_tmp) bytes_per_line = 3 * self.img.width self.q_img = QImage(self.img.img_tmp_RGB(), self.img.width, self.img.height, bytes_per_line, QImage.Format_RGB888)
def run(self): time.sleep(0.5) # create hash dict of current list self._hash_item_dict = {} for item in self._item_list: self._hash_item_dict[item.hash] = item # compare and swap between lists if new item is not generated for new_hash in self._hash_item_dict.keys(): if new_hash in self._old_hash_item_dict.keys(): # swap to avoid generating uselessly : self._hash_item_dict[ new_hash] = self._old_hash_item_dict[new_hash] else: # generate _ = self._hash_item_dict[new_hash].image # append generated images # images_list.append() pix_list = [] for new_item in self._item_list: usable_item = self._hash_item_dict[new_item.hash] pix_list.append(usable_item.image) # draw pixmaps in one : image = QImage(20, 20, QImage.Format_ARGB32_Premultiplied) image.fill(Qt.white) point = QPoint(0, 0) width_list = [pix.width() for pix in pix_list] max_width = max(width_list) self._max_width_found = max([max_width, self._max_width_found]) for pix in pix_list: last_image = image image = QImage(self._max_width_found, image.height( ) + pix.height(), QImage.Format_ARGB32_Premultiplied) pix_paint = QPainter(image) image.fill(Qt.white) pix_paint.drawImage(0, 0, last_image) pix_paint.drawImage(point, pix) point = QPoint(0, point.y() + pix.height()) pix_paint.end() ''' pixmap = QImage(21,21, QImage.Format_ARGB32_Premultiplied) # temp pixPaint = QPainter(pixmap) myPen = QPen( Qt.black) pixPaint.setPen(myPen) pixPaint.drawRect(0,0, 20,20); pixPaint.end() image = pixmap painter.drawImage(point, pix) point = QPoint(0, point.y() + pix.height()) painter.end() ''' final_pixmap = QPixmap.fromImage(image, Qt.AutoColor) self.image_generated.emit(final_pixmap) self._old_item_list = self._item_list self._old_hash_item_dict = self._hash_item_dict
def _fetch_marvin_cover(border_width=0): ''' Retrieve LargeCoverJpg from cache ''' #self._log_location('border_width: {0}'.format(border_width)) con = sqlite3.connect(self.marvin_db_path) with con: con.row_factory = sqlite3.Row # Fetch Hash from mainDb cover_cur = con.cursor() cover_cur.execute('''SELECT Hash FROM Books WHERE ID = '{0}' '''.format(self.book_id)) row = cover_cur.fetchone() book_hash = row[b'Hash'] large_covers_subpath = self.connected_device._cover_subpath(size="large") cover_path = '/'.join([large_covers_subpath, '%s.jpg' % book_hash]) stats = self.parent.ios.exists(cover_path) if stats: self._log("fetching large cover from cache") #self._log("cover size: {:,} bytes".format(int(stats['st_size']))) cover_bytes = self.parent.ios.read(cover_path, mode='rb') m_image = QImage() m_image.loadFromData(cover_bytes) if border_width: # Construct a QPixmap with oversized yellow background m_image = m_image.scaledToHeight( self.COVER_ICON_SIZE - border_width * 2, Qt.SmoothTransformation) self.m_pixmap = QPixmap( QSize(m_image.width() + border_width * 2, m_image.height() + border_width * 2)) m_painter = QPainter(self.m_pixmap) m_painter.setRenderHints(m_painter.Antialiasing) m_painter.fillRect(self.m_pixmap.rect(), self.MISMATCH_COLOR) m_painter.drawImage(border_width, border_width, m_image) else: m_image = m_image.scaledToHeight( self.COVER_ICON_SIZE, Qt.SmoothTransformation) self.m_pixmap = QPixmap( QSize(m_image.width(), m_image.height())) m_painter = QPainter(self.m_pixmap) m_painter.setRenderHints(m_painter.Antialiasing) m_painter.drawImage(0, 0, m_image) self.marvin_cover.setPixmap(self.m_pixmap) else: # No cover available, use generic self._log("No cached cover, using generic") pixmap = QPixmap() pixmap.load(I('book.png')) pixmap = pixmap.scaled(self.COVER_ICON_SIZE, self.COVER_ICON_SIZE, aspectRatioMode=Qt.KeepAspectRatio, transformMode=Qt.SmoothTransformation) self.marvin_cover.setPixmap(pixmap)
def _populate_covers(self): ''' Display calibre cover for both unless mismatch ''' def _fetch_marvin_cover(border_width=0): ''' Retrieve LargeCoverJpg from cache ''' #self._log_location('border_width: {0}'.format(border_width)) con = sqlite3.connect(self.marvin_db_path) with con: con.row_factory = sqlite3.Row # Fetch Hash from mainDb cover_cur = con.cursor() cover_cur.execute('''SELECT Hash FROM Books WHERE ID = '{0}' '''.format(self.book_id)) row = cover_cur.fetchone() book_hash = row[b'Hash'] large_covers_subpath = self.connected_device._cover_subpath(size="large") cover_path = '/'.join([large_covers_subpath, '%s.jpg' % book_hash]) stats = self.parent.ios.exists(cover_path) if stats: self._log("fetching large cover from cache") #self._log("cover size: {:,} bytes".format(int(stats['st_size']))) cover_bytes = self.parent.ios.read(cover_path, mode='rb') m_image = QImage() m_image.loadFromData(cover_bytes) if border_width: # Construct a QPixmap with oversized yellow background m_image = m_image.scaledToHeight( self.COVER_ICON_SIZE - border_width * 2, Qt.SmoothTransformation) self.m_pixmap = QPixmap( QSize(m_image.width() + border_width * 2, m_image.height() + border_width * 2)) m_painter = QPainter(self.m_pixmap) m_painter.setRenderHints(m_painter.Antialiasing) m_painter.fillRect(self.m_pixmap.rect(), self.MISMATCH_COLOR) m_painter.drawImage(border_width, border_width, m_image) else: m_image = m_image.scaledToHeight( self.COVER_ICON_SIZE, Qt.SmoothTransformation) self.m_pixmap = QPixmap( QSize(m_image.width(), m_image.height())) m_painter = QPainter(self.m_pixmap) m_painter.setRenderHints(m_painter.Antialiasing) m_painter.drawImage(0, 0, m_image) self.marvin_cover.setPixmap(self.m_pixmap) else: # No cover available, use generic self._log("No cached cover, using generic") pixmap = QPixmap() pixmap.load(I('book.png')) pixmap = pixmap.scaled(self.COVER_ICON_SIZE, self.COVER_ICON_SIZE, aspectRatioMode=Qt.KeepAspectRatio, transformMode=Qt.SmoothTransformation) self.marvin_cover.setPixmap(pixmap) self.calibre_cover.setMaximumSize(QSize(self.COVER_ICON_SIZE, self.COVER_ICON_SIZE)) self.calibre_cover.setText('') self.calibre_cover.setScaledContents(False) self.marvin_cover.setMaximumSize(QSize(self.COVER_ICON_SIZE, self.COVER_ICON_SIZE)) self.marvin_cover.setText('') self.marvin_cover.setScaledContents(False) if self.cid: db = self.opts.gui.current_db if 'cover_hash' not in self.mismatches: mi = db.get_metadata(self.cid, index_is_id=True, get_cover=True, cover_as_data=True) c_image = QImage() if mi.has_cover: c_image.loadFromData(mi.cover_data[1]) c_image = c_image.scaledToHeight(self.COVER_ICON_SIZE, Qt.SmoothTransformation) self.c_pixmap = QPixmap(QSize(c_image.width(), c_image.height())) c_painter = QPainter(self.c_pixmap) c_painter.setRenderHints(c_painter.Antialiasing) c_painter.drawImage(0, 0, c_image) else: c_image.load(I('book.png')) c_image = c_image.scaledToWidth(135, Qt.SmoothTransformation) # Construct a QPixmap with dialog background self.c_pixmap = QPixmap( QSize(c_image.width(), c_image.height())) c_painter = QPainter(self.c_pixmap) c_painter.setRenderHints(c_painter.Antialiasing) bgcolor = self.palette().color(QPalette.Background) c_painter.fillRect(self.c_pixmap.rect(), bgcolor) c_painter.drawImage(0, 0, c_image) # Set calibre cover self.calibre_cover.setPixmap(self.c_pixmap) if self.opts.prefs.get('development_mode', False): # Show individual covers _fetch_marvin_cover() else: # Show calibre cover on both sides self.marvin_cover.setPixmap(self.c_pixmap) else: # Covers don't match - render with border # Construct a QImage with the cover sized to fit inside border c_image = QImage() cdata = db.cover(self.cid, index_is_id=True) if cdata is None: c_image.load(I('book.png')) self.calibre_cover.setScaledContents(True) else: c_image.loadFromData(cdata) c_image = c_image.scaledToHeight( self.COVER_ICON_SIZE - self.BORDER_WIDTH * 2, Qt.SmoothTransformation) # Construct a QPixmap with yellow background self.c_pixmap = QPixmap( QSize(c_image.width() + self.BORDER_WIDTH * 2, c_image.height() + self.BORDER_WIDTH * 2)) c_painter = QPainter(self.c_pixmap) c_painter.setRenderHints(c_painter.Antialiasing) c_painter.fillRect(self.c_pixmap.rect(),self.MISMATCH_COLOR) c_painter.drawImage(self.BORDER_WIDTH, self.BORDER_WIDTH, c_image) self.calibre_cover.setPixmap(self.c_pixmap) # Render Marvin cover with small border if different covers, # large cover if no cover hash (loaded via OPDS) border_width = self.BORDER_WIDTH if self.mismatches['cover_hash']['Marvin'] is None: border_width = self.BORDER_WIDTH * 3 _fetch_marvin_cover(border_width=border_width) else: _fetch_marvin_cover()