from krita import * from PyQt5.QtWidgets import QDialog, QVBoxLayout, QHBoxLayout, QLabel, QLineEdit, QComboBox, QCheckBox, QPushButton from PyQt5.QtCore import * class BleedGenerator(Extension): def __init__(self, parent): super().__init__(parent) # Krita.instance() exists, so do any setup work def setup(self): pass # called after setup(self) def createActions(self, window): # Create menu item in Tools > Scripts. action = window.createAction("bleedgen", "Bleed Generator") action.triggered.connect(self.bleed_generator) def bleed_generator(self): # Get the current selected layer, called a 'node' self.doc = Krita.instance().activeDocument() self.layer = self.doc.activeNode() # Create dialog. newDialog = QDialog() newDialog.setWindowTitle("Bleed Generator!") desc = QLabel('Adds bleed to the active paint layer') desc.setAlignment(Qt.AlignCenter) # Count and unit inputs. Default to 2mm. self.countInput = QLineEdit('2') self.unitInput = QComboBox() self.unitInput.addItems( ['mm', 'inch', 'px'] ) self.unitIndex = 0 # track current unit. self.offsetInput = QLineEdit('0') # Side selection self.topCheck = QCheckBox('Top') self.topCheck.setChecked(True) self.botCheck = QCheckBox('Bottom') self.botCheck.setChecked(True) self.leftCheck = QCheckBox('Left') self.leftCheck.setChecked(True) self.rightCheck = QCheckBox('Right') self.rightCheck.setChecked(True) # Button! goButton = QPushButton("Add Bleed") goButton.setIcon( Krita.instance().icon('animation_play') ) # create layouts row0 = QHBoxLayout() row1 = QHBoxLayout() row2 = QHBoxLayout() row3 = QHBoxLayout() row0.addWidget(desc) row1.addWidget(QLabel('How much bleed:')) row1.addWidget(self.countInput) row1.addWidget(self.unitInput) row1.addWidget(QLabel('Offset (0 = use edge):')) row1.addWidget(self.offsetInput) row2.addWidget(QLabel('Sides to bleed:')) row2.addWidget(self.topCheck) row2.addWidget(self.botCheck) row2.addWidget(self.leftCheck) row2.addWidget(self.rightCheck) if self.layer.type() != 'paintlayer': desc.setText('Please select a paint layer!') else: row3.addWidget(goButton) layoutMain = QVBoxLayout() layoutMain.addLayout(row0) layoutMain.addLayout(row1) layoutMain.addLayout(row2) layoutMain.addLayout(row3) newDialog.setLayout(layoutMain) # hook up the actions. goButton.clicked.connect( self.generateBleed ) # self.unitInput.currentIndexChanged.connect( self.convertCount ) # show the dialog. newDialog.exec_() ########## # Slots ########## # Actually generates the bleed! def generateBleed(self, e): # Calculate how many lines of pixels to copy. unit = self.unitInput.currentIndex() count = float(self.countInput.text()) ppi = self.doc.resolution() if unit == 0: # mm count = count * (ppi / 24.5) if unit == 1: # inch count = count * ppi offset = round(float(self.offsetInput.text())) count = round(count) - offset print("Pixel bleed amount: ", count) print("Edge offset: ", offset) # Copy lines for selected sides. if self.topCheck.checkState(): bds = self.layer.bounds() xpos = bds.left() ypos = bds.top() - offset len = bds.width() bleedline = self.layer.pixelData(xpos, ypos, len, 1) for c in range(1, count+1): self.layer.setPixelData(bleedline, xpos, (ypos - c), len, 1) print("Top lines cloned: ", count) if self.botCheck.checkState(): bds = self.layer.bounds() xpos = bds.left() ypos = bds.bottom() + offset len = bds.width() bleedline = self.layer.pixelData(xpos, ypos, len, 1) for c in range(1, count+1): self.layer.setPixelData(bleedline, xpos, (ypos + c), len, 1) print("Bottom lines cloned: ", count) if self.leftCheck.checkState(): bds = self.layer.bounds() xpos = bds.left() - offset ypos = bds.top() len = bds.height() bleedline = self.layer.pixelData(xpos, ypos, 1, len) for c in range(1, count+1): self.layer.setPixelData(bleedline, (xpos - c), ypos, 1, len) print("Left lines cloned: ", count) if self.rightCheck.checkState(): bds = self.layer.bounds() xpos = bds.right() + offset ypos = bds.top() len = bds.height() bleedline = self.layer.pixelData(xpos, ypos, 1, len) for c in range(1, count+1): self.layer.setPixelData(bleedline, (xpos + c), ypos, 1, len) print("Right lines cloned: ", count) self.doc.refreshProjection() # Convert count input values to relevant units def convertCount(): unitIndex = unitInput.currentIndex() print("Updated unit index: ", unitIndex)