def changeResolution(self): fileName = QFileDialog.getOpenFileName( self, 'Load .prn file', directory=self.settings.value('unpacker/dir_open', QDir.currentPath()), filter='PRN files (*.prn *.bin);;All (*)') if not fileName: return file = QFile(fileName) if not file.open(QFile.ReadWrite): QMessageBox.warning( self, "Unpacker .prn", "Unable load file {}:\n{}.".format(fileName, file.errorString())) return self.settings.setValue('unpacker/dir_open', QFileInfo(file).path()) data = QDataStream(file) data.setByteOrder(QDataStream.LittleEndian) headerVersion = data.readInt32() xdpi = data.readInt32() ydpi = data.readInt32() dialog = ChangeResolutionDialog(xdpi, ydpi, self) if dialog.exec_(): file.seek(4) data.writeInt32(dialog.sbXdpi.value()) data.writeInt32(dialog.sbYdpi.value()) self.status.showMessage("Resolution changed successful", 7000) file.close()
def send(self, command, *args): self._logger.info("GC<<: {}:{}".format(command, args)) ds = QDataStream(self._socket) ds.setByteOrder(QDataStream.LittleEndian) # Header ds.writeUInt32(len(command)) ds.writeRawData(command.encode()) # Chunks ds.writeUInt32(len(args)) for chunk in args: ds.writeRawData(self._packLuaVal(chunk))
def changeResolution(self): fileName = QFileDialog.getOpenFileName(self, 'Load .prn file', directory=self.settings.value('unpacker/dir_open',QDir.currentPath()), filter='PRN files (*.prn *.bin);;All (*)') if not fileName: return file = QFile(fileName) if not file.open(QFile.ReadWrite): QMessageBox.warning(self, "Unpacker .prn", "Unable load file {}:\n{}.".format(fileName, file.errorString())) return self.settings.setValue('unpacker/dir_open', QFileInfo(file).path()) data = QDataStream(file) data.setByteOrder(QDataStream.LittleEndian) headerVersion = data.readInt32() xdpi = data.readInt32() ydpi = data.readInt32() dialog = ChangeResolutionDialog(xdpi, ydpi, self) if dialog.exec_(): file.seek(4) data.writeInt32(dialog.sbXdpi.value()) data.writeInt32(dialog.sbYdpi.value()) self.status.showMessage("Resolution changed successful", 7000) file.close()
def _onReadyRead(self): while self._socket.bytesAvailable() >= 4: ds = QDataStream(self._socket) ds.setByteOrder(QDataStream.LittleEndian) # Header packet if self.header is None: size, = unpack('=l', self._socket.peek(4)) if self._socket.bytesAvailable() < size + 4: return #Omit size ds.readUInt32() self.header = ds.readRawData(size).decode() # Chunks packet else: if self.nchunks == -1: self.nchunks = ds.readUInt32() self.chunks = [] while len(self.chunks) < self.nchunks: chunk = self._readLuaVal(ds) if chunk is None: return self.chunks.append(chunk) # Packet pair reading done. self._logger.info("GC >> : %s : %s", self.header, self.chunks) self.messageReceived.emit(self.header, self.chunks) self.header = None self.nchunks = -1 self.chunks = None
def unpackPrnFile(self): fileName = QFileDialog.getOpenFileName(self, 'Load .prn file', directory=self.settings.value('unpacker/dir_open',QDir.currentPath()), filter='PRN files (*.prn *.bin);;All (*)') if not fileName: return file = QFile(fileName) if not file.open(QFile.ReadOnly): QMessageBox.warning(self, "Unpacker .prn", "Unable load file {}:\n{}.".format(fileName, file.errorString())) return self.settings.setValue('unpacker/dir_open', QFileInfo(file).path()) data = QDataStream(file) data.setByteOrder(QDataStream.LittleEndian) file_name = QFileInfo(file).fileName() headerVersion = int.from_bytes(data.readRawData(4), 'little', signed=False) self.status.showMessage("Header Type: {:#X}".format(headerVersion)) if headerVersion == self.NEW_RIP_FILE: xdpi = data.readInt32() ydpi = data.readInt32() bpl = data.readInt32() imgh = data.readInt32() imgw = data.readInt32() ppw = data.readInt32() colnum = data.readInt32() bitsperdrop = data.readInt32() colorOrder = data.readRawData(16).decode().replace(chr(0), '') colorList = list(colorOrder) name = b'\xff\xfe' + data.readRawData(512) name = name.decode('utf-16').replace(chr(0), '') zero = data.readInt32() elif headerVersion == self.STD_RIP_FILE: xdpi = data.readInt32() ydpi = data.readInt32() bpl = data.readInt32() imgh = data.readInt32() imgw = data.readInt32() ppw = data.readInt32() colnum = data.readInt32() bitsperdrop = data.readInt32() if not bitsperdrop: QMessageBox.warning(self, "Unpacker .prn", "File format not supported") return colorOrder = data.readRawData(16).decode().replace(chr(0), '') colorList = list(colorOrder) zero = data.readInt32() name = 'Not used in this format' elif headerVersion == self.CALDERA_RIP_FILE: xdpi = data.readInt32() ydpi = data.readInt32() bpl = data.readInt32() imgh = data.readInt32() imgw = data.readInt32() ppw = data.readInt32() colnum = data.readInt32() bitsperdrop = data.readInt32() if not bitsperdrop: QMessageBox.warning(self, "Unpacker .prn", "File format not supported") return colorOrder = data.readRawData(16).decode().replace(chr(0), '') colorList = list(colorOrder) zero = data.readInt32() name = 'Not used in this format' else: QMessageBox.warning(self, "Unpacker .prn", "File format not supported") return colors = {} for color in colorList: colors[color] = {} for level in range(1, 2**bitsperdrop): colors[color][level] = QImage(imgw, imgh , QImage.Format_Mono) colors[color][level].setColor(0, qRgb(255, 255, 255)) colors[color][level].setColor(1, qRgb(0, 0, 0)) colors[color][level].fill(0) pd = QProgressDialog('Analyze file ...', 'Cancel', 0, imgh-1, self) pd.setWindowTitle('Analyze ...') pd.open() mask = 0xFF>>(8-bitsperdrop) # Получаем маску для текущего количества бит на каплю for row in range(imgh): for color in colorList: for bytenum in range(0, bpl, bitsperdrop): # Получаем номер байта, с которого будем читать byte = int.from_bytes(data.readRawData(bitsperdrop), 'big') for pix in range(8): shift = (7 - pix)*bitsperdrop pixel = (byte>>shift)&mask if pixel > 0: numofpix = 8*bytenum/bitsperdrop + pix if numofpix < imgw: colors[color][pixel].setPixel(numofpix, row, 1) pd.setValue(row) if pd.wasCanceled(): pd.close() file.close() return pd.close() file.close() catalog = QFileDialog.getExistingDirectory(self, directory=self.settings.value('unpacker/dir_save',QDir.currentPath())) if catalog is None: return self.settings.setValue('unpacker/dir_save', catalog) file = QFile("{}\{}_{}.txt".format(catalog, file_name, colorOrder)) if not file.open(QFile.WriteOnly | QFile.Text): QMessageBox.warning(self, "Prn creator", "Unable create file {}:\n{}.".format(name, file.errorString())) return text = QTextStream(file) text << "Filename: {}\n".format(file_name) text << "Test Name: {}\n\n".format(name) text << "X Resolution: {} dpi\n".format(xdpi) text << "Y Resolution: {} dpi\n".format(ydpi) text << "Image Width: {} pix\n".format(imgw) text << "Image Height: {} pix\n\n".format(imgh) text << "Bits Per Drop: {}\n".format(bitsperdrop) text << "Bytes Per Line: {}\n\n".format(bpl) text << "Number Of Colors: {}\n".format(colnum) text << "Order Of Colors: {}\n\n".format(colorOrder) text << "Paper Width: {}\n".format(ppw) for color in colorList: for level in range(1, 2**bitsperdrop): colors[color][level].save("{}\{}.{}.gs{}.tif".format(catalog, file_name, "{}".format(color) if color.isupper() else "_{}".format(color), level)) self.status.showMessage("Unpacking finished", 7000)
class MainWindow(QMainWindow): STD_RIP_FILE = 0x1111FFFF NEW_RIP_FILE = 0x2222FFFF CALDERA_RIP_FILE = 0xFFFF1111 ver = '1.3.10' colors = {'Black':'K', 'Cyan':'C', 'Magenta':'M', 'Yellow':'Y', 'Light Cyan':'c', 'Light Magenta':'m', 'White': 'W', 'Varnish':'V', 'Orange':'O', 'Green':'G', 'Gold':'D', 'Silver':'S', 'Medium Black':'k', 'Light Gray':'g', 'Red':'R', 'Blue':'B', 'Violet':'v', 'Spot Color 1':'1', 'Spot Color 2':'2', 'Spot Color 3':'3', 'Spot Color 4':'4', 'Spot Color 5':'5', 'Spot Color 6':'6', 'Spot Color 7':'7', 'Spot Color 8':'8', 'Spot Color 9':'9'} listColors = ['Black', 'Cyan', 'Magenta', 'Yellow', 'Light Cyan', 'Light Magenta', 'White', 'Varnish', 'Orange', 'Red', 'Green', 'Blue', 'Violet', 'Gold', 'Silver', 'Medium Black', 'Light Gray', 'Spot Color 1', 'Spot Color 2', 'Spot Color 3', 'Spot Color 4', 'Spot Color 5', 'Spot Color 6', 'Spot Color 7', 'Spot Color 8', 'Spot Color 9'] levelGS = {'1 bit per drop (Binary)':1, '2 bit per drop':2, '4 bit per drop (not used)':4 } acceptedFormats = ['tif', 'bmp'] listGSLevel = ['1 bit per drop (Binary)', '2 bit per drop']#,'4 bit per drop (not used)'] black = qRgb(0, 0, 0) def __init__(self, parent=None): super(MainWindow, self).__init__(parent) # self.stackLayout = QStackedLayout() self.settings = QSettings('settings.ini', QSettings.IniFormat) self.vLayout = QVBoxLayout() self.toolBar = QToolBar('mainToolBar') self.addToolBar(Qt.RightToolBarArea, self.toolBar) self.centralWidget = QSplitter(Qt.Vertical) self.setCentralWidget(self.centralWidget) self.status = self.statusBar() self.colorWidgets = {} self.levelWidgets = {} self.cmbGS = QComboBox() self.cmbGS.addItems(self.listGSLevel) self.connect(self.cmbGS, SIGNAL("currentIndexChanged(int)"), self.fillCmbGSLevel) self.gsLevel = self.levelGS[self.cmbGS.currentText()] self.xdpiCmbBox = QComboBox() self.xdpiCmbBox.addItems(['720', '600', '360', '300', '180', '150']) self.ydpiCmbBox = QComboBox() self.ydpiCmbBox.addItems(['360', '300', '180', '150', '90', '75']) self.table = QTableWidget(0,4) self.connect(self.table, SIGNAL("cellClicked(int, int)"), self.tableCellActivated) self.table.setHorizontalHeaderLabels(['Filename', 'Color', 'GS Level', 'Size']) self._table = TableWidget(self.table, self.cmbGS, self.xdpiCmbBox, self.ydpiCmbBox) self.connect(self._table, SIGNAL("insertRowAfter(int)"), self.addFile) self.connect(self._table, SIGNAL("removeRowAt(int)"), self.removeFile) # self._table.setAcceptDrops(True) self.table.setAcceptDrops(True) self.scene = QGraphicsScene() self.view = QGraphicsView(self.scene) self.scale = False self.chkBoxScale = QCheckBox("See the Whole") self.connect(self.chkBoxScale, SIGNAL("toggled(bool)"), self.setScale) self.centralWidget.addWidget(self._table) vbox = QVBoxLayout() vbox.addWidget(self.chkBoxScale) vbox.addWidget(self.view) widget = QWidget() widget.setLayout(vbox) self.centralWidget.addWidget(widget) # self.centralWidget.addWidget(self.statusBar) savePrnAction = self.createAction('Create .prn',self.savePrnFile, QKeySequence.Save, 'save_as', 'Create test file') self.toolBar.addAction(savePrnAction) unpackPrnAction = self.createAction('Unpack .prn', self.unpackPrnFile, QKeySequence.Open, 'analyze', 'Unpack prn file') self.toolBar.addAction(unpackPrnAction) editHeaderAction = self.createAction('Edit .prn', self.changeResolution, QKeySequence(Qt.CTRL+Qt.Key_E), 'edit', 'Change print resolution in prn file') self.toolBar.addAction(editHeaderAction) self.pix = QPixmap() self.pix.convertFromImage(QImage()) self.grPixmap = QGraphicsPixmapItem(self.pix) self.scene.addItem(self.grPixmap) # self.view.scale(0.3, 0.3) self.setWindowTitle('PRN Creator {}'.format(self.ver)) self.setWindowIcon(QIcon('icons/icon.png')) desktop = QApplication.desktop() rect = desktop.availableGeometry() pos = self.settings.value('window/pos', QPoint(0,0)) if pos.x() < rect.left(): x = rect.left() else: x = pos.x() if pos.y() < rect.top(): y = rect.top() else: y = pos.y() self.resize(self.settings.value('window/size', QSize(640, 480))) self.move(x, y) self.setWindowState(Qt.WindowState(int(self.settings.value('window/state', 0)))) def setScale(self, scaleBool): if not self.scene.sceneRect().size().isEmpty(): scaleX = self.view.size().width()/self.scene.sceneRect().size().width() scaleY = self.view.size().height()/self.scene.sceneRect().size().height() self.view.resetMatrix() if scaleBool: self.view.scale(min(scaleX, scaleY), min(scaleX, scaleY)) def dragEnterEvent(self, event): event.acceptProposedAction() def dropEvent(self, event): for file in event.mimeData().urls(): fi = QFileInfo(QFile(file.toLocalFile())) if fi.suffix() in self.acceptedFormats: self.addImageToTable(fi.filePath(), self.table.rowCount()) else: self.statusBar.showMessage('File format of {} not supported'.format(fi.fileName()), 5000) event.accept() def createColorComboBox(self, index): self.colorWidgets[index] = QComboBox() for color in self.listColors: self.colorWidgets[index].addItem(QIcon('icons/colors/{}.png'.format(self.colors[color] if color != 'Light Cyan' and color != 'Light Magenta' and color != 'Violet' and color != 'Medium Black' and color != 'Light Gray' else self.colors[color]+'_')), color) return self.colorWidgets[index] def createLevelComboBox(self, index): self.levelWidgets[index] = QComboBox() for level in range(1, 2**self.gsLevel): self.levelWidgets[index].addItem("Level {}".format(level), level) return self.levelWidgets[index] def tableCellActivated(self, row, column): self.scene.removeItem(self.grPixmap) image = self.table.item(row, 0).data(Qt.UserRole) self.pix.convertFromImage(image) self.grPixmap = QGraphicsPixmapItem(self.pix) self.scene.addItem(self.grPixmap) self.scene.setSceneRect(0,0, float(image.width()), float(image.height())) self.setScale(self.chkBoxScale.isChecked()) def closeEvent(self, event): self.settings.setValue('window/size', self.size()) self.settings.setValue('window/pos', self.pos()) self.settings.setValue('window/state', self.windowState()) event.accept() def addFile(self, index): file = QFileDialog.getOpenFileName(self, 'Load image', directory=self.settings.value('directories/dir_open',QDir.currentPath()), filter='Bitmap graphics (*.tif *.bmp);;All (*)') if not file: return self.settings.setValue('directories/dir_open', QFileInfo(file).path()) self.settings.sync() self.addImageToTable(file, index) def addImageToTable(self, file, index): image = QImage(file) if image.format() == QImage.Format_Mono: self.table.insertRow(index) self.table.setItem(index, 0, QTableWidgetItem(QFileInfo(file).fileName())) self.table.item(index, 0).setFlags(Qt.ItemIsUserCheckable|Qt.ItemIsEnabled|Qt.ItemIsSelectable) self.table.item(index,0).setData(Qt.UserRole, image) self.table.item(index, 0).setToolTip(file) self.table.setCellWidget(index, 1, self.createColorComboBox(index)) self.table.setCellWidget(index, 2, self.createLevelComboBox(index)) self.table.setCurrentCell(index, 0) self.table.setItem(index, 3, QTableWidgetItem("{}x{}".format(image.width(), image.height()))) self.table.item(index, 3).setFlags(Qt.ItemIsSelectable) else: self.statusBar.showMessage("Tiff file not monochrome ({})".format(image.format())) def removeFile(self, index): self.table.removeRow(index) self.table.setCurrentCell(index-1, 0) try: del self.colorWidgets[index] del self.levelWidgets[index] except (KeyError, IndexError) as err: pass def fillCmbGSLevel(self, index): """ Фунция для заполнения списка уровней значениями. Вызывается при выборе уровня GS """ self.gsLevel = self.levelGS[self.cmbGS.currentText()] for widget in self.levelWidgets: if self.levelWidgets[widget] is not None: self.levelWidgets[widget].clear() for level in range(1, 2**self.gsLevel): self.levelWidgets[widget].addItem("Level {}".format(level), level) def savePrnFile(self): width = 0 height = 0 images = {} for index in range(self.table.rowCount()): image = self.table.item(index, 0).data(Qt.UserRole) color = self.colors[self.table.cellWidget(index, 1).currentText()] if color not in images: images[color] = {} levelCmb = self.table.cellWidget(index, 2) level = levelCmb.itemData(levelCmb.currentIndex()) if level in images[color]: QMessageBox.warning(self, "Error!", "Duplicated GS Level for color!") return else: images[color][level] = image if width != 0: if width != image.width(): QMessageBox.warning(self, "Error!", "Width of images does not match!") return else: width = image.width() if height != 0: if height != image.height(): QMessageBox.warning(self, "Error!", "Height of images does not match!") return else: height = image.height() fileName = QFileDialog.getSaveFileName(self, "Save .prn file", self.settings.value('directories/dir_save', QDir.currentPath()), "PRN Files (*.prn);;BIN Files (*.bin)") if not fileName: return file = QFile(fileName) if not file.open(QFile.WriteOnly): QMessageBox.warning(self, "Prn Creator", "Unable to write file {}:\n{}.".format(self.fileName, file.errorString())) return self.settings.setValue('directories/dir_save', QFileInfo(file).path()) self.testName, status = QInputDialog.getText(self, "Test name", "Enter name of the test to write into file:", text="Test") if not status: QMessageBox.warning(self, "Prn Creator", "Name changed to 'Test'") self.testName = "Test" self.fileName = QFileInfo(file).fileName() self.out = QDataStream(file) self.out.setByteOrder(QDataStream.LittleEndian) colors = '' for color in images: colors+=color self.imgwidth = width self.imgheight = height self.bytesPerLine = int((self.gsLevel*self.imgwidth+31)/32)*4 self.writeNewHeader(colors) pd = QProgressDialog('Writing file ...', 'Cancel', 0, self.imgheight-1, self) pd.setWindowTitle('Creating file...') pd.open() tmp = 0 # Записывать данные будем построчно for row in range(self.imgheight): # обходим по порядку цветов, как расположены в файле for color in colors: # Добиваем строку до длины, кратной 32м байтам for column in range (int(self.bytesPerLine/self.gsLevel*8)): shift = 7-column+int(column/8)*8 pixel = 0 # Упорядочиваем уровни (на всякий) levels = sorted(list(images[color].keys())) # Если изображение меньше длины строки, то if column < self.imgwidth: for level in levels: # Выбираем максимальный уровень из тех, что указаны в данном пикселе на всех слоях if images[color][level].pixel(column, row) == self.black: pixel = level tmp |= (pixel<<shift*self.gsLevel) # Как только сдвиг обнулится, то записываем в файл if not shift: self.out.writeRawData(tmp.to_bytes(self.gsLevel, 'big')) tmp=0 pd.setValue(row) if pd.wasCanceled(): pd.close() file.close() return pd.close() file.close() self.status.showMessage("File created successful", 7000) def writeNewHeader(self, colors): xdpi = int(self.xdpiCmbBox.currentText()) ydpi = int(self.ydpiCmbBox.currentText()) self.paperWidth = 0 colorOrder = colors.encode() while len(colorOrder) < 16: colorOrder += bytes.fromhex('00') self.out.writeInt32(self.NEW_RIP_FILE) self.out.writeInt32(xdpi) self.out.writeInt32(ydpi) self.out.writeInt32(self.bytesPerLine) self.out.writeInt32(self.imgheight) self.out.writeInt32(self.imgwidth) self.out.writeInt32(self.paperWidth) self.out.writeInt32(len(colors)) self.out.writeInt32(self.gsLevel) self.out.writeRawData(colorOrder) name = self.testName.encode(encoding='utf_16')[2:514] # Удаляем первые два байта сигнатуры UTF-16 while len(name) < 256*2: # Дополняем до 256 символов WCHAR name += bytes.fromhex('00') self.out.writeRawData(name) self.out.writeInt32(0) # Зарезервировано def unpackPrnFile(self): fileName = QFileDialog.getOpenFileName(self, 'Load .prn file', directory=self.settings.value('unpacker/dir_open',QDir.currentPath()), filter='PRN files (*.prn *.bin);;All (*)') if not fileName: return file = QFile(fileName) if not file.open(QFile.ReadOnly): QMessageBox.warning(self, "Unpacker .prn", "Unable load file {}:\n{}.".format(fileName, file.errorString())) return self.settings.setValue('unpacker/dir_open', QFileInfo(file).path()) data = QDataStream(file) data.setByteOrder(QDataStream.LittleEndian) file_name = QFileInfo(file).fileName() headerVersion = int.from_bytes(data.readRawData(4), 'little', signed=False) self.status.showMessage("Header Type: {:#X}".format(headerVersion)) if headerVersion == self.NEW_RIP_FILE: xdpi = data.readInt32() ydpi = data.readInt32() bpl = data.readInt32() imgh = data.readInt32() imgw = data.readInt32() ppw = data.readInt32() colnum = data.readInt32() bitsperdrop = data.readInt32() colorOrder = data.readRawData(16).decode().replace(chr(0), '') colorList = list(colorOrder) name = b'\xff\xfe' + data.readRawData(512) name = name.decode('utf-16').replace(chr(0), '') zero = data.readInt32() elif headerVersion == self.STD_RIP_FILE: xdpi = data.readInt32() ydpi = data.readInt32() bpl = data.readInt32() imgh = data.readInt32() imgw = data.readInt32() ppw = data.readInt32() colnum = data.readInt32() bitsperdrop = data.readInt32() if not bitsperdrop: QMessageBox.warning(self, "Unpacker .prn", "File format not supported") return colorOrder = data.readRawData(16).decode().replace(chr(0), '') colorList = list(colorOrder) zero = data.readInt32() name = 'Not used in this format' elif headerVersion == self.CALDERA_RIP_FILE: xdpi = data.readInt32() ydpi = data.readInt32() bpl = data.readInt32() imgh = data.readInt32() imgw = data.readInt32() ppw = data.readInt32() colnum = data.readInt32() bitsperdrop = data.readInt32() if not bitsperdrop: QMessageBox.warning(self, "Unpacker .prn", "File format not supported") return colorOrder = data.readRawData(16).decode().replace(chr(0), '') colorList = list(colorOrder) zero = data.readInt32() name = 'Not used in this format' else: QMessageBox.warning(self, "Unpacker .prn", "File format not supported") return colors = {} for color in colorList: colors[color] = {} for level in range(1, 2**bitsperdrop): colors[color][level] = QImage(imgw, imgh , QImage.Format_Mono) colors[color][level].setColor(0, qRgb(255, 255, 255)) colors[color][level].setColor(1, qRgb(0, 0, 0)) colors[color][level].fill(0) pd = QProgressDialog('Analyze file ...', 'Cancel', 0, imgh-1, self) pd.setWindowTitle('Analyze ...') pd.open() mask = 0xFF>>(8-bitsperdrop) # Получаем маску для текущего количества бит на каплю for row in range(imgh): for color in colorList: for bytenum in range(0, bpl, bitsperdrop): # Получаем номер байта, с которого будем читать byte = int.from_bytes(data.readRawData(bitsperdrop), 'big') for pix in range(8): shift = (7 - pix)*bitsperdrop pixel = (byte>>shift)&mask if pixel > 0: numofpix = 8*bytenum/bitsperdrop + pix if numofpix < imgw: colors[color][pixel].setPixel(numofpix, row, 1) pd.setValue(row) if pd.wasCanceled(): pd.close() file.close() return pd.close() file.close() catalog = QFileDialog.getExistingDirectory(self, directory=self.settings.value('unpacker/dir_save',QDir.currentPath())) if catalog is None: return self.settings.setValue('unpacker/dir_save', catalog) file = QFile("{}\{}_{}.txt".format(catalog, file_name, colorOrder)) if not file.open(QFile.WriteOnly | QFile.Text): QMessageBox.warning(self, "Prn creator", "Unable create file {}:\n{}.".format(name, file.errorString())) return text = QTextStream(file) text << "Filename: {}\n".format(file_name) text << "Test Name: {}\n\n".format(name) text << "X Resolution: {} dpi\n".format(xdpi) text << "Y Resolution: {} dpi\n".format(ydpi) text << "Image Width: {} pix\n".format(imgw) text << "Image Height: {} pix\n\n".format(imgh) text << "Bits Per Drop: {}\n".format(bitsperdrop) text << "Bytes Per Line: {}\n\n".format(bpl) text << "Number Of Colors: {}\n".format(colnum) text << "Order Of Colors: {}\n\n".format(colorOrder) text << "Paper Width: {}\n".format(ppw) for color in colorList: for level in range(1, 2**bitsperdrop): colors[color][level].save("{}\{}.{}.gs{}.tif".format(catalog, file_name, "{}".format(color) if color.isupper() else "_{}".format(color), level)) self.status.showMessage("Unpacking finished", 7000) def changeResolution(self): fileName = QFileDialog.getOpenFileName(self, 'Load .prn file', directory=self.settings.value('unpacker/dir_open',QDir.currentPath()), filter='PRN files (*.prn *.bin);;All (*)') if not fileName: return file = QFile(fileName) if not file.open(QFile.ReadWrite): QMessageBox.warning(self, "Unpacker .prn", "Unable load file {}:\n{}.".format(fileName, file.errorString())) return self.settings.setValue('unpacker/dir_open', QFileInfo(file).path()) data = QDataStream(file) data.setByteOrder(QDataStream.LittleEndian) headerVersion = data.readInt32() xdpi = data.readInt32() ydpi = data.readInt32() dialog = ChangeResolutionDialog(xdpi, ydpi, self) if dialog.exec_(): file.seek(4) data.writeInt32(dialog.sbXdpi.value()) data.writeInt32(dialog.sbYdpi.value()) self.status.showMessage("Resolution changed successful", 7000) file.close() def createAction(self, text, slot=None, shortcut=None, icon=None, tip=None, checkable=False, signal='triggered()'): action = QAction(text, self) if icon is not None: action.setIcon(QIcon('icons/{}.png'.format(icon))) if shortcut is not None: action.setShortcut(shortcut) if tip is not None: action.setToolTip(tip) action.setStatusTip(tip) if slot is not None: self.connect(action, SIGNAL(signal), slot) if checkable: action.setCheckable(True) return action
def unpackPrnFile(self): fileName = QFileDialog.getOpenFileName( self, 'Load .prn file', directory=self.settings.value('unpacker/dir_open', QDir.currentPath()), filter='PRN files (*.prn *.bin);;All (*)') if not fileName: return file = QFile(fileName) if not file.open(QFile.ReadOnly): QMessageBox.warning( self, "Unpacker .prn", "Unable load file {}:\n{}.".format(fileName, file.errorString())) return self.settings.setValue('unpacker/dir_open', QFileInfo(file).path()) data = QDataStream(file) data.setByteOrder(QDataStream.LittleEndian) file_name = QFileInfo(file).fileName() headerVersion = int.from_bytes(data.readRawData(4), 'little', signed=False) self.status.showMessage("Header Type: {:#X}".format(headerVersion)) if headerVersion == self.NEW_RIP_FILE: xdpi = data.readInt32() ydpi = data.readInt32() bpl = data.readInt32() imgh = data.readInt32() imgw = data.readInt32() ppw = data.readInt32() colnum = data.readInt32() bitsperdrop = data.readInt32() colorOrder = data.readRawData(16).decode().replace(chr(0), '') colorList = list(colorOrder) name = b'\xff\xfe' + data.readRawData(512) name = name.decode('utf-16').replace(chr(0), '') zero = data.readInt32() elif headerVersion == self.STD_RIP_FILE: xdpi = data.readInt32() ydpi = data.readInt32() bpl = data.readInt32() imgh = data.readInt32() imgw = data.readInt32() ppw = data.readInt32() colnum = data.readInt32() bitsperdrop = data.readInt32() if not bitsperdrop: QMessageBox.warning(self, "Unpacker .prn", "File format not supported") return colorOrder = data.readRawData(16).decode().replace(chr(0), '') colorList = list(colorOrder) zero = data.readInt32() name = 'Not used in this format' elif headerVersion == self.CALDERA_RIP_FILE: xdpi = data.readInt32() ydpi = data.readInt32() bpl = data.readInt32() imgh = data.readInt32() imgw = data.readInt32() ppw = data.readInt32() colnum = data.readInt32() bitsperdrop = data.readInt32() if not bitsperdrop: QMessageBox.warning(self, "Unpacker .prn", "File format not supported") return colorOrder = data.readRawData(16).decode().replace(chr(0), '') colorList = list(colorOrder) zero = data.readInt32() name = 'Not used in this format' else: QMessageBox.warning(self, "Unpacker .prn", "File format not supported") return colors = {} for color in colorList: colors[color] = {} for level in range(1, 2**bitsperdrop): colors[color][level] = QImage(imgw, imgh, QImage.Format_Mono) colors[color][level].setColor(0, qRgb(255, 255, 255)) colors[color][level].setColor(1, qRgb(0, 0, 0)) colors[color][level].fill(0) pd = QProgressDialog('Analyze file ...', 'Cancel', 0, imgh - 1, self) pd.setWindowTitle('Analyze ...') pd.open() mask = 0xFF >> ( 8 - bitsperdrop ) # Получаем маску для текущего количества бит на каплю for row in range(imgh): for color in colorList: for bytenum in range( 0, bpl, bitsperdrop ): # Получаем номер байта, с которого будем читать byte = int.from_bytes(data.readRawData(bitsperdrop), 'big') for pix in range(8): shift = (7 - pix) * bitsperdrop pixel = (byte >> shift) & mask if pixel > 0: numofpix = 8 * bytenum / bitsperdrop + pix if numofpix < imgw: colors[color][pixel].setPixel(numofpix, row, 1) pd.setValue(row) if pd.wasCanceled(): pd.close() file.close() return pd.close() file.close() catalog = QFileDialog.getExistingDirectory( self, directory=self.settings.value('unpacker/dir_save', QDir.currentPath())) if catalog is None: return self.settings.setValue('unpacker/dir_save', catalog) file = QFile("{}\{}_{}.txt".format(catalog, file_name, colorOrder)) if not file.open(QFile.WriteOnly | QFile.Text): QMessageBox.warning( self, "Prn creator", "Unable create file {}:\n{}.".format(name, file.errorString())) return text = QTextStream(file) text << "Filename: {}\n".format(file_name) text << "Test Name: {}\n\n".format(name) text << "X Resolution: {} dpi\n".format(xdpi) text << "Y Resolution: {} dpi\n".format(ydpi) text << "Image Width: {} pix\n".format(imgw) text << "Image Height: {} pix\n\n".format(imgh) text << "Bits Per Drop: {}\n".format(bitsperdrop) text << "Bytes Per Line: {}\n\n".format(bpl) text << "Number Of Colors: {}\n".format(colnum) text << "Order Of Colors: {}\n\n".format(colorOrder) text << "Paper Width: {}\n".format(ppw) for color in colorList: for level in range(1, 2**bitsperdrop): colors[color][level].save("{}\{}.{}.gs{}.tif".format( catalog, file_name, "{}".format(color) if color.isupper() else "_{}".format(color), level)) self.status.showMessage("Unpacking finished", 7000)
class MainWindow(QMainWindow): STD_RIP_FILE = 0x1111FFFF NEW_RIP_FILE = 0x2222FFFF CALDERA_RIP_FILE = 0xFFFF1111 ver = '1.3.10' colors = { 'Black': 'K', 'Cyan': 'C', 'Magenta': 'M', 'Yellow': 'Y', 'Light Cyan': 'c', 'Light Magenta': 'm', 'White': 'W', 'Varnish': 'V', 'Orange': 'O', 'Green': 'G', 'Gold': 'D', 'Silver': 'S', 'Medium Black': 'k', 'Light Gray': 'g', 'Red': 'R', 'Blue': 'B', 'Violet': 'v', 'Spot Color 1': '1', 'Spot Color 2': '2', 'Spot Color 3': '3', 'Spot Color 4': '4', 'Spot Color 5': '5', 'Spot Color 6': '6', 'Spot Color 7': '7', 'Spot Color 8': '8', 'Spot Color 9': '9' } listColors = [ 'Black', 'Cyan', 'Magenta', 'Yellow', 'Light Cyan', 'Light Magenta', 'White', 'Varnish', 'Orange', 'Red', 'Green', 'Blue', 'Violet', 'Gold', 'Silver', 'Medium Black', 'Light Gray', 'Spot Color 1', 'Spot Color 2', 'Spot Color 3', 'Spot Color 4', 'Spot Color 5', 'Spot Color 6', 'Spot Color 7', 'Spot Color 8', 'Spot Color 9' ] levelGS = { '1 bit per drop (Binary)': 1, '2 bit per drop': 2, '4 bit per drop (not used)': 4 } acceptedFormats = ['tif', 'bmp'] listGSLevel = ['1 bit per drop (Binary)', '2 bit per drop'] #,'4 bit per drop (not used)'] black = qRgb(0, 0, 0) def __init__(self, parent=None): super(MainWindow, self).__init__(parent) # self.stackLayout = QStackedLayout() self.settings = QSettings('settings.ini', QSettings.IniFormat) self.vLayout = QVBoxLayout() self.toolBar = QToolBar('mainToolBar') self.addToolBar(Qt.RightToolBarArea, self.toolBar) self.centralWidget = QSplitter(Qt.Vertical) self.setCentralWidget(self.centralWidget) self.status = self.statusBar() self.colorWidgets = {} self.levelWidgets = {} self.cmbGS = QComboBox() self.cmbGS.addItems(self.listGSLevel) self.connect(self.cmbGS, SIGNAL("currentIndexChanged(int)"), self.fillCmbGSLevel) self.gsLevel = self.levelGS[self.cmbGS.currentText()] self.xdpiCmbBox = QComboBox() self.xdpiCmbBox.addItems(['720', '600', '360', '300', '180', '150']) self.ydpiCmbBox = QComboBox() self.ydpiCmbBox.addItems(['360', '300', '180', '150', '90', '75']) self.table = QTableWidget(0, 4) self.connect(self.table, SIGNAL("cellClicked(int, int)"), self.tableCellActivated) self.table.setHorizontalHeaderLabels( ['Filename', 'Color', 'GS Level', 'Size']) self._table = TableWidget(self.table, self.cmbGS, self.xdpiCmbBox, self.ydpiCmbBox) self.connect(self._table, SIGNAL("insertRowAfter(int)"), self.addFile) self.connect(self._table, SIGNAL("removeRowAt(int)"), self.removeFile) # self._table.setAcceptDrops(True) self.table.setAcceptDrops(True) self.scene = QGraphicsScene() self.view = QGraphicsView(self.scene) self.scale = False self.chkBoxScale = QCheckBox("See the Whole") self.connect(self.chkBoxScale, SIGNAL("toggled(bool)"), self.setScale) self.centralWidget.addWidget(self._table) vbox = QVBoxLayout() vbox.addWidget(self.chkBoxScale) vbox.addWidget(self.view) widget = QWidget() widget.setLayout(vbox) self.centralWidget.addWidget(widget) # self.centralWidget.addWidget(self.statusBar) savePrnAction = self.createAction('Create .prn', self.savePrnFile, QKeySequence.Save, 'save_as', 'Create test file') self.toolBar.addAction(savePrnAction) unpackPrnAction = self.createAction('Unpack .prn', self.unpackPrnFile, QKeySequence.Open, 'analyze', 'Unpack prn file') self.toolBar.addAction(unpackPrnAction) editHeaderAction = self.createAction( 'Edit .prn', self.changeResolution, QKeySequence(Qt.CTRL + Qt.Key_E), 'edit', 'Change print resolution in prn file') self.toolBar.addAction(editHeaderAction) self.pix = QPixmap() self.pix.convertFromImage(QImage()) self.grPixmap = QGraphicsPixmapItem(self.pix) self.scene.addItem(self.grPixmap) # self.view.scale(0.3, 0.3) self.setWindowTitle('PRN Creator {}'.format(self.ver)) self.setWindowIcon(QIcon('icons/icon.png')) desktop = QApplication.desktop() rect = desktop.availableGeometry() pos = self.settings.value('window/pos', QPoint(0, 0)) if pos.x() < rect.left(): x = rect.left() else: x = pos.x() if pos.y() < rect.top(): y = rect.top() else: y = pos.y() self.resize(self.settings.value('window/size', QSize(640, 480))) self.move(x, y) self.setWindowState( Qt.WindowState(int(self.settings.value('window/state', 0)))) def setScale(self, scaleBool): if not self.scene.sceneRect().size().isEmpty(): scaleX = self.view.size().width() / self.scene.sceneRect().size( ).width() scaleY = self.view.size().height() / self.scene.sceneRect().size( ).height() self.view.resetMatrix() if scaleBool: self.view.scale(min(scaleX, scaleY), min(scaleX, scaleY)) def dragEnterEvent(self, event): event.acceptProposedAction() def dropEvent(self, event): for file in event.mimeData().urls(): fi = QFileInfo(QFile(file.toLocalFile())) if fi.suffix() in self.acceptedFormats: self.addImageToTable(fi.filePath(), self.table.rowCount()) else: self.statusBar.showMessage( 'File format of {} not supported'.format(fi.fileName()), 5000) event.accept() def createColorComboBox(self, index): self.colorWidgets[index] = QComboBox() for color in self.listColors: self.colorWidgets[index].addItem( QIcon('icons/colors/{}.png'.format( self.colors[color] if color != 'Light Cyan' and color != 'Light Magenta' and color != 'Violet' and color != 'Medium Black' and color != 'Light Gray' else self.colors[color] + '_')), color) return self.colorWidgets[index] def createLevelComboBox(self, index): self.levelWidgets[index] = QComboBox() for level in range(1, 2**self.gsLevel): self.levelWidgets[index].addItem("Level {}".format(level), level) return self.levelWidgets[index] def tableCellActivated(self, row, column): self.scene.removeItem(self.grPixmap) image = self.table.item(row, 0).data(Qt.UserRole) self.pix.convertFromImage(image) self.grPixmap = QGraphicsPixmapItem(self.pix) self.scene.addItem(self.grPixmap) self.scene.setSceneRect(0, 0, float(image.width()), float(image.height())) self.setScale(self.chkBoxScale.isChecked()) def closeEvent(self, event): self.settings.setValue('window/size', self.size()) self.settings.setValue('window/pos', self.pos()) self.settings.setValue('window/state', self.windowState()) event.accept() def addFile(self, index): file = QFileDialog.getOpenFileName( self, 'Load image', directory=self.settings.value('directories/dir_open', QDir.currentPath()), filter='Bitmap graphics (*.tif *.bmp);;All (*)') if not file: return self.settings.setValue('directories/dir_open', QFileInfo(file).path()) self.settings.sync() self.addImageToTable(file, index) def addImageToTable(self, file, index): image = QImage(file) if image.format() == QImage.Format_Mono: self.table.insertRow(index) self.table.setItem(index, 0, QTableWidgetItem(QFileInfo(file).fileName())) self.table.item( index, 0).setFlags(Qt.ItemIsUserCheckable | Qt.ItemIsEnabled | Qt.ItemIsSelectable) self.table.item(index, 0).setData(Qt.UserRole, image) self.table.item(index, 0).setToolTip(file) self.table.setCellWidget(index, 1, self.createColorComboBox(index)) self.table.setCellWidget(index, 2, self.createLevelComboBox(index)) self.table.setCurrentCell(index, 0) self.table.setItem( index, 3, QTableWidgetItem("{}x{}".format(image.width(), image.height()))) self.table.item(index, 3).setFlags(Qt.ItemIsSelectable) else: self.statusBar.showMessage("Tiff file not monochrome ({})".format( image.format())) def removeFile(self, index): self.table.removeRow(index) self.table.setCurrentCell(index - 1, 0) try: del self.colorWidgets[index] del self.levelWidgets[index] except (KeyError, IndexError) as err: pass def fillCmbGSLevel(self, index): """ Фунция для заполнения списка уровней значениями. Вызывается при выборе уровня GS """ self.gsLevel = self.levelGS[self.cmbGS.currentText()] for widget in self.levelWidgets: if self.levelWidgets[widget] is not None: self.levelWidgets[widget].clear() for level in range(1, 2**self.gsLevel): self.levelWidgets[widget].addItem("Level {}".format(level), level) def savePrnFile(self): width = 0 height = 0 images = {} for index in range(self.table.rowCount()): image = self.table.item(index, 0).data(Qt.UserRole) color = self.colors[self.table.cellWidget(index, 1).currentText()] if color not in images: images[color] = {} levelCmb = self.table.cellWidget(index, 2) level = levelCmb.itemData(levelCmb.currentIndex()) if level in images[color]: QMessageBox.warning(self, "Error!", "Duplicated GS Level for color!") return else: images[color][level] = image if width != 0: if width != image.width(): QMessageBox.warning(self, "Error!", "Width of images does not match!") return else: width = image.width() if height != 0: if height != image.height(): QMessageBox.warning(self, "Error!", "Height of images does not match!") return else: height = image.height() fileName = QFileDialog.getSaveFileName( self, "Save .prn file", self.settings.value('directories/dir_save', QDir.currentPath()), "PRN Files (*.prn);;BIN Files (*.bin)") if not fileName: return file = QFile(fileName) if not file.open(QFile.WriteOnly): QMessageBox.warning( self, "Prn Creator", "Unable to write file {}:\n{}.".format(self.fileName, file.errorString())) return self.settings.setValue('directories/dir_save', QFileInfo(file).path()) self.testName, status = QInputDialog.getText( self, "Test name", "Enter name of the test to write into file:", text="Test") if not status: QMessageBox.warning(self, "Prn Creator", "Name changed to 'Test'") self.testName = "Test" self.fileName = QFileInfo(file).fileName() self.out = QDataStream(file) self.out.setByteOrder(QDataStream.LittleEndian) colors = '' for color in images: colors += color self.imgwidth = width self.imgheight = height self.bytesPerLine = int((self.gsLevel * self.imgwidth + 31) / 32) * 4 self.writeNewHeader(colors) pd = QProgressDialog('Writing file ...', 'Cancel', 0, self.imgheight - 1, self) pd.setWindowTitle('Creating file...') pd.open() tmp = 0 # Записывать данные будем построчно for row in range(self.imgheight): # обходим по порядку цветов, как расположены в файле for color in colors: # Добиваем строку до длины, кратной 32м байтам for column in range(int(self.bytesPerLine / self.gsLevel * 8)): shift = 7 - column + int(column / 8) * 8 pixel = 0 # Упорядочиваем уровни (на всякий) levels = sorted(list(images[color].keys())) # Если изображение меньше длины строки, то if column < self.imgwidth: for level in levels: # Выбираем максимальный уровень из тех, что указаны в данном пикселе на всех слоях if images[color][level].pixel(column, row) == self.black: pixel = level tmp |= (pixel << shift * self.gsLevel) # Как только сдвиг обнулится, то записываем в файл if not shift: self.out.writeRawData(tmp.to_bytes( self.gsLevel, 'big')) tmp = 0 pd.setValue(row) if pd.wasCanceled(): pd.close() file.close() return pd.close() file.close() self.status.showMessage("File created successful", 7000) def writeNewHeader(self, colors): xdpi = int(self.xdpiCmbBox.currentText()) ydpi = int(self.ydpiCmbBox.currentText()) self.paperWidth = 0 colorOrder = colors.encode() while len(colorOrder) < 16: colorOrder += bytes.fromhex('00') self.out.writeInt32(self.NEW_RIP_FILE) self.out.writeInt32(xdpi) self.out.writeInt32(ydpi) self.out.writeInt32(self.bytesPerLine) self.out.writeInt32(self.imgheight) self.out.writeInt32(self.imgwidth) self.out.writeInt32(self.paperWidth) self.out.writeInt32(len(colors)) self.out.writeInt32(self.gsLevel) self.out.writeRawData(colorOrder) name = self.testName.encode(encoding='utf_16')[ 2:514] # Удаляем первые два байта сигнатуры UTF-16 while len(name) < 256 * 2: # Дополняем до 256 символов WCHAR name += bytes.fromhex('00') self.out.writeRawData(name) self.out.writeInt32(0) # Зарезервировано def unpackPrnFile(self): fileName = QFileDialog.getOpenFileName( self, 'Load .prn file', directory=self.settings.value('unpacker/dir_open', QDir.currentPath()), filter='PRN files (*.prn *.bin);;All (*)') if not fileName: return file = QFile(fileName) if not file.open(QFile.ReadOnly): QMessageBox.warning( self, "Unpacker .prn", "Unable load file {}:\n{}.".format(fileName, file.errorString())) return self.settings.setValue('unpacker/dir_open', QFileInfo(file).path()) data = QDataStream(file) data.setByteOrder(QDataStream.LittleEndian) file_name = QFileInfo(file).fileName() headerVersion = int.from_bytes(data.readRawData(4), 'little', signed=False) self.status.showMessage("Header Type: {:#X}".format(headerVersion)) if headerVersion == self.NEW_RIP_FILE: xdpi = data.readInt32() ydpi = data.readInt32() bpl = data.readInt32() imgh = data.readInt32() imgw = data.readInt32() ppw = data.readInt32() colnum = data.readInt32() bitsperdrop = data.readInt32() colorOrder = data.readRawData(16).decode().replace(chr(0), '') colorList = list(colorOrder) name = b'\xff\xfe' + data.readRawData(512) name = name.decode('utf-16').replace(chr(0), '') zero = data.readInt32() elif headerVersion == self.STD_RIP_FILE: xdpi = data.readInt32() ydpi = data.readInt32() bpl = data.readInt32() imgh = data.readInt32() imgw = data.readInt32() ppw = data.readInt32() colnum = data.readInt32() bitsperdrop = data.readInt32() if not bitsperdrop: QMessageBox.warning(self, "Unpacker .prn", "File format not supported") return colorOrder = data.readRawData(16).decode().replace(chr(0), '') colorList = list(colorOrder) zero = data.readInt32() name = 'Not used in this format' elif headerVersion == self.CALDERA_RIP_FILE: xdpi = data.readInt32() ydpi = data.readInt32() bpl = data.readInt32() imgh = data.readInt32() imgw = data.readInt32() ppw = data.readInt32() colnum = data.readInt32() bitsperdrop = data.readInt32() if not bitsperdrop: QMessageBox.warning(self, "Unpacker .prn", "File format not supported") return colorOrder = data.readRawData(16).decode().replace(chr(0), '') colorList = list(colorOrder) zero = data.readInt32() name = 'Not used in this format' else: QMessageBox.warning(self, "Unpacker .prn", "File format not supported") return colors = {} for color in colorList: colors[color] = {} for level in range(1, 2**bitsperdrop): colors[color][level] = QImage(imgw, imgh, QImage.Format_Mono) colors[color][level].setColor(0, qRgb(255, 255, 255)) colors[color][level].setColor(1, qRgb(0, 0, 0)) colors[color][level].fill(0) pd = QProgressDialog('Analyze file ...', 'Cancel', 0, imgh - 1, self) pd.setWindowTitle('Analyze ...') pd.open() mask = 0xFF >> ( 8 - bitsperdrop ) # Получаем маску для текущего количества бит на каплю for row in range(imgh): for color in colorList: for bytenum in range( 0, bpl, bitsperdrop ): # Получаем номер байта, с которого будем читать byte = int.from_bytes(data.readRawData(bitsperdrop), 'big') for pix in range(8): shift = (7 - pix) * bitsperdrop pixel = (byte >> shift) & mask if pixel > 0: numofpix = 8 * bytenum / bitsperdrop + pix if numofpix < imgw: colors[color][pixel].setPixel(numofpix, row, 1) pd.setValue(row) if pd.wasCanceled(): pd.close() file.close() return pd.close() file.close() catalog = QFileDialog.getExistingDirectory( self, directory=self.settings.value('unpacker/dir_save', QDir.currentPath())) if catalog is None: return self.settings.setValue('unpacker/dir_save', catalog) file = QFile("{}\{}_{}.txt".format(catalog, file_name, colorOrder)) if not file.open(QFile.WriteOnly | QFile.Text): QMessageBox.warning( self, "Prn creator", "Unable create file {}:\n{}.".format(name, file.errorString())) return text = QTextStream(file) text << "Filename: {}\n".format(file_name) text << "Test Name: {}\n\n".format(name) text << "X Resolution: {} dpi\n".format(xdpi) text << "Y Resolution: {} dpi\n".format(ydpi) text << "Image Width: {} pix\n".format(imgw) text << "Image Height: {} pix\n\n".format(imgh) text << "Bits Per Drop: {}\n".format(bitsperdrop) text << "Bytes Per Line: {}\n\n".format(bpl) text << "Number Of Colors: {}\n".format(colnum) text << "Order Of Colors: {}\n\n".format(colorOrder) text << "Paper Width: {}\n".format(ppw) for color in colorList: for level in range(1, 2**bitsperdrop): colors[color][level].save("{}\{}.{}.gs{}.tif".format( catalog, file_name, "{}".format(color) if color.isupper() else "_{}".format(color), level)) self.status.showMessage("Unpacking finished", 7000) def changeResolution(self): fileName = QFileDialog.getOpenFileName( self, 'Load .prn file', directory=self.settings.value('unpacker/dir_open', QDir.currentPath()), filter='PRN files (*.prn *.bin);;All (*)') if not fileName: return file = QFile(fileName) if not file.open(QFile.ReadWrite): QMessageBox.warning( self, "Unpacker .prn", "Unable load file {}:\n{}.".format(fileName, file.errorString())) return self.settings.setValue('unpacker/dir_open', QFileInfo(file).path()) data = QDataStream(file) data.setByteOrder(QDataStream.LittleEndian) headerVersion = data.readInt32() xdpi = data.readInt32() ydpi = data.readInt32() dialog = ChangeResolutionDialog(xdpi, ydpi, self) if dialog.exec_(): file.seek(4) data.writeInt32(dialog.sbXdpi.value()) data.writeInt32(dialog.sbYdpi.value()) self.status.showMessage("Resolution changed successful", 7000) file.close() def createAction(self, text, slot=None, shortcut=None, icon=None, tip=None, checkable=False, signal='triggered()'): action = QAction(text, self) if icon is not None: action.setIcon(QIcon('icons/{}.png'.format(icon))) if shortcut is not None: action.setShortcut(shortcut) if tip is not None: action.setToolTip(tip) action.setStatusTip(tip) if slot is not None: self.connect(action, SIGNAL(signal), slot) if checkable: action.setCheckable(True) return action