|
|
@@ -0,0 +1,154 @@
|
|
|
+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)
|