-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathProgetto_2_GUI.py
More file actions
executable file
·244 lines (182 loc) · 8.74 KB
/
Progetto_2_GUI.py
File metadata and controls
executable file
·244 lines (182 loc) · 8.74 KB
1
import sysfrom PyQt5 import QtGuifrom PyQt5.QtGui import QPixmapfrom PyQt5.QtCore import Qt, QPoint, pyqtSlotfrom PyQt5.QtWidgets import (QApplication, QMainWindow, QFileDialog, QGridLayout, QWidget, QAction, QLabel, QPushButton, QSlider, QMessageBox, QCheckBox)from datetime import datetimeimport numpy as npfrom scipy.fftpack import dctn, idctnclass Application(QMainWindow): def __init__(self): super(Application, self).__init__() self.mainContent = MainContent() self.setCentralWidget(self.mainContent) self.setGeometry(100, 100, 500, 300) self.setWindowTitle("Image Compression Using DCT") openFile = QAction("&Open", self) openFile.setShortcut("Ctrl+O") openFile.setStatusTip("Open Image") openFile.triggered.connect(self.openImage) exitApp = QAction("&Quit", self) exitApp.setShortcut("Ctrl+W") exitApp.setStatusTip("Quit Application") exitApp.triggered.connect(self.close) self.statusBar() mainMenu = self.menuBar() mainMenu.setNativeMenuBar(False) fileMenu = mainMenu.addMenu('&File') fileMenu.addAction(openFile) fileMenu.addAction(exitApp) self.show() def openImage(self): self.mainContent.openImage() class MainContent(QWidget): def __init__(self): super(MainContent, self).__init__() mainGrid = QGridLayout() # 0, 0 self.originalImage = ImageLabel('prova.bmp') # self.originalImage.setText('Original Image') # self.originalImage.setAlignment(Qt.AlignCenter) mainGrid.addWidget(self.originalImage, 0, 0) # 1, 0 subGrid = QGridLayout() # Parameters subGrid.addWidget(QLabel('Parameters'), 0, 0, 1, 3) imageSize = self.originalImage.pixmap.size() minimumSize = min(imageSize.height(), imageSize.width()) # F subGrid.addWidget(QLabel('F'), 1, 0) self.F = QSlider(Qt.Horizontal) self.F.setMinimum(1) #self.f.setFocusPolicy(Qt.StrongFocus) self.F.setTickPosition(QSlider.TicksBelow) self.F.setSingleStep(1) self.F.setMaximum(minimumSize) self.F.setTickInterval(minimumSize/10) self.F.valueChanged.connect(lambda: self.d.setMaximum(2 * self.F.value() - 2) or self.d.setTickInterval((2 * self.F.value() - 2) / 10) or self.Fvalue.setText(str(self.F.value()))) subGrid.addWidget(self.F, 1, 1) self.Fvalue = QLabel('1') subGrid.addWidget(self.Fvalue, 1, 2) # d subGrid.addWidget(QLabel('d'), 2, 0) self.d = QSlider(Qt.Horizontal) self.d.setMinimum(0) #self.d.setFocusPolicy(Qt.StrongFocus) self.d.setTickPosition(QSlider.TicksBelow) self.d.setSingleStep(1) self.d.setMaximum((2 * self.F.value() - 2)) self.d.valueChanged.connect(lambda: self.dvalue.setText(str(self.d.value()))) subGrid.addWidget(self.d, 2, 1) self.dvalue = QLabel('0') subGrid.addWidget(self.dvalue, 2, 2) innerWidget = QWidget() innerWidget.setLayout(subGrid) mainGrid.addWidget(innerWidget, 1, 0) # 1, 1 buttonGrid = QGridLayout() buttonGrid.addWidget(QLabel(), 0, 0) # Button button = QPushButton('Compress!', self) button.setToolTip('Run Compression') button.clicked.connect(self.compressImage) buttonGrid.addWidget(button, 1, 0) # CheckBox self.checkbox = QCheckBox() self.checkbox.setText('Save Compressed Image') buttonGrid.addWidget(self.checkbox, 2, 0) buttonWidget = QWidget() buttonWidget.setLayout(buttonGrid) mainGrid.addWidget(buttonWidget, 1, 1) # 0, 1 self.DCTImage = ImageLabel() mainGrid.addWidget(self.DCTImage, 0, 1) mainGrid.setColumnStretch(0, 1) mainGrid.setColumnStretch(1, 1) mainGrid.setRowStretch(0, 10) mainGrid.setRowStretch(1, 1) self.setLayout(mainGrid) def openImage(self): fileName = QFileDialog.getOpenFileName(self, 'Open File', '', '*.bmp') if fileName[0]: if QtGui.QPixmap(fileName[0]).toImage().isGrayscale(): self.originalImage.setPixmap(QtGui.QPixmap(fileName[0])) imageSize = self.originalImage.pixmap.size() minimumSize = min(imageSize.height(), imageSize.width()) self.F.setMaximum(minimumSize) self.F.setTickInterval(minimumSize/10) self.F.valueChanged.connect(lambda: self.d.setMaximum(2 * self.F.value() - 2) or self.d.setTickInterval((2 * self.F.value() - 2) / 10) or self.Fvalue.setText(str(self.F.value()))) self.d.valueChanged.connect(lambda: self.dvalue.setText(str(self.d.value()))) self.DCTImage.setPixmap(QPixmap()) else: messageError = QMessageBox() messageError.setIcon(QMessageBox.Critical) messageError.setText("Error") messageError.setInformativeText('Bitmap Image is NOT Grayscale!') messageError.setWindowTitle("Error") messageError.exec_() @pyqtSlot() def compressImage(self): print('Running Compression') sourceImage = self.originalImage.pixmap.toImage() sourceHeight = sourceImage.height() sourceWidth = sourceImage.width() sourceChannel = 4 sourceImageBits = sourceImage.bits() sourceImageBits.setsize(sourceHeight * sourceWidth * sourceChannel) sourceImageBytes = np.frombuffer(sourceImageBits, np.uint8).reshape((sourceHeight, sourceWidth, sourceChannel)) sourceImageBytes = sourceImageBytes[:,:,0].astype(float) # np.savetxt("sourceImageBytes_Before.csv", sourceImageBytes, delimiter = ",", fmt = "%d") fValue = self.F.value() dValue = self.d.value() for h in range(0, sourceHeight - fValue + 1, fValue): for w in range(0, sourceWidth - fValue + 1, fValue): tmp = sourceImageBytes[h:h+fValue, w:w+fValue] tmp = dctn(tmp, type=2, norm='ortho') for k in range(0, tmp.shape[1]): for l in range(0, tmp.shape[0]): if k + l >= dValue: tmp[k, l] = 0 tmp = idctn(tmp, norm='ortho') sourceImageBytes[h:h+fValue, w:w+fValue] = tmp # np.savetxt("sourceImageBytes_After.csv", sourceImageBytes, delimiter = ",", fmt = "%d") sourceImageBytes = sourceImageBytes.clip(0, 255).round().astype(np.uint8) destinationImage = QtGui.QPixmap(QtGui.QImage(bytes(sourceImageBytes), sourceImageBytes.shape[1], sourceImageBytes.shape[0], int(sourceImageBytes.nbytes/sourceHeight), QtGui.QImage.Format_Grayscale8)) if self.checkbox.isChecked(): formatOut = "%d-%m-%Y %H:%M:%S" date = datetime.now().strftime(formatOut) destinationImageName = date + '.bmp' destinationImage.save(destinationImageName, 'bmp') self.DCTImage.setPixmap(destinationImage) class ImageLabel(QLabel): def __init__(self, filename = None, parent = None): QWidget.__init__(self, parent = parent) self.pixmap = QtGui.QPixmap(filename) def setPixmap(self, pixmap): self.pixmap = pixmap self.update() def paintEvent(self, event): if not self.pixmap.isNull(): size = self.size() painter = QtGui.QPainter(self) point = QPoint(0,0) scaledPixel = self.pixmap.scaled(size, Qt.KeepAspectRatio, transformMode = Qt.SmoothTransformation) point.setX((size.width() - scaledPixel.width())/2) point.setY((size.height() - scaledPixel.height())/2) painter.drawPixmap(point, scaledPixel) else: super().paintEvent(event)def run(): app = QApplication(sys.argv) GUI = Application() sys.exit(app.exec_())run()