def __init__(self, parent=None): super(Form, self).__init__(parent) self.svg_style = SvgStyle() self.temp_svg_file = QTemporaryFile() if not self.temp_svg_file.open(): # need to obtain temp file name raise RuntimeError('Cannot create temporary file for svg object') self.temp_svg_file.close() self.setWindowTitle(u'Круговая диаграмма') self.model = CustomTableModel() self.table_view = QTableView() self.table_view.horizontalHeader().setSectionResizeMode(QHeaderView.ResizeToContents) self.table_view.verticalHeader().setSectionResizeMode(QHeaderView.ResizeToContents) self.widget_svg = QSvgWidget() self.widget_style = StyleWidget() self.widget_style.style_changed.connect(self.style_updated) # central widget layout layout = QHBoxLayout() # size = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred) # size.setHorizontalStretch(1) # self.table_view.setSizePolicy(size) layout.addWidget(self.table_view) layout.addWidget(self.widget_svg) layout.addWidget(self.widget_style) self.widget_svg.setFixedSize(500, 500) widget_central = QWidget() widget_central.setLayout(layout) self.setCentralWidget(widget_central) # main menu self.menu = self.menuBar() self.menu_file = self.menu.addMenu("File") # load QAction action_load = QAction('Open', self) action_load.setShortcut(QKeySequence.Open) action_load.triggered.connect(self.load_data) self.menu_file.addAction(action_load) self.statusBar() # exit QAction action_exit = QAction('Exit', self) action_exit.setShortcut(QKeySequence.Quit) action_exit.triggered.connect(self.close) self.menu_file.addAction(action_exit)
def testCallFunction(self): f = QTemporaryFile() self.assertTrue(f.open()) fileName = f.fileName() f.close() f = QFile(fileName) self.assertEqual(f.open(QIODevice.Truncate | QIODevice.Text | QIODevice.ReadWrite), True) om = f.openMode() self.assertEqual(om & QIODevice.Truncate, QIODevice.Truncate) self.assertEqual(om & QIODevice.Text, QIODevice.Text) self.assertEqual(om & QIODevice.ReadWrite, QIODevice.ReadWrite) self.assertTrue(om == QIODevice.Truncate | QIODevice.Text | QIODevice.ReadWrite) f.close()
def __init__(self, filename, image, parent=None): super(ThumbWidget, self).__init__(parent) temp_file = QTemporaryFile() if temp_file.open(): output = subprocess.check_output( [exiftool_exe(), '-b', '-ThumbnailImage', filename]) temp_name = temp_file.fileName() with open(temp_name, 'wb') as file: file.write(output) thumb = cv.imread(temp_name, cv.IMREAD_COLOR) if thumb is None: self.show_error(self.tr('Thumbnail image not found!')) return # resized = cv.resize(image, thumb.shape[:-1][::-1], interpolation=cv.INTER_AREA) resized = cv.resize(thumb, image.shape[:-1][::-1], interpolation=cv.INTER_LANCZOS4) diff = cv.absdiff(image, resized) # image_aspect = image.shape[1] / image.shape[0] # thumb_aspect = thumb.shape[1] / thumb.shape[0] # if thumb_aspect < image_aspect: # shape = (thumb.shape[1] // image_aspect, thumb.shape[1]) # elif thumb_aspect > image_aspect: # shape = (thumb.shape[0], thumb.shape[0] * image_aspect) # else: # shape = thumb.shape # resized = cv.resize(image, shape, None, 0, 0, interpolation=cv.INTER_AREA) # top = (thumb.shape[0] - resized.shape[0]) / 2 # bottom = top # left = (thumb.shape[1] - resized.shape[1]) / 2 # right = left # padded = cv.copyMakeBorder(resized, top, bottom, left, right, cv.BORDER_CONSTANT) # if padded.shape != thumb.shape: # padded = cv.resize(padded, thumb.shape, interpolation=cv.INTER_AREA) # diff = cv.cvtColor(cv.absdiff(thumb, padded), cv.COLOR_BGR2GRAY) viewer = ImageViewer(resized, diff) layout = QVBoxLayout() layout.addWidget(viewer) self.setLayout(layout)
def testWrite(self): temporaryFile = QTemporaryFile(QDir.tempPath() + "/pdfwriter_test_XXXXXX.pdf") self.assertTrue(temporaryFile.open()) pdfWriter = QPdfWriter(temporaryFile) pdfWriter.setPageLayout(QPageLayout(QPageSize(QPageSize.A4), QPageLayout.Portrait, QMarginsF(10, 10, 10, 10))) doc = QTextDocument("Some text") doc.print_(pdfWriter) temporaryFile.close() self.assertTrue(temporaryFile.size() > 0)
def testDictionary(self): confFile = QTemporaryFile(QDir.tempPath() + '/pysidebug829_XXXXXX.ini') confFile.setAutoRemove(False) self.assertTrue(confFile.open()) confFile.close() self._confFileName = confFile.fileName() del confFile s = QSettings(self._confFileName, QSettings.IniFormat) self.assertEqual(s.status(), QSettings.NoError) # Save value s.setValue('x', {1: 'a'}) s.sync() self.assertEqual(s.status(), QSettings.NoError) del s # Restore value s = QSettings(self._confFileName, QSettings.IniFormat) self.assertEqual(s.status(), QSettings.NoError) self.assertEqual(s.value('x'), {1: 'a'})
class Form(QMainWindow): def __init__(self, parent=None): super(Form, self).__init__(parent) self.svg_style = SvgStyle() self.temp_svg_file = QTemporaryFile() if not self.temp_svg_file.open(): # need to obtain temp file name raise RuntimeError('Cannot create temporary file for svg object') self.temp_svg_file.close() self.setWindowTitle(u'Круговая диаграмма') self.model = CustomTableModel() self.table_view = QTableView() self.table_view.horizontalHeader().setSectionResizeMode(QHeaderView.ResizeToContents) self.table_view.verticalHeader().setSectionResizeMode(QHeaderView.ResizeToContents) self.widget_svg = QSvgWidget() self.widget_style = StyleWidget() self.widget_style.style_changed.connect(self.style_updated) # central widget layout layout = QHBoxLayout() # size = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred) # size.setHorizontalStretch(1) # self.table_view.setSizePolicy(size) layout.addWidget(self.table_view) layout.addWidget(self.widget_svg) layout.addWidget(self.widget_style) self.widget_svg.setFixedSize(500, 500) widget_central = QWidget() widget_central.setLayout(layout) self.setCentralWidget(widget_central) # main menu self.menu = self.menuBar() self.menu_file = self.menu.addMenu("File") # load QAction action_load = QAction('Open', self) action_load.setShortcut(QKeySequence.Open) action_load.triggered.connect(self.load_data) self.menu_file.addAction(action_load) self.statusBar() # exit QAction action_exit = QAction('Exit', self) action_exit.setShortcut(QKeySequence.Quit) action_exit.triggered.connect(self.close) self.menu_file.addAction(action_exit) # window dimensions # geometry = qApp.desktop().availableGeometry(self) # self.setFixedSize(geometry.width() * 0.5, geometry.height() * 0.5) def load_data(self) -> None: filename, _ = QFileDialog.getOpenFileName(self, "Load data", dir="./tests", filter="Text files (*.txt);;Excel data (*csv)") if filename: country_data: CountryData = read_data(filename) self.model = CustomTableModel(country_data) self.table_view.setModel(self.model) self.statusBar().showMessage("Data loaded and plotted") self.draw_diagram() def load_svg(self, filename) -> None: self.widget_svg.load(filename) def draw_diagram(self) -> None: n_countries: int = self.model.rowCount() if n_countries > 0: style: SvgStyle = self.svg_style delta_angle: float = 2.0*math.pi/n_countries max_value: float = max(self.model.values) dwg = Drawing(self.temp_svg_file.fileName(), profile='tiny', viewBox='-250 -250 500 500') for idx, v in enumerate(self.model.values): x: float = style.line_length * v/max_value * math.sin(idx * delta_angle) y: float = -style.line_length * v/max_value * math.cos(idx * delta_angle) dwg.add(shapes.Line(start=(0, 0), end=(x, y), stroke=style.line_color, stroke_width=style.line_width)) radius: float = style.circle_rad if style.circle_rad_normalization: radius *= v/max_value dwg.add(shapes.Circle(center=(x, y), r=radius, stroke=style.circle_stroke_color, stroke_width=style.circle_stroke_width, fill=style.circle_fill_color)) dwg.save(pretty=True) self.load_svg(self.temp_svg_file.fileName()) @Slot() def style_updated(self, style: SvgStyle): self.svg_style = style self.draw_diagram()
def __init__(self, filename, image, parent=None): super(QualityWidget, self).__init__(parent) x = np.arange(1, 101) y = loss_curve(image) tail = 5 qm = np.argmin(y[:-tail]) + 1 if qm == 100 - tail: qm = 100 figure = Figure() canvas = FigureCanvas(figure) axes = canvas.figure.subplots() axes.plot(x, y * 100, label="compression loss") axes.fill_between(x, y * 100, alpha=0.2) axes.axvline(qm, linestyle=":", color="k", label=f"min error (q = {qm})") xt = axes.get_xticks() xt = np.append(xt, 1) axes.set_xticks(xt) axes.set_xlim([1, 100]) axes.set_ylim([0, 100]) axes.set_xlabel(self.tr("JPEG quality (%)")) axes.set_ylabel(self.tr("average error (%)")) axes.grid(True, which="both") axes.legend(loc="upper center") axes.figure.canvas.draw() figure.set_tight_layout(True) main_layout = QVBoxLayout() main_layout.addWidget(canvas) MRK = b"\xFF" SOI = b"\xD8" DQT = b"\xDB" # DHT = b'\xC4' MSK = b"\x0F" PAD = b"\x00" MAX_TABLES = 2 LEN_OFFSET = 2 LUMA_IDX = 0 CHROMA_IDX = 1 luma = np.zeros((DCT_SIZE, DCT_SIZE), dtype=int) chroma = np.zeros((DCT_SIZE, DCT_SIZE), dtype=int) temp_file = QTemporaryFile() try: if temp_file.open(): copyfile(filename, temp_file.fileName()) subprocess.run( [ exiftool_exe(), "-all=", "-overwrite_original", temp_file.fileName() ], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, ) found = False with open(temp_file.fileName(), "rb") as file: first = file.read(1) if first not in [MRK, SOI]: raise ValueError(self.tr("File is not a JPEG image!")) while True: if not self.find_next(file, [MRK, DQT, PAD]): break length = file.read(1)[0] - LEN_OFFSET if length <= 0 or length % (TABLE_SIZE + 1) != 0: continue while length > 0: mode = file.read(1) if not mode: break index = mode[0] & MSK[0] if index >= MAX_TABLES: break length -= 1 for k in range(TABLE_SIZE): b = file.read(1)[0] if not b: break length -= 1 i, j = ZIG_ZAG[k] if index == LUMA_IDX: luma[i, j] = b elif index == CHROMA_IDX: chroma[i, j] = b else: found = True if not found: raise ValueError(self.tr("Unable to find JPEG tables!")) levels = [(1 - (np.mean(t.ravel()[1:]) - 1) / 254) * 100 for t in [luma, chroma]] distance = np.zeros(101) for qm in range(101): lu, ch = cv.split(get_tables(qm)) lu_diff = np.mean(cv.absdiff(luma, lu)) ch_diff = np.mean(cv.absdiff(chroma, ch)) distance[qm] = (lu_diff + 2 * ch_diff) / 3 closest = np.argmin(distance) deviation = distance[closest] if deviation == 0: quality = closest message = "(standard tables)" else: quality = int(np.round(closest - deviation)) message = f"(deviation from standard tables = {deviation:.4f})" if quality == 0: quality = 1 quality_label = QLabel( self.tr( f"[JPEG FORMAT] Last saved quality: {quality}% {message}")) modify_font(quality_label, bold=True) luma_label = QLabel( self. tr(f"Luminance Quantization Table (level = {levels[0]:.2f}%)\n" )) luma_label.setAlignment(Qt.AlignCenter) modify_font(luma_label, underline=True) luma_table = self.create_table(luma) luma_table.setFixedSize(420, 190) chroma_label = QLabel( self. tr(f"Chrominance Quantization Table (level = {levels[1]:.2f}%)\n" )) chroma_label.setAlignment(Qt.AlignCenter) modify_font(chroma_label, underline=True) chroma_table = self.create_table(chroma) chroma_table.setFixedSize(420, 190) table_layout = QGridLayout() table_layout.addWidget(luma_label, 0, 0) table_layout.addWidget(luma_table, 1, 0) table_layout.addWidget(chroma_label, 0, 1) table_layout.addWidget(chroma_table, 1, 1) table_layout.addWidget(quality_label, 2, 0, 1, 2) main_layout.addLayout(table_layout) except ValueError: modelfile = "models/jpeg_qf.mdl" try: model = load(modelfile) limit = model.best_ntree_limit if hasattr( model, "best_ntree_limit") else None # f = self.get_features(image) # p = model.predict_proba(f, ntree_limit=limit)[0, 0] qp = model.predict(np.reshape(y, (1, len(y))), ntree_limit=limit)[0] # if p > 0.5: # p = 2 * (p - 0.5) * 100 # output = self.tr('Uncompressed image (p = {:.2f}%)'.format(p)) # else: # p = (1 - 2 * p) * 100 # output = self.tr('Compressed image (p = {:.2f}%) ---> Estimated JPEG quality = {}%'.format(p, qm)) message = self.tr( f"[LOSSLESS FORMAT] Estimated last saved quality = {qp:.1f}%{'' if qp <= 99 else ' (uncompressed)'}" ) if qp == 100: message += " (uncompressed)" prob_label = QLabel(message) modify_font(prob_label, bold=True) main_layout.addWidget(prob_label) except FileNotFoundError: QMessageBox.critical( self, self.tr("Error"), self.tr(f'Model not found ("{modelfile}")!')) main_layout.addStretch() self.setLayout(main_layout)
def __init__(self, filename, parent=None): super(QualityWidget, self).__init__(parent) MRK = b'\xFF' SOI = b'\xD8' DQT = b'\xDB' # DHT = b'\xC4' MSK = b'\x0F' PAD = b'\x00' MAX_TABLES = 2 LEN_OFFSET = 2 LUMA_IDX = 0 CHROMA_IDX = 1 luma = np.zeros((DCT_SIZE, DCT_SIZE), dtype=int) chroma = np.zeros((DCT_SIZE, DCT_SIZE), dtype=int) temp_file = QTemporaryFile() if temp_file.open(): copyfile(filename, temp_file.fileName()) subprocess.run([ exiftool_exe(), '-all=', '-overwrite_original', temp_file.fileName() ], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) found = False with open(temp_file.fileName(), 'rb') as file: first = file.read(1) if first not in [MRK, SOI]: self.show_error(self.tr('File is not a JPEG image!')) return while True: if not self.find_next(file, [MRK, DQT, PAD]): break length = file.read(1)[0] - LEN_OFFSET if length <= 0 or length % (TABLE_SIZE + 1) != 0: continue while length > 0: mode = file.read(1) if not mode: break index = mode[0] & MSK[0] if index >= MAX_TABLES: break length -= 1 for k in range(TABLE_SIZE): b = file.read(1)[0] if not b: break length -= 1 i, j = ZIG_ZAG[k] if index == LUMA_IDX: luma[i, j] = b elif index == CHROMA_IDX: chroma[i, j] = b else: found = True if not found: self.show_error(self.tr('Unable to find JPEG tables!')) return levels = [(1 - (np.mean(t.ravel()[1:]) - 1) / 254) * 100 for t in [luma, chroma]] distance = np.zeros(101) for q in range(101): lu, ch = cv.split(get_tables(q)) lu_diff = np.mean(cv.absdiff(luma, lu)) ch_diff = np.mean(cv.absdiff(chroma, ch)) distance[q] = (lu_diff + 2 * ch_diff) / 3 closest = np.argmin(distance) deviation = distance[closest] if deviation == 0: quality = closest message = '(standard tables)' else: quality = int(np.round(closest - deviation)) message = '(deviation from standard = {:.4f})'.format(deviation) quality_label = QLabel( self.tr('Last saved JPEG quality: {}% {}'.format(quality, message))) modify_font(quality_label, bold=True) luma_label = QLabel( self.tr('Luminance Quantization Table (level = {:.2f}%)\n'.format( levels[0]))) luma_label.setAlignment(Qt.AlignCenter) modify_font(luma_label, underline=True) luma_table = self.create_table(luma) luma_table.setMaximumHeight(200) chroma_label = QLabel( self.tr( 'Chrominance Quantization Table (level = {:.2f}%)\n'.format( levels[1]))) chroma_label.setAlignment(Qt.AlignCenter) modify_font(chroma_label, underline=True) chroma_table = self.create_table(chroma) chroma_table.setMaximumHeight(200) main_layout = QGridLayout() main_layout.addWidget(luma_label, 0, 0) main_layout.addWidget(luma_table, 1, 0) main_layout.addWidget(chroma_label, 0, 1) main_layout.addWidget(chroma_table, 1, 1) main_layout.addWidget(quality_label, 2, 0, 1, 2) self.setLayout(main_layout) self.setFixedSize(880, 270)
def __init__(self, filename, parent=None): super(QualityWidget, self).__init__(parent) MRK = b'\xFF' SOI = b'\xD8' DQT = b'\xDB' # DHT = b'\xC4' MSK = b'\x0F' PAD = b'\x00' MAX_TABLES = 2 LEN_OFFSET = 2 LUMA_IDX = 0 CHROMA_IDX = 1 luma = np.zeros((DCT_SIZE, DCT_SIZE), dtype=int) chroma = np.zeros((DCT_SIZE, DCT_SIZE), dtype=int) temp_file = QTemporaryFile() if temp_file.open(): copyfile(filename, temp_file.fileName()) subprocess.run([ exiftool_exe(), '-all=', '-overwrite_original', temp_file.fileName() ], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) found = False with open(temp_file.fileName(), 'rb') as file: first = file.read(1) if first not in [MRK, SOI]: self.show_error(self.tr('File is not a JPEG image!')) return while True: if not self.find_next(file, [MRK, DQT, PAD]): break length = file.read(1)[0] - LEN_OFFSET if length <= 0 or length % (TABLE_SIZE + 1) != 0: continue while length > 0: mode = file.read(1) if not mode: break index = mode[0] & MSK[0] if index >= MAX_TABLES: break length -= 1 for k in range(TABLE_SIZE): b = file.read(1)[0] if not b: break length -= 1 i, j = ZIG_ZAG[k] if index == LUMA_IDX: luma[i, j] = b elif index == CHROMA_IDX: chroma[i, j] = b else: found = True if not found: self.show_error(self.tr('Unable to find JPEG tables!')) return tables = np.concatenate( (luma[:, :, np.newaxis], chroma[:, :, np.newaxis]), axis=2) levels = [0, 0] for i in range(2): table = tables[:, :, i] mean = (np.mean(table) * TABLE_SIZE - table[0, 0]) / (TABLE_SIZE - 1) levels[i] = (1 - mean / 255) * 100 if levels[i] > 99.6: levels[i] = 100 profile = [np.mean(np.abs(tables - get_tables(q))) for q in range(101)] quality = np.argmin(profile) luma_label = QLabel( self.tr('Luminance Quantization Table (level = {:.2f}%)\n'.format( levels[0]))) luma_label.setAlignment(Qt.AlignCenter) modify_font(luma_label, underline=True) luma_table = self.create_table(luma) chroma_label = QLabel( self.tr( 'Chrominance Quantization Table (level = {:.2f}%)\n'.format( levels[1]))) chroma_label.setAlignment(Qt.AlignCenter) modify_font(chroma_label, underline=True) chroma_table = self.create_table(chroma) quality_label = QLabel( self.tr( 'Estimated JPEG quality (last save) = {}%'.format(quality))) modify_font(quality_label, bold=True) deviation_label = QLabel( self.tr('(average deviation from standard tables = {:.2f})'.format( profile[quality]))) modify_font(deviation_label, italic=True) deviation_label.setAlignment(Qt.AlignRight) main_layout = QGridLayout() main_layout.addWidget(luma_label, 0, 0) main_layout.addWidget(luma_table, 1, 0) main_layout.addWidget(chroma_label, 0, 1) main_layout.addWidget(chroma_table, 1, 1) main_layout.addWidget(quality_label, 2, 0) main_layout.addWidget(deviation_label, 2, 1) self.setLayout(main_layout) self.setMinimumSize(890, 270)