bleed_generator_extension.py 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. from krita import *
  2. from PyQt5.QtWidgets import QDialog, QVBoxLayout, QHBoxLayout, QLabel, QLineEdit, QComboBox, QCheckBox, QPushButton
  3. from PyQt5.QtCore import *
  4. class BleedGenerator(Extension):
  5. def __init__(self, parent):
  6. super().__init__(parent)
  7. # Krita.instance() exists, so do any setup work
  8. def setup(self):
  9. pass
  10. # called after setup(self)
  11. def createActions(self, window):
  12. # Create menu item in Tools > Scripts.
  13. action = window.createAction("bleedgen", "Bleed Generator")
  14. action.triggered.connect(self.bleed_generator)
  15. def bleed_generator(self):
  16. # Get the current selected layer, called a 'node'
  17. self.doc = Krita.instance().activeDocument()
  18. self.layer = self.doc.activeNode()
  19. # Create dialog.
  20. newDialog = QDialog()
  21. newDialog.setWindowTitle("Bleed Generator!")
  22. desc = QLabel('Adds bleed to the active paint layer')
  23. desc.setAlignment(Qt.AlignCenter)
  24. # Count and unit inputs. Default to 2mm.
  25. self.countInput = QLineEdit('2')
  26. self.unitInput = QComboBox()
  27. self.unitInput.addItems( ['mm', 'inch', 'px'] )
  28. self.unitIndex = 0 # track current unit.
  29. self.offsetInput = QLineEdit('0')
  30. # Side selection
  31. self.topCheck = QCheckBox('Top')
  32. self.topCheck.setChecked(True)
  33. self.botCheck = QCheckBox('Bottom')
  34. self.botCheck.setChecked(True)
  35. self.leftCheck = QCheckBox('Left')
  36. self.leftCheck.setChecked(True)
  37. self.rightCheck = QCheckBox('Right')
  38. self.rightCheck.setChecked(True)
  39. # Button!
  40. goButton = QPushButton("Add Bleed")
  41. goButton.setIcon( Krita.instance().icon('animation_play') )
  42. # create layouts
  43. row0 = QHBoxLayout()
  44. row1 = QHBoxLayout()
  45. row2 = QHBoxLayout()
  46. row3 = QHBoxLayout()
  47. row0.addWidget(desc)
  48. row1.addWidget(QLabel('How much bleed:'))
  49. row1.addWidget(self.countInput)
  50. row1.addWidget(self.unitInput)
  51. row1.addWidget(QLabel('Offset (0 = use edge):'))
  52. row1.addWidget(self.offsetInput)
  53. row2.addWidget(QLabel('Sides to bleed:'))
  54. row2.addWidget(self.topCheck)
  55. row2.addWidget(self.botCheck)
  56. row2.addWidget(self.leftCheck)
  57. row2.addWidget(self.rightCheck)
  58. if self.layer.type() != 'paintlayer':
  59. desc.setText('Please select a paint layer!')
  60. else:
  61. row3.addWidget(goButton)
  62. layoutMain = QVBoxLayout()
  63. layoutMain.addLayout(row0)
  64. layoutMain.addLayout(row1)
  65. layoutMain.addLayout(row2)
  66. layoutMain.addLayout(row3)
  67. newDialog.setLayout(layoutMain)
  68. # hook up the actions.
  69. goButton.clicked.connect( self.generateBleed )
  70. # self.unitInput.currentIndexChanged.connect( self.convertCount )
  71. # show the dialog.
  72. newDialog.exec_()
  73. ##########
  74. # Slots
  75. ##########
  76. # Actually generates the bleed!
  77. def generateBleed(self, e):
  78. # Calculate how many lines of pixels to copy.
  79. unit = self.unitInput.currentIndex()
  80. count = float(self.countInput.text())
  81. ppi = self.doc.resolution()
  82. if unit == 0: # mm
  83. count = count * (ppi / 24.5)
  84. if unit == 1: # inch
  85. count = count * ppi
  86. offset = round(float(self.offsetInput.text()))
  87. count = round(count) - offset
  88. print("Pixel bleed amount: ", count)
  89. print("Edge offset: ", offset)
  90. # Copy lines for selected sides.
  91. if self.topCheck.checkState():
  92. bds = self.layer.bounds()
  93. xpos = bds.left()
  94. ypos = bds.top() - offset
  95. len = bds.width()
  96. bleedline = self.layer.pixelData(xpos, ypos, len, 1)
  97. for c in range(1, count+1):
  98. self.layer.setPixelData(bleedline, xpos, (ypos - c), len, 1)
  99. print("Top lines cloned: ", count)
  100. if self.botCheck.checkState():
  101. bds = self.layer.bounds()
  102. xpos = bds.left()
  103. ypos = bds.bottom() + offset
  104. len = bds.width()
  105. bleedline = self.layer.pixelData(xpos, ypos, len, 1)
  106. for c in range(1, count+1):
  107. self.layer.setPixelData(bleedline, xpos, (ypos + c), len, 1)
  108. print("Bottom lines cloned: ", count)
  109. if self.leftCheck.checkState():
  110. bds = self.layer.bounds()
  111. xpos = bds.left() - offset
  112. ypos = bds.top()
  113. len = bds.height()
  114. bleedline = self.layer.pixelData(xpos, ypos, 1, len)
  115. for c in range(1, count+1):
  116. self.layer.setPixelData(bleedline, (xpos - c), ypos, 1, len)
  117. print("Left lines cloned: ", count)
  118. if self.rightCheck.checkState():
  119. bds = self.layer.bounds()
  120. xpos = bds.right() + offset
  121. ypos = bds.top()
  122. len = bds.height()
  123. bleedline = self.layer.pixelData(xpos, ypos, 1, len)
  124. for c in range(1, count+1):
  125. self.layer.setPixelData(bleedline, (xpos + c), ypos, 1, len)
  126. print("Right lines cloned: ", count)
  127. self.doc.refreshProjection()
  128. # Convert count input values to relevant units
  129. def convertCount():
  130. unitIndex = unitInput.currentIndex()
  131. print("Updated unit index: ", unitIndex)