def image_to_data(img, compression_quality=95, fmt='JPEG', png_compression_level=9, jpeg_optimized=True, jpeg_progressive=False): ''' Serialize image to bytestring in the specified format. :param compression_quality: is for JPEG and goes from 0 to 100. 100 being lowest compression, highest image quality :param png_compression_level: is for PNG and goes from 0-9. 9 being highest compression. :param jpeg_optimized: Turns on the 'optimize' option for libjpeg which losslessly reduce file size :param jpeg_progressive: Turns on the 'progressive scan' option for libjpeg which allows JPEG images to be downloaded in streaming fashion ''' ba = QByteArray() buf = QBuffer(ba) buf.open(QBuffer.WriteOnly) fmt = fmt.upper() is_jpeg = fmt in ('JPG', 'JPEG') w = QImageWriter(buf, fmt.encode('ascii')) if is_jpeg: if img.hasAlphaChannel(): img = blend_image(img) # QImageWriter only gained the following options in Qt 5.5 if jpeg_optimized and hasattr(QImageWriter, 'setOptimizedWrite'): w.setOptimizedWrite(True) if jpeg_progressive and hasattr(QImageWriter, 'setProgressiveScanWrite'): w.setProgressiveScanWrite(True) w.setQuality(compression_quality) elif fmt == 'PNG': cl = min(9, max(0, png_compression_level)) w.setQuality(10 * (9-cl)) if not w.write(img): raise ValueError('Failed to export image as ' + fmt + ' with error: ' + w.errorString()) return ba.data()
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 __call__(self, ok): from PyQt5.Qt import QImage, QPainter, QByteArray, QBuffer try: if not ok: raise RuntimeError('Rendering of HTML failed.') de = self.page.mainFrame().documentElement() pe = de.findFirst('parsererror') if not pe.isNull(): raise ParserError(pe.toPlainText()) image = QImage(self.page.viewportSize(), QImage.Format_ARGB32) image.setDotsPerMeterX(96*(100/2.54)) image.setDotsPerMeterY(96*(100/2.54)) painter = QPainter(image) self.page.mainFrame().render(painter) painter.end() ba = QByteArray() buf = QBuffer(ba) buf.open(QBuffer.WriteOnly) image.save(buf, 'JPEG') self.data = str(ba.data()) except Exception as e: self.exception = e self.traceback = traceback.format_exc() finally: self.loop.exit(0)
def icon_to_dbus_menu_icon(icon, size=32): if icon.isNull(): return None ba = QByteArray() buf = QBuffer(ba) buf.open(QBuffer.WriteOnly) icon.pixmap(32).save(buf, 'PNG') return dbus.ByteArray(bytes((ba.data())))
def pixmap_to_data(pixmap, format='PNG'): ''' Return the QPixmap pixmap as a string saved in the specified format. ''' ba = QByteArray() buf = QBuffer(ba) buf.open(QBuffer.WriteOnly) pixmap.save(buf, format) return bytes(ba.data())
def image_to_data(image): # {{{ ba = QByteArray() buf = QBuffer(ba) buf.open(QBuffer.WriteOnly) if not image.save(buf, CACHE_FORMAT): raise EncodeError('Failed to encode thumbnail') ret = bytes(ba.data()) buf.close() return ret
def pixmap_to_data(pixmap, format='JPEG', quality=90): ''' Return the QPixmap pixmap as a string saved in the specified format. ''' ba = QByteArray() buf = QBuffer(ba) buf.open(QBuffer.WriteOnly) pixmap.save(buf, format, quality=quality) return bytes(ba.data())
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 to_png(bmp): from PyQt5.Qt import QImage, QByteArray, QBuffer i = QImage() if not i.loadFromData(bmp): raise ValueError('Invalid image data') ba = QByteArray() buf = QBuffer(ba) buf.open(QBuffer.WriteOnly) i.save(buf, 'png') return bytes(ba.data())
def to_png(bmp): from PyQt5.Qt import QImage, QByteArray, QBuffer i = QImage() if not i.loadFromData(bmp): raise ValueError('Invalid image data') ba = QByteArray() buf = QBuffer(ba) buf.open(QBuffer.WriteOnly) i.save(buf, 'png') return ba.data()
def clear(self): self.title = '' self.url = QUrl() self.icon = QIcon() self.history = QByteArray() self.isPinned = False self.zoomLevel = 1 self.parentTab = -1 self.childTabs = [] self.sessionData = {}
def __init__(self, urlOrReq=QUrl(), op=GetOperation, data=QByteArray()): if isinstance(urlOrReq, self.__class__): otherReq = urlOrReq self._url = QUrl(otherReq._url) self._op = otherReq._op self._data = QByteArray(otherReq._data) else: url = QUrl(urlOrReq) self._url = url self._op = op self._data = data
def pixmapToByteArray(self, pix): ''' @param: pix QPixmap @return: QByteArray ''' bytes_ = QByteArray() buffer_ = QBuffer(bytes_) buffer_.open(QIODevice.WriteOnly) if pix.save(buffer_, 'PNG'): return buffer_.buffer().toBase64() return QByteArray()
def restore_state(self): try: geom = gprefs.get('jobs_dialog_geometry', bytearray('')) self.restoreGeometry(QByteArray(geom)) state = gprefs.get('jobs view column layout2', bytearray('')) self.jobs_view.horizontalHeader().restoreState(QByteArray(state)) except: pass idx = self.jobs_view.model().index(0, 0) if idx.isValid(): sm = self.jobs_view.selectionModel() sm.select(idx, sm.ClearAndSelect | sm.Rows)
def __init__(self, window=None): ''' @param: window BrowserWindow ''' self.windowState = QByteArray() self.windowGeometry = QByteArray() self.windowUiState = {} # QString -> QVariant self.virtualDesktop = -1 self.currentTab = -1 self.tabs = [] # WebTab.SavedTab if window: self.init(window)
def __init__(self, webTab=None): self.title = '' self.url = QUrl() self.icon = QIcon() self.history = QByteArray() self.isPinned = False self.zoomLevel = 1 self.parentTab = -1 self.childTabs = [] self.sessionData = {} if webTab: self.setWebTab(webTab)
def encode_jpeg(file_path, quality=80): from calibre.utils.speedups import ReadOnlyFileBuffer quality = max(0, min(100, int(quality))) exe = get_exe_path('cjpeg') cmd = [exe] + '-optimize -progressive -maxmemory 100M -quality'.split() + [str(quality)] img = QImage() if not img.load(file_path): raise ValueError('%s is not a valid image file' % file_path) ba = QByteArray() buf = QBuffer(ba) buf.open(QBuffer.WriteOnly) if not img.save(buf, 'PPM'): raise ValueError('Failed to export image to PPM') return run_optimizer(file_path, cmd, as_filter=True, input_data=ReadOnlyFileBuffer(ba.data()))
def rasterize_svg(self, elem, width=0, height=0, format='PNG'): view_box = elem.get('viewBox', elem.get('viewbox', None)) sizes = None logger = self.oeb.logger if view_box is not None: try: box = [ float(x) for x in [_f for _f in re.split('[, ]', view_box) if _f] ] sizes = [box[2] - box[0], box[3] - box[1]] except (TypeError, ValueError, IndexError): logger.warn( 'SVG image has invalid viewBox="%s", ignoring the viewBox' % view_box) else: for image in elem.xpath( 'descendant::*[local-name()="image" and ' '@height and contains(@height, "%")]'): logger.info( 'Found SVG image height in %, trying to convert...') try: h = float(image.get('height').replace('%', '')) / 100. image.set('height', str(h * sizes[1])) except: logger.exception( 'Failed to convert percentage height:', image.get('height')) data = QByteArray(xml2str(elem, with_tail=False)) svg = QSvgRenderer(data) size = svg.defaultSize() if size.width() == 100 and size.height() == 100 and sizes: size.setWidth(sizes[0]) size.setHeight(sizes[1]) if width or height: size.scale(width, height, Qt.KeepAspectRatio) logger.info('Rasterizing %r to %dx%d' % (elem, size.width(), size.height())) image = QImage(size, QImage.Format_ARGB32_Premultiplied) image.fill(QColor("white").rgb()) painter = QPainter(image) svg.render(painter) painter.end() array = QByteArray() buffer = QBuffer(array) buffer.open(QIODevice.WriteOnly) image.save(buffer, format) return str(array)
class SavedWindow(object): def __init__(self, window=None): ''' @param: window BrowserWindow ''' self.windowState = QByteArray() self.windowGeometry = QByteArray() self.windowUiState = {} # QString -> QVariant self.virtualDesktop = -1 self.currentTab = -1 self.tabs = [] # WebTab.SavedTab if window: self.init(window) def init(self, window): if window.isFullScreen(): self.windowState = QByteArray() else: self.windowState = window.saveState() self.windowGeometry = window.saveGeometry() self.windowUiState = window._saveUiState() tabsCount = window.tabCount() for idx in range(tabsCount): # TabbedWebView webView = window.weView(idx) if not webView: continue webTab = webView.webTab() if not webTab: continue tab = WebTab.SavedTab(webTab) if not tab.isValid(): continue if webTab.isCurrentTab(): self.currentTab = len(self.tabs) self.tabs.append(tab) def isValid(self): for tab in self.tabs: if not tab.isValid(): return False return self.currentTab > -1 def clear(self): self.windowState.clear() self.windowGeometry.clear() self.virtualDesktop = -1 self.currentTab = -1 self.tabs.clear()
def restore_state(self): try: geom = gprefs.get('jobs_dialog_geometry', None) if geom: QApplication.instance().safe_restore_geometry(self, QByteArray(geom)) state = gprefs.get('jobs view column layout3', None) if state is not None: self.jobs_view.horizontalHeader().restoreState(QByteArray(state)) except: pass idx = self.jobs_view.model().index(0, 0) if idx.isValid(): sm = self.jobs_view.selectionModel() sm.select(idx, QItemSelectionModel.SelectionFlag.ClearAndSelect|QItemSelectionModel.SelectionFlag.Rows)
def image_to_data(img, compression_quality=95, fmt='JPEG'): ba = QByteArray() buf = QBuffer(ba) buf.open(QBuffer.WriteOnly) fmt = fmt.upper() if img.hasAlphaChannel() and fmt in 'JPEG JPG'.split(): nimg = QImage(img.size(), QImage.Format_RGB32) nimg.fill(Qt.white) p = QPainter(nimg) p.drawImage(0, 0, img) p.end() img = nimg if not img.save(buf, fmt, quality=compression_quality): raise ValueError('Failed to export image as ' + fmt) return ba.data()
def image_to_data(img, compression_quality=95, fmt='JPEG', png_compression_level=9, jpeg_optimized=True, jpeg_progressive=False): ''' Serialize image to bytestring in the specified format. :param compression_quality: is for JPEG and goes from 0 to 100. 100 being lowest compression, highest image quality :param png_compression_level: is for PNG and goes from 0-9. 9 being highest compression. :param jpeg_optimized: Turns on the 'optimize' option for libjpeg which losslessly reduce file size :param jpeg_progressive: Turns on the 'progressive scan' option for libjpeg which allows JPEG images to be downloaded in streaming fashion ''' fmt = fmt.upper() ba = QByteArray() buf = QBuffer(ba) buf.open(QBuffer.WriteOnly) if fmt == 'GIF': w = QImageWriter(buf, b'PNG') w.setQuality(90) if not w.write(img): raise ValueError('Failed to export image as ' + fmt + ' with error: ' + w.errorString()) from PIL import Image im = Image.open(BytesIO(ba.data())) buf = BytesIO() im.save(buf, 'gif') return buf.getvalue() is_jpeg = fmt in ('JPG', 'JPEG') w = QImageWriter(buf, fmt.encode('ascii')) if is_jpeg: if img.hasAlphaChannel(): img = blend_image(img) # QImageWriter only gained the following options in Qt 5.5 if jpeg_optimized and hasattr(QImageWriter, 'setOptimizedWrite'): w.setOptimizedWrite(True) if jpeg_progressive and hasattr(QImageWriter, 'setProgressiveScanWrite'): w.setProgressiveScanWrite(True) w.setQuality(compression_quality) elif fmt == 'PNG': cl = min(9, max(0, png_compression_level)) w.setQuality(10 * (9 - cl)) if not w.write(img): raise ValueError('Failed to export image as ' + fmt + ' with error: ' + w.errorString()) return ba.data()
def create_profile(): ans = getattr(create_profile, 'ans', None) if ans is None: ans = QWebEngineProfile(QApplication.instance()) osname = 'windows' if iswindows else ('macos' if ismacos else 'linux') # DO NOT change the user agent as it is used to workaround # Qt bugs see workaround_qt_bug() in ajax.pyj ua = 'calibre-viewer {} {}'.format(__version__, osname) ans.setHttpUserAgent(ua) if is_running_from_develop: from calibre.utils.rapydscript import compile_viewer prints('Compiling viewer code...') compile_viewer() js = P('viewer.js', data=True, allow_user_override=False) translations_json = get_translations_data() or b'null' js = js.replace(b'__TRANSLATIONS_DATA__', translations_json, 1) if in_develop_mode: js = js.replace(b'__IN_DEVELOP_MODE__', b'1') insert_scripts(ans, create_script('viewer.js', js)) url_handler = UrlSchemeHandler(ans) ans.installUrlSchemeHandler(QByteArray(FAKE_PROTOCOL.encode('ascii')), url_handler) s = ans.settings() s.setDefaultTextEncoding('utf-8') s.setAttribute(QWebEngineSettings.WebAttribute.LinksIncludedInFocusChain, False) create_profile.ans = ans return ans
def create_profile(): ans = getattr(create_profile, 'ans', None) if ans is None: ans = QWebEngineProfile(QApplication.instance()) ua = 'calibre-editor-preview ' + __version__ ans.setHttpUserAgent(ua) if is_running_from_develop: from calibre.utils.rapydscript import compile_editor compile_editor() js = P('editor.js', data=True, allow_user_override=False) cparser = P('csscolorparser.js', data=True, allow_user_override=False) insert_scripts( ans, create_script('csscolorparser.js', cparser), create_script('editor.js', js), ) url_handler = UrlSchemeHandler(ans) ans.installUrlSchemeHandler(QByteArray(FAKE_PROTOCOL.encode('ascii')), url_handler) s = ans.settings() s.setDefaultTextEncoding('utf-8') s.setAttribute(s.FullScreenSupportEnabled, False) s.setAttribute(s.LinksIncludedInFocusChain, False) create_profile.ans = ans return ans
def __init__(self, parent=None): super().__init__(parent) self._name = '' self._description = '' self._imageUrl = '' self._image = QImage() self._searchUrlTemplate = '' self._suggestionsUrlTemplate = '' self._searchParameters = [] # QList<Parameter> self._suggestionsParameters = [] # QList<Parameter> self._searchMethod = '' self._suggestionsMethod = '' self._preparedSuggestionsParameters = QByteArray() self._preparedSuggestionsUrl = '' self._requestMethods = { } # QMap<QString, QNetworkAccessManager::Operation> self._networkAccessManager = None # QNetworkAccessManager self._suggestionsReply = None # QNetworkReply self._delegate = None # OpenSearchEngineDelegate
def create_profile(): ans = getattr(create_profile, 'ans', None) if ans is None: ans = QWebEngineProfile(QApplication.instance()) ua = 'calibre-editor-preview ' + __version__ ans.setHttpUserAgent(ua) if is_running_from_develop: from calibre.utils.rapydscript import compile_editor compile_editor() js = P('editor.js', data=True, allow_user_override=False) cparser = P('csscolorparser.js', data=True, allow_user_override=False) dark_mode_css = P('dark_mode.css', data=True, allow_user_override=False).decode('utf-8') insert_scripts( ans, create_script('csscolorparser.js', cparser), create_script('editor.js', js), create_script('dark-mode.js', ''' (function() { var settings = JSON.parse(navigator.userAgent.split('|')[1]); var dark_css = CSS; function apply_body_colors(event) { if (document.documentElement) { if (settings.bg) document.documentElement.style.backgroundColor = settings.bg; if (settings.fg) document.documentElement.style.color = settings.fg; } if (document.body) { if (settings.bg) document.body.style.backgroundColor = settings.bg; if (settings.fg) document.body.style.color = settings.fg; } } function apply_css() { var css = ''; if (settings.link) css += 'html > body :link, html > body :link * { color: ' + settings.link + ' !important; }'; if (settings.is_dark_theme) { css += dark_css; } var style = document.createElement('style'); style.textContent = css; document.documentElement.appendChild(style); apply_body_colors(); } apply_body_colors(); document.addEventListener("DOMContentLoaded", apply_css); })(); '''.replace('CSS', json.dumps(dark_mode_css), 1), injection_point=QWebEngineScript.InjectionPoint. DocumentCreation)) url_handler = UrlSchemeHandler(ans) ans.installUrlSchemeHandler(QByteArray(FAKE_PROTOCOL.encode('ascii')), url_handler) s = ans.settings() s.setDefaultTextEncoding('utf-8') s.setAttribute(s.FullScreenSupportEnabled, False) s.setAttribute(s.LinksIncludedInFocusChain, False) create_profile.ans = ans return ans
def __init__(self): self.id = None self.host = '' self.username = '' self.password = '' self.data = QByteArray() self.updated = -1
def ins_image(self, image, fmt, width, height, insert_space=True): bytes_ = QByteArray() buffer = QBuffer(bytes_) buffer.open(QIODevice.WriteOnly) image.save(buffer, fmt) buffer.close() base64 = bytes_.toBase64().data().decode(encoding="utf-8") s = (f'<img width="{width}" height="{height}" ' f'src="data:image/{fmt};base64,{base64}"') self._text_edit_cursor.insertHtml(s) if insert_space: self._text_edit_cursor.insertText(" ")
def __init__(self, db, book_id, regex, doc=None, parent=None): QDialog.__init__(self, parent) self.setupUi(self) self.regex.setText(regex) self.regex_valid() if not db or not book_id: button = self.button_box.addButton(QDialogButtonBox.Open) button.clicked.connect(self.open_clicked) elif not doc and not self.select_format(db, book_id): self.cancelled = True return if doc: self.preview.setPlainText(doc) self.cancelled = False self.button_box.accepted.connect(self.accept) self.regex.textChanged[native_string_type].connect(self.regex_valid) for src, slot in (('test', 'do'), ('previous', 'goto'), ('next', 'goto')): getattr(self, src).clicked.connect(getattr(self, '%s_%s' % (slot, src))) self.test.setDefault(True) self.match_locs = [] geom = gprefs.get('regex_builder_geometry', None) if geom is not None: QApplication.instance().safe_restore_geometry( self, QByteArray(geom)) self.finished.connect(self.save_state)
def __init__(self, parent, cover_flow): QDialog.__init__(self, parent) self._layout = QStackedLayout() self.setLayout(self._layout) self.setWindowTitle(_('Browse by covers')) self.layout().addWidget(cover_flow) geom = gprefs.get('cover_browser_dialog_geometry', bytearray('')) geom = QByteArray(geom) if not self.restoreGeometry(geom): h, w = available_height()-60, int(available_width()/1.5) self.resize(w, h) self.action_fs_toggle = a = QAction(self) self.addAction(a) a.setShortcuts([QKeySequence('F11', QKeySequence.PortableText), QKeySequence('Ctrl+Shift+F', QKeySequence.PortableText)]) a.triggered.connect(self.toggle_fullscreen) self.action_esc_fs = a = QAction(self) a.triggered.connect(self.show_normal) self.addAction(a) a.setShortcuts([QKeySequence('Esc', QKeySequence.PortableText)]) self.pre_fs_geom = None cover_flow.setFocus(Qt.OtherFocusReason) self.view_action = a = QAction(self) iactions = parent.iactions self.addAction(a) a.setShortcuts(list(iactions['View'].menuless_qaction.shortcuts())+ [QKeySequence(Qt.Key_Space)]) a.triggered.connect(iactions['View'].menuless_qaction.trigger) self.sd_action = a = QAction(self) self.addAction(a) a.setShortcuts(list(iactions['Send To Device']. menuless_qaction.shortcuts())) a.triggered.connect(iactions['Send To Device'].menuless_qaction.trigger)
def load_html(path, view, codec='utf-8', mime_type=None, pre_load_callback=lambda x:None, path_is_html=False, force_as_html=False, loading_url=None): from PyQt5.Qt import QUrl, QByteArray if mime_type is None: mime_type = guess_type(path)[0] if not mime_type: mime_type = 'text/html' if path_is_html: html = path else: with open(path, 'rb') as f: html = f.read().decode(codec, 'replace') html = cleanup_html(html) loading_url = loading_url or QUrl.fromLocalFile(path) pre_load_callback(loading_url) if force_as_html or load_as_html(html): view.setHtml(html, loading_url) else: view.setContent(QByteArray(html.encode(codec)), mime_type, loading_url) mf = view.page().mainFrame() elem = mf.findFirstElement('parsererror') if not elem.isNull(): return False return True
def load_html(path, view, codec='utf-8', mime_type=None, pre_load_callback=lambda x:None, path_is_html=False, force_as_html=False): from PyQt5.Qt import QUrl, QByteArray if mime_type is None: mime_type = guess_type(path)[0] if not mime_type: mime_type = 'text/html' if path_is_html: html = path else: with open(path, 'rb') as f: html = f.read().decode(codec, 'replace') html = EntityDeclarationProcessor(html).processed_html self_closing_pat = re.compile(r'<\s*([:A-Za-z0-9-]+)([^>]*)/\s*>') html = self_closing_pat.sub(self_closing_sub, html) loading_url = QUrl.fromLocalFile(path) pre_load_callback(loading_url) if force_as_html or re.search(r'<[a-zA-Z0-9-]+:svg', html) is None and '<![CDATA[' not in html: view.setHtml(html, loading_url) else: view.setContent(QByteArray(html.encode(codec)), mime_type, loading_url) mf = view.page().mainFrame() elem = mf.findFirstElement('parsererror') if not elem.isNull(): return False return True
class SavedTab(object): def __init__(self, webTab=None): self.title = '' self.url = QUrl() self.icon = QIcon() self.history = QByteArray() self.isPinned = False self.zoomLevel = 1 self.parentTab = -1 self.childTabs = [] self.sessionData = {} if webTab: self.setWebTab(webTab) def __getstate__(self): result = dict(self.__dict__) result['url'] = result['url'].toEncoded() data = QByteArray() ds = QDataStream(data, QIODevice.WriteOnly) ds.writeQVariant(self.icon) result['icon'] = data.data() return result def __setstate__(self, state): for key, val in state.items(): if key == 'url': self.__dict__[key] = QUrl.fromEncoded(val) elif key == 'icon': ds = QDataStream(QByteArray(val)) self.__dict__[key] = ds.readQVariant() else: self.__dict__[key] = val def setWebTab(self, webTab): self.title = webTab.title() self.url = webTab.url() self.icon = webTab.icon() self.history = webTab.historyData() self.isPinned = webTab.isPinned() self.zoomLevel = webTab.zoomLevel() if webTab.parentTab(): self.parentTab = webTab.parentTab().tabIndex() else: self.parentTab = -1 self.childTabs = [ tab.tabIndex() for tab in webTab.childTabs() ] self.sessionData = webTab.sessionData() def isValid(self): return not self.url.isEmpty() or not self.history.isEmpty() def clear(self): self.title = '' self.url = QUrl() self.icon = QIcon() self.history = QByteArray() self.isPinned = False self.zoomLevel = 1 self.parentTab = -1 self.childTabs = [] self.sessionData = {}
def image_and_format_from_data(data): ' Create an image object from the specified data which should be a bytsestring 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
def icon_to_dbus_menu_icon(icon, size=32): if icon.isNull(): return None ba = QByteArray() buf = QBuffer(ba) buf.open(QBuffer.WriteOnly) icon.pixmap(32).save(buf, 'PNG') return dbus.ByteArray(ba)
def create_profile(parent=None, private=False): from .vise_scheme import UrlSchemeHandler from .url_intercept import Interceptor if parent is None: parent = QApplication.instance() if private: from .downloads import download_requested ans = QWebEngineProfile(parent) ans.downloadRequested.connect(download_requested) else: ans = QWebEngineProfile(appname, parent) ans.setCachePath(os.path.join(cache_dir, appname, 'cache')) safe_makedirs(ans.cachePath()) ans.setPersistentStoragePath( os.path.join(cache_dir, appname, 'storage')) safe_makedirs(ans.persistentStoragePath()) # TODO: Enable spellchecking when # https://bugreports.qt.io/browse/QTBUG-58512 is implemented. # See https://doc.qt.io/qt-5/qtwebengine-webenginewidgets-spellchecker-example.html for how to create the Qt .bdic files ua = ' '.join(x for x in ans.httpUserAgent().split() if 'QtWebEngine' not in x) ans.setHttpUserAgent(ua) ans.setRequestInterceptor(Interceptor(ans)) try: insert_scripts(ans, client_script()) except FileNotFoundError as err: if '-client.js' in str(err): raise SystemExit( 'You need to compile the rapydscript parts of vise before running it. Install rapydscript-ng and run the build script' ) raise ans.url_handler = UrlSchemeHandler(ans) ans.installUrlSchemeHandler(QByteArray(b'vise'), ans.url_handler) s = ans.settings() s.setDefaultTextEncoding('utf-8') s.setAttribute(s.FullScreenSupportEnabled, True) s.setAttribute(s.LinksIncludedInFocusChain, False) from .config import font_families, font_sizes for ftype, family in font_families().items(): if ftype != 'default' and family: ftype = ftype.replace('-', '').capitalize().replace( 'serif', 'Serif') + 'Font' ftype = getattr(s, ftype, None) if ftype: s.setFontFamily(ftype, family) for ftype, sz in font_sizes().items(): if sz > 0: ftype = { 'minimum': 'Minimum', 'minimum-logical': 'MinimumLogical', 'default-size': 'Default', 'default-monospace-size': 'DefaultFixed' }.get(ftype) if ftype: ftype = getattr(s, ftype + 'FontSize') s.setFontSize(ftype, sz) return ans
def pixmap_to_data(pixmap, format='JPEG', quality=None): ''' Return the QPixmap pixmap as a string saved in the specified format. ''' if quality is None: if format.upper() == "PNG": # For some reason on windows with Qt 5.6 using a quality of 90 # generates invalid PNG data. Many other quality values work # but we use -1 for the default quality which is most likely to # work quality = -1 else: quality = 90 ba = QByteArray() buf = QBuffer(ba) buf.open(QBuffer.WriteOnly) pixmap.save(buf, format, quality=quality) return bytes(ba.data())
def image_to_data( img, compression_quality=95, fmt="JPEG", png_compression_level=9, jpeg_optimized=True, jpeg_progressive=False ): """ Serialize image to bytestring in the specified format. :param compression_quality: is for JPEG and goes from 0 to 100. 100 being lowest compression, highest image quality :param png_compression_level: is for PNG and goes from 0-9. 9 being highest compression. :param jpeg_optimized: Turns on the 'optimize' option for libjpeg which losslessly reduce file size :param jpeg_progressive: Turns on the 'progressive scan' option for libjpeg which allows JPEG images to be downloaded in streaming fashion """ fmt = fmt.upper() ba = QByteArray() buf = QBuffer(ba) buf.open(QBuffer.WriteOnly) if fmt == "GIF": w = QImageWriter(buf, b"PNG") w.setQuality(90) if not w.write(img): raise ValueError("Failed to export image as " + fmt + " with error: " + w.errorString()) from PIL import Image im = Image.open(BytesIO(ba.data())) buf = BytesIO() im.save(buf, "gif") return buf.getvalue() is_jpeg = fmt in ("JPG", "JPEG") w = QImageWriter(buf, fmt.encode("ascii")) if is_jpeg: if img.hasAlphaChannel(): img = blend_image(img) # QImageWriter only gained the following options in Qt 5.5 if jpeg_optimized and hasattr(QImageWriter, "setOptimizedWrite"): w.setOptimizedWrite(True) if jpeg_progressive and hasattr(QImageWriter, "setProgressiveScanWrite"): w.setProgressiveScanWrite(True) w.setQuality(compression_quality) elif fmt == "PNG": cl = min(9, max(0, png_compression_level)) w.setQuality(10 * (9 - cl)) if not w.write(img): raise ValueError("Failed to export image as " + fmt + " with error: " + w.errorString()) return ba.data()
def to_png(bmp): # ImageMagick does not convert some bmp files correctly, while Qt does, # so try Qt first. See for instance: # https://bugs.launchpad.net/calibre/+bug/934167 # ImageMagick bug report: # http://www.imagemagick.org/discourse-server/viewtopic.php?f=3&t=20350 from PyQt5.Qt import QImage, QByteArray, QBuffer i = QImage() if i.loadFromData(bmp): ba = QByteArray() buf = QBuffer(ba) buf.open(QBuffer.WriteOnly) i.save(buf, 'png') return bytes(ba.data()) from calibre.utils.magick import Image img = Image() img.load(bmp) return img.export('png')
def pixmap_to_data(pixmap): ba = QByteArray() buf = QBuffer(ba) buf.open(QBuffer.WriteOnly) pixmap.save(buf, 'PNG') return bytearray(ba.data())