Krita Source Code Documentation
Loading...
Searching...
No Matches
channels2layers.channels2layers.ChannelsToLayers Class Reference
+ Inheritance diagram for channels2layers.channels2layers.ChannelsToLayers:

Public Member Functions

 __init__ (self, parent)
 
 action_triggered (self)
 
 checkCurrentLayer (self)
 
 createActions (self, window)
 
 dBoxMessage (self, msgType, msg)
 
 openDialogOptions (self)
 
 process (self, pDocument, pOriginalLayer, pProgress)
 
 progressNext (self, pProgress)
 
 run (self)
 
 setup (self)
 
 toQImage (self, layerNode, rect=None)
 
 translateDictKey (self, key, value)
 

Public Attributes

 action_triggered
 
 layerNum
 
 parent
 

Private Attributes

 __outputOptions
 
 __sourceDocument
 
 __sourceLayer
 

Detailed Description

Definition at line 826 of file channels2layers.py.

Constructor & Destructor Documentation

◆ __init__()

channels2layers.channels2layers.ChannelsToLayers.__init__ ( self,
parent )

Definition at line 828 of file channels2layers.py.

828 def __init__(self, parent):
829 # Default options
830 self.__outputOptions = {
831 'outputMode': OUTPUT_MODE_RGB,
832 'originalLayerAction': ORIGINAL_LAYER_KEEPHIDDEN,
833 'layerGroupName': '{mode}-{source:name}',
834 'layerColorName': '{mode}[{color:short}]-{source:name}'
835 }
836
837 self.__sourceDocument = None
838 self.__sourceLayer = None
839
840 # Always initialise the superclass.
841 # This is necessary to create the underlying C++ object
842 super().__init__(parent)
843 self.parent = parent
844
845

Member Function Documentation

◆ action_triggered()

channels2layers.channels2layers.ChannelsToLayers.action_triggered ( self)
Action called when script is executed from Kitra menu

Definition at line 870 of file channels2layers.py.

870 def action_triggered(self):
871 """Action called when script is executed from Kitra menu"""
872 if self.checkCurrentLayer():
873 if self.openDialogOptions():
874 self.run()
875
876

◆ checkCurrentLayer()

channels2layers.channels2layers.ChannelsToLayers.checkCurrentLayer ( self)
Check if current layer is valid
   - A document must be opened
   - Active layer properties must be:
     . Layer type:  a paint layer
     . Color model: RGBA
     . Color depth: 8bits

Definition at line 888 of file channels2layers.py.

888 def checkCurrentLayer(self):
889 """Check if current layer is valid
890 - A document must be opened
891 - Active layer properties must be:
892 . Layer type: a paint layer
893 . Color model: RGBA
894 . Color depth: 8bits
895 """
896 self.__sourceDocument = Application.activeDocument()
897 # Check if there's an active document
898 if self.__sourceDocument is None:
899 self.dBoxMessage(DBOX_WARNING, "There's no active document!")
900 return False
901
902 self.__sourceLayer = self.__sourceDocument.activeNode()
903
904 # Check if current layer can be processed
905 if self.__sourceLayer.type() != "paintlayer" or self.__sourceLayer.colorModel() != "RGBA" or self.__sourceLayer.colorDepth() != "U8":
906 self.dBoxMessage(DBOX_WARNING, "Selected layer must be a 8bits RGBA Paint Layer!"
907 "\n\nCurrent layer '{0}' properties:"
908 "\n- Layer type: {1}"
909 "\n- Color model: {2} ({3})"
910 "\n- Color depth: {4}"
911 "\n\n> Action is cancelled".format(self.__sourceLayer.name(),
912 self.translateDictKey('layerType', self.__sourceLayer.type()),
913 self.__sourceLayer.colorModel(), self.translateDictKey('colorModel', self.__sourceLayer.colorModel()),
914 self.translateDictKey('colorDepth', self.__sourceLayer.colorDepth())
915 ))
916 return False
917
918 return True
919
920
921

◆ createActions()

channels2layers.channels2layers.ChannelsToLayers.createActions ( self,
window )

Definition at line 850 of file channels2layers.py.

850 def createActions(self, window):
851 action = window.createAction(EXTENSION_ID, PLUGIN_MENU_ENTRY, "tools/scripts")
852 action.triggered.connect(self.action_triggered)
853

◆ dBoxMessage()

channels2layers.channels2layers.ChannelsToLayers.dBoxMessage ( self,
msgType,
msg )
Simplified function for DialogBox 'OK' message

Definition at line 854 of file channels2layers.py.

854 def dBoxMessage(self, msgType, msg):
855 """Simplified function for DialogBox 'OK' message"""
856 if msgType == DBOX_WARNING:
857 QMessageBox.warning(
858 QWidget(),
859 PLUGIN_DIALOG_TITLE,
860 i18n(msg)
861 )
862 else:
863 QMessageBox.information(
864 QWidget(),
865 PLUGIN_DIALOG_TITLE,
866 i18n(msg)
867 )
868
869

◆ openDialogOptions()

channels2layers.channels2layers.ChannelsToLayers.openDialogOptions ( self)
Open dialog box to let user define channel extraction options

Definition at line 944 of file channels2layers.py.

944 def openDialogOptions(self):
945 """Open dialog box to let user define channel extraction options"""
946
947 tmpDocument = None
948 previewBaSrc = QByteArray()
949 lblPreview = [QLabel(), QLabel(), QLabel(), QLabel()]
950 lblPreviewLbl = [QLabel(), QLabel(), QLabel(), QLabel()]
951
952
953 # ----------------------------------------------------------------------
954 # Define signal and slots for UI widgets
955 @pyqtSlot('QString')
956 def ledLayerGroupName_Changed(value):
957 self.__outputOptions['layerGroupName'] = value
958
959 @pyqtSlot('QString')
960 def ledLayerColorName_Changed(value):
961 self.__outputOptions['layerColorName'] = value
962
963 @pyqtSlot('QString')
964 def cmbOutputMode_Changed(value):
965 self.__outputOptions['outputMode'] = value
966 buildPreview()
967
968 @pyqtSlot('QString')
969 def cmbOriginalLayerAction_Changed(value):
970 self.__outputOptions['originalLayerAction'] = value
971
972 def buildPreview():
973 pbProgress.setVisible(True)
974
975 backupValue = self.__outputOptions['layerColorName']
976 self.__outputOptions['layerColorName'] = '{color:long}'
977
978 # create a temporary document to work
979 tmpDocument = Application.createDocument(imgThumbSrc.width(), imgThumbSrc.height(), "tmp", "RGBA", "U8", "", 120.0)
980
981 # create a layer used as original layer
982 originalLayer = tmpDocument.createNode("Original", "paintlayer")
983 tmpDocument.rootNode().addChildNode(originalLayer, None)
984 # and set original image content
985 originalLayer.setPixelData(previewBaSrc, 0, 0, tmpDocument.width(), tmpDocument.height())
986
987 # execute process
988 groupLayer = self.process(tmpDocument, originalLayer, pbProgress)
989
990 self.__outputOptions['layerColorName'] = backupValue
991
992 originalLayer.setVisible(False)
993 groupLayer.setVisible(True)
994
995 for layer in groupLayer.childNodes():
996 layer.setBlendingMode('normal')
997 layer.setVisible(False)
998 tmpDocument.refreshProjection()
999
1000 index = 0
1001 for layer in groupLayer.childNodes():
1002 layer.setVisible(True)
1003 tmpDocument.refreshProjection()
1004
1005 lblPreview[index].setPixmap(QPixmap.fromImage(tmpDocument.projection(0, 0, tmpDocument.width(), tmpDocument.height())))
1006 lblPreviewLbl[index].setText("<i>{0}</i>".format(layer.name()))
1007 layer.setVisible(False)
1008
1009 index+=1
1010
1011 if index > 3:
1012 lblPreview[3].setVisible(True)
1013 lblPreviewLbl[3].setVisible(True)
1014 else:
1015 lblPreview[3].setVisible(False)
1016 lblPreviewLbl[3].setVisible(False)
1017
1018
1019 tmpDocument.close()
1020
1021 pbProgress.setVisible(False)
1022
1023
1024 # ----------------------------------------------------------------------
1025 # Create dialog box
1026 dlgMain = QDialog(Application.activeWindow().qwindow())
1027 dlgMain.setWindowTitle(PLUGIN_DIALOG_TITLE)
1028 # resizeable with minimum size
1029 dlgMain.setSizeGripEnabled(True)
1030 dlgMain.setMinimumSize(DOPT_MIN_WIDTH, DOPT_MIN_HEIGHT)
1031 dlgMain.setModal(True)
1032
1033 # ......................................................................
1034 # main dialog box, container
1035 vbxMainContainer = QVBoxLayout(dlgMain)
1036
1037 # main dialog box, current layer name
1038 lblLayerName = QLabel("{0} <b><i>{1}</i></b>".format(i18n("Processing layer"), self.__sourceLayer.name()))
1039 lblLayerName.setFixedHeight(30)
1040 vbxMainContainer.addWidget(lblLayerName)
1041
1042 # main dialog box, groupbox for layers options
1043 gbxLayersMgt = QGroupBox("Layers management")
1044 vbxMainContainer.addWidget(gbxLayersMgt)
1045
1046 # main dialog box, groupbox for output options
1047 gbxOutputResults = QGroupBox("Output results")
1048 vbxMainContainer.addWidget(gbxOutputResults)
1049
1050 vbxMainContainer.addStretch()
1051
1052 # main dialog box, OK/Cancel buttons
1053 dbbxOkCancel = QDialogButtonBox(dlgMain)
1054 dbbxOkCancel.setOrientation(Qt.Orientation.Horizontal)
1055 dbbxOkCancel.setStandardButtons(QDialogButtonBox.StandardButton.Ok | QDialogButtonBox.StandardButton.Cancel)
1056 dbbxOkCancel.accepted.connect(dlgMain.accept)
1057 dbbxOkCancel.rejected.connect(dlgMain.reject)
1058 vbxMainContainer.addWidget(dbbxOkCancel)
1059
1060 # ......................................................................
1061 # create layout for groupbox "Layers management"
1062 flLayersMgt = QFormLayout()
1063 gbxLayersMgt.setLayout(flLayersMgt)
1064
1065 ledLayerGroupName = QLineEdit()
1066 ledLayerGroupName.setText(self.__outputOptions['layerGroupName'])
1067 ledLayerGroupName.textChanged.connect(ledLayerGroupName_Changed)
1068 flLayersMgt.addRow(i18nc('The name for a new group layer; the generated layers will be placed in this group.', 'New layer group name'), ledLayerGroupName)
1069
1070 ledLayerColorName = QLineEdit()
1071 ledLayerColorName.setText(self.__outputOptions['layerColorName'])
1072 ledLayerColorName.textChanged.connect(ledLayerColorName_Changed)
1073 flLayersMgt.addRow(i18nc('Defines how the name for each layer created from the channel is generated.', 'New layers color name'), ledLayerColorName)
1074
1075 cmbOriginalLayerAction = QComboBox()
1076 cmbOriginalLayerAction.addItems([
1077 ORIGINAL_LAYER_KEEPUNCHANGED,
1078 ORIGINAL_LAYER_KEEPVISIBLE,
1079 ORIGINAL_LAYER_KEEPHIDDEN,
1080 ORIGINAL_LAYER_REMOVE
1081 ])
1082 cmbOriginalLayerAction.setCurrentText(self.__outputOptions['originalLayerAction'])
1083 cmbOriginalLayerAction.currentTextChanged.connect(cmbOriginalLayerAction_Changed)
1084 flLayersMgt.addRow(i18n("Original layer"), cmbOriginalLayerAction)
1085
1086 # ......................................................................
1087 # create layout for groupbox "Output results"
1088 flOutputResults = QFormLayout()
1089 gbxOutputResults.setLayout(flOutputResults)
1090
1091 cmbOutputMode = QComboBox()
1092 cmbOutputMode.addItems([
1093 OUTPUT_MODE_RGB,
1094 OUTPUT_MODE_CMY,
1095 OUTPUT_MODE_CMYK,
1096 OUTPUT_MODE_LRGB,
1097 OUTPUT_MODE_LCMY,
1098 OUTPUT_MODE_LCMYK
1099 ])
1100 cmbOutputMode.setCurrentText(self.__outputOptions['outputMode'])
1101 cmbOutputMode.currentTextChanged.connect(cmbOutputMode_Changed)
1102 flOutputResults.addRow(i18n("Mode"), cmbOutputMode)
1103
1104 vbxPreviewLblContainer = QHBoxLayout()
1105 flOutputResults.addRow('', vbxPreviewLblContainer)
1106 vbxPreviewContainer = QHBoxLayout()
1107 flOutputResults.addRow('', vbxPreviewContainer)
1108
1109 # add preview progressbar
1110 pbProgress = QProgressBar()
1111 pbProgress.setFixedHeight(8)
1112 pbProgress.setTextVisible(False)
1113 pbProgress.setVisible(False)
1114 pbProgress.setRange(0, 107)
1115 flOutputResults.addRow('', pbProgress)
1116
1117
1118 imageRatio = self.__sourceDocument.width() / self.__sourceDocument.height()
1119 rect = QRect(0, 0, OUTPUT_PREVIEW_MAXSIZE, OUTPUT_PREVIEW_MAXSIZE)
1120
1121 # always ensure that final preview width and/or height is lower or equal than OUTPUT_PREVIEW_MAXSIZE
1122 if imageRatio < 1:
1123 # width < height
1124 rect.setWidth(int(imageRatio * OUTPUT_PREVIEW_MAXSIZE))
1125 else:
1126 # width >= height
1127 rect.setHeight(int(OUTPUT_PREVIEW_MAXSIZE / imageRatio))
1128
1129 imgThumbSrc = self.toQImage(self.__sourceLayer, rect)
1130
1131 previewBaSrc.resize(imgThumbSrc.sizeInBytes())
1132 ptr = imgThumbSrc.bits()
1133 ptr.setsize(imgThumbSrc.sizeInBytes())
1134 previewBaSrc = QByteArray(ptr.asstring())
1135
1136
1137 lblPreviewSrc = QLabel()
1138 lblPreviewSrc.setPixmap(QPixmap.fromImage(imgThumbSrc))
1139 lblPreviewSrc.setFixedHeight(imgThumbSrc.height() + 4)
1140 lblPreviewSrc.setFixedWidth(imgThumbSrc.width() + 4)
1141 vbxPreviewContainer.addWidget(lblPreviewSrc)
1142
1143 lblPreviewLblSrc = QLabel(i18nc("the original layer", "Original"))
1144 lblPreviewLblSrc.setFixedWidth(imgThumbSrc.width() + 4)
1145 vbxPreviewLblContainer.addWidget(lblPreviewLblSrc)
1146
1147
1148 vbxPreviewLblContainer.addWidget(QLabel(" "))
1149 vbxPreviewContainer.addWidget(QLabel(">"))
1150
1151 lblPreview[3].setPixmap(QPixmap.fromImage(imgThumbSrc))
1152 lblPreview[3].setFixedHeight(imgThumbSrc.height() + 4)
1153 lblPreview[3].setFixedWidth(imgThumbSrc.width() + 4)
1154 vbxPreviewContainer.addWidget(lblPreview[3])
1155
1156 lblPreviewLbl[3] = QLabel(i18n("<i>Cyan</i>"))
1157 lblPreviewLbl[3].setIndent(10)
1158 lblPreviewLbl[3].setFixedWidth(imgThumbSrc.width() + 4)
1159 vbxPreviewLblContainer.addWidget(lblPreviewLbl[3])
1160
1161
1162 lblPreview[2] = QLabel()
1163 lblPreview[2].setPixmap(QPixmap.fromImage(imgThumbSrc))
1164 lblPreview[2].setFixedHeight(imgThumbSrc.height() + 4)
1165 lblPreview[2].setFixedWidth(imgThumbSrc.width() + 4)
1166 vbxPreviewContainer.addWidget(lblPreview[2])
1167
1168 lblPreviewLbl[2] = QLabel(i18n("<i>Magenta</i>"))
1169 lblPreviewLbl[2].setIndent(10)
1170 lblPreviewLbl[2].setFixedWidth(imgThumbSrc.width() + 4)
1171 vbxPreviewLblContainer.addWidget(lblPreviewLbl[2])
1172
1173
1174 lblPreview[1] = QLabel()
1175 lblPreview[1].setPixmap(QPixmap.fromImage(imgThumbSrc))
1176 lblPreview[1].setFixedHeight(imgThumbSrc.height() + 4)
1177 lblPreview[1].setFixedWidth(imgThumbSrc.width() + 4)
1178 vbxPreviewContainer.addWidget(lblPreview[1])
1179
1180 lblPreviewLbl[1] = QLabel(i18n("<i>Yellow</i>"))
1181 lblPreviewLbl[1].setIndent(10)
1182 lblPreviewLbl[1].setFixedWidth(imgThumbSrc.width() + 4)
1183 vbxPreviewLblContainer.addWidget(lblPreviewLbl[1])
1184
1185
1186 lblPreview[0] = QLabel()
1187 lblPreview[0].setPixmap(QPixmap.fromImage(imgThumbSrc))
1188 lblPreview[0].setFixedHeight(imgThumbSrc.height() + 4)
1189 lblPreview[0].setFixedWidth(imgThumbSrc.width() + 4)
1190 vbxPreviewContainer.addWidget(lblPreview[0])
1191
1192 lblPreviewLbl[0] = QLabel(i18n("<i>Black</i>"))
1193 lblPreviewLbl[0].setIndent(10)
1194 lblPreviewLbl[0].setFixedWidth(imgThumbSrc.width() + 4)
1195 vbxPreviewLblContainer.addWidget(lblPreviewLbl[0])
1196
1197
1198 vbxPreviewLblContainer.addStretch()
1199 vbxPreviewContainer.addStretch()
1200
1201 buildPreview()
1202
1203 returned = dlgMain.exec()
1204
1205 return returned
1206
1207

◆ process()

channels2layers.channels2layers.ChannelsToLayers.process ( self,
pDocument,
pOriginalLayer,
pProgress )
Process given layer with current options

Definition at line 1232 of file channels2layers.py.

1232 def process(self, pDocument, pOriginalLayer, pProgress):
1233 """Process given layer with current options"""
1234
1235 self.layerNum = 0
1236 document = pDocument
1237 originalLayer = pOriginalLayer
1238 parentGroupLayer = None
1239 currentProcessedLayer = None
1240 originalLayerIsVisible = originalLayer.visible()
1241
1242
1243 def getLayerByName(parent, value):
1244 """search and return a layer by name, within given parent group"""
1245 if parent == None:
1246 return document.nodeByName(value)
1247
1248 for layer in parent.childNodes():
1249 if layer.name() == value:
1250 return layer
1251
1252 return None
1253
1254
1255 def duplicateLayer(currentProcessedLayer, value):
1256 """Duplicate layer from given name
1257 New layer become active layer
1258 """
1259
1260 newLayer = None
1261 srcLayer = None
1262 srcName = re.match("^@(.*)", value)
1263
1264 if not srcName is None:
1265 # reference to a specific layer
1266 if srcName[1] == 'original':
1267 # original layer currently processed
1268 srcLayer = originalLayer
1269 else:
1270 # a color layer previously built (and finished)
1271 srcLayer = getLayerByName(parentGroupLayer, parseLayerName(self.__outputOptions['layerColorName'], srcName[1]))
1272 else:
1273 # a layer with a fixed name
1274 srcLayer = document.nodeByName(parseLayerName(value, ''))
1275
1276
1277 if not srcLayer is None:
1278 newLayer = srcLayer.duplicate()
1279
1280 self.layerNum+=1
1281 newLayer.setName("c2l-w{0}".format(self.layerNum))
1282
1283 parentGroupLayer.addChildNode(newLayer, currentProcessedLayer)
1284 return newLayer
1285 else:
1286 return None
1287
1288
1289 def newLayer(currentProcessedLayer, value):
1290 """Create a new layer of given type
1291 New layer become active layer
1292 """
1293
1294 newLayer = None
1295
1296 if value is None or not value['type'] in ['filllayer']:
1297 # given type for new layer is not valid
1298 # currently only one layer type is implemented
1299 return None
1300
1301 if value['type'] == 'filllayer':
1302 infoObject = InfoObject();
1303 infoObject.setProperty("color", value['color'])
1304 selection = Selection();
1305 selection.select(0, 0, document.width(), document.height(), 255)
1306
1307 newLayer = document.createFillLayer(value['color'].name(), "color", infoObject, selection)
1308
1309
1310 if newLayer:
1311 self.layerNum+=1
1312 newLayer.setName("c2l-w{0}".format(self.layerNum))
1313
1314 parentGroupLayer.addChildNode(newLayer, currentProcessedLayer)
1315
1316 # Need to force generator otherwise, information provided when creating layer seems to not be taken in
1317 # account
1318 newLayer.setGenerator("color", infoObject)
1319
1320 return newLayer
1321 else:
1322 return None
1323
1324
1325 def mergeDown(currentProcessedLayer, value):
1326 """Merge current layer with layer below"""
1327 if currentProcessedLayer is None:
1328 return None
1329
1330 newLayer = currentProcessedLayer.mergeDown()
1331 # note:
1332 # when layer is merged down:
1333 # - a new layer seems to be created (reference to 'down' layer does not match anymore layer in group)
1334 # - retrieved 'newLayer' reference does not match to new layer resulting from merge
1335 # - activeNode() in document doesn't match to new layer resulting from merge
1336 # maybe it's norpmal, maybe not...
1337 # but the only solution to be able to work on merged layer (with current script) is to consider that from
1338 # parent node, last child match to last added layer and then, to our merged layer
1339 currentProcessedLayer = parentGroupLayer.childNodes()[-1]
1340 # for an unknown reason, merged layer bounds are not corrects... :'-(
1341 currentProcessedLayer.cropNode(0, 0, document.width(), document.height())
1342 return currentProcessedLayer
1343
1344
1345 def applyBlendingMode(currentProcessedLayer, value):
1346 """Set blending mode for current layer"""
1347 if currentProcessedLayer is None or value is None or value == '':
1348 return False
1349
1350 currentProcessedLayer.setBlendingMode(value)
1351 return True
1352
1353
1354 def applyFilter(currentProcessedLayer, value):
1355 """Apply filter to layer"""
1356 if currentProcessedLayer is None or value is None or value == '':
1357 return None
1358
1359 filterName = re.match("name=([^;]+)", value)
1360
1361 if filterName is None:
1362 return None
1363
1364 filter = Application.filter(filterName.group(1))
1365 filterConfiguration = filter.configuration()
1366
1367 for parameter in value.split(';'):
1368 parameterName = re.match("^([^=]+)=(.*)", parameter)
1369
1370 if not parameterName is None and parameterName != 'name':
1371 filterConfiguration.setProperty(parameterName.group(1), parameterName.group(2))
1372
1373 filter.setConfiguration(filterConfiguration)
1374 filter.apply(currentProcessedLayer, 0, 0, document.width(), document.height())
1375
1376 return currentProcessedLayer
1377
1378
1379 def parseLayerName(value, color):
1380 """Parse layer name"""
1381
1382 returned = value
1383
1384 returned = returned.replace("{source:name}", originalLayer.name())
1385 returned = returned.replace("{mode}", OUTPUT_MODE_NFO[self.__outputOptions['outputMode']]['groupLayerName'])
1386 returned = returned.replace("{color:short}", color)
1387 if color == "C":
1388 returned = returned.replace("{color:long}", i18n("Cyan"))
1389 elif color == "M":
1390 returned = returned.replace("{color:long}", i18n("Magenta"))
1391 elif color == "Y":
1392 returned = returned.replace("{color:long}", i18n("Yellow"))
1393 elif color == "K":
1394 returned = returned.replace("{color:long}", i18n("Black"))
1395 elif color == "R":
1396 returned = returned.replace("{color:long}", i18n("Red"))
1397 elif color == "G":
1398 returned = returned.replace("{color:long}", i18n("Green"))
1399 elif color == "B":
1400 returned = returned.replace("{color:long}", i18n("Blue"))
1401 else:
1402 returned = returned.replace("{color:long}", "")
1403
1404 return returned
1405
1406
1407 if document is None or originalLayer is None:
1408 # should not occurs, but...
1409 return None
1410
1411 if not pProgress is None:
1412 stepTotal = 4
1413 for layer in OUTPUT_MODE_NFO[self.__outputOptions['outputMode']]['layers']:
1414 stepTotal+=len(layer['process'])
1415
1416 pProgress.setRange(0, stepTotal)
1417
1418
1419 if originalLayerIsVisible == False:
1420 originalLayer.setVisible(True)
1421
1422 # ----------------------------------------------------------------------
1423 # Create new group layer
1424 parentGroupLayer = document.createGroupLayer(parseLayerName(self.__outputOptions['layerGroupName'], ''))
1425
1426 self.progressNext(pProgress)
1427
1428 currentProcessedLayer = None
1429
1430 for layer in OUTPUT_MODE_NFO[self.__outputOptions['outputMode']]['layers']:
1431 for process in layer['process']:
1432 if process['action'] == 'duplicate':
1433 currentProcessedLayer = duplicateLayer(currentProcessedLayer, process['value'])
1434 elif process['action'] == 'new':
1435 currentProcessedLayer = newLayer(currentProcessedLayer, process['value'])
1436 elif process['action'] == 'merge down':
1437 currentProcessedLayer = mergeDown(currentProcessedLayer, process['value'])
1438 pass
1439 elif process['action'] == 'blending mode':
1440 applyBlendingMode(currentProcessedLayer, process['value'])
1441 elif process['action'] == 'filter':
1442 applyFilter(currentProcessedLayer, process['value'])
1443
1444 self.progressNext(pProgress)
1445
1446 if not currentProcessedLayer is None:
1447 # rename currentProcessedLayer
1448 currentProcessedLayer.setName(parseLayerName(self.__outputOptions['layerColorName'], layer['color']))
1449
1450 document.rootNode().addChildNode(parentGroupLayer, originalLayer)
1451 self.progressNext(pProgress)
1452
1453 if self.__outputOptions['originalLayerAction'] == ORIGINAL_LAYER_KEEPVISIBLE:
1454 originalLayer.setVisible(True)
1455 elif self.__outputOptions['originalLayerAction'] == ORIGINAL_LAYER_KEEPHIDDEN:
1456 originalLayer.setVisible(False)
1457 elif self.__outputOptions['originalLayerAction'] == ORIGINAL_LAYER_REMOVE:
1458 originalLayer.remove()
1459 else:
1460 # ORIGINAL_LAYER_KEEPUNCHANGED
1461 originalLayer.setVisible(originalLayerIsVisible)
1462
1463
1464 self.progressNext(pProgress)
1465
1466 document.refreshProjection()
1467 self.progressNext(pProgress)
1468
1469 document.setActiveNode(parentGroupLayer)
1470
1471 return parentGroupLayer
1472
1473
1474#ChannelsToLayers(Krita.instance()).process(Application.activeDocument(), Application.activeDocument().activeNode(), None)
1475#ChannelsToLayers(Krita.instance()).action_triggered()

◆ progressNext()

channels2layers.channels2layers.ChannelsToLayers.progressNext ( self,
pProgress )
Update progress bar

Definition at line 1208 of file channels2layers.py.

1208 def progressNext(self, pProgress):
1209 """Update progress bar"""
1210 if pProgress is not None:
1211 stepCurrent=pProgress.value()+1
1212 pProgress.setValue(stepCurrent)
1213 QApplication.instance().processEvents()
1214
1215

◆ run()

channels2layers.channels2layers.ChannelsToLayers.run ( self)
Run process for current layer

Definition at line 1216 of file channels2layers.py.

1216 def run(self):
1217 """Run process for current layer"""
1218
1219 pdlgProgress = QProgressDialog(self.__outputOptions['outputMode'], None, 0, 100, Application.activeWindow().qwindow())
1220 pdlgProgress.setWindowTitle(PLUGIN_DIALOG_TITLE)
1221 pdlgProgress.setMinimumSize(640, 200)
1222 pdlgProgress.setModal(True)
1223 pdlgProgress.show()
1224
1225 self.process(self.__sourceDocument, self.__sourceLayer, pdlgProgress)
1226
1227 pdlgProgress.close()
1228
1229
1230
1231

◆ setup()

channels2layers.channels2layers.ChannelsToLayers.setup ( self)

Definition at line 846 of file channels2layers.py.

846 def setup(self):
847 pass
848
849

◆ toQImage()

channels2layers.channels2layers.ChannelsToLayers.toQImage ( self,
layerNode,
rect = None )
Return `layerNode` content as a QImage (as ARGB32)

The `rect` value can be:
- None, in this case will return all `layerNode` content
- A QRect() object, in this case return `layerNode` content reduced to given rectangle bounds

Definition at line 922 of file channels2layers.py.

922 def toQImage(self, layerNode, rect=None):
923 """Return `layerNode` content as a QImage (as ARGB32)
924
925 The `rect` value can be:
926 - None, in this case will return all `layerNode` content
927 - A QRect() object, in this case return `layerNode` content reduced to given rectangle bounds
928 """
929 srcRect = layerNode.bounds()
930
931 if len(layerNode.childNodes()) == 0:
932 projectionMode = False
933 else:
934 projectionMode = True
935
936 if projectionMode == True:
937 img = QImage(layerNode.projectionPixelData(srcRect.left(), srcRect.top(), srcRect.width(), srcRect.height()), srcRect.width(), srcRect.height(), QImage.Format.Format_ARGB32)
938 else:
939 img = QImage(layerNode.pixelData(srcRect.left(), srcRect.top(), srcRect.width(), srcRect.height()), srcRect.width(), srcRect.height(), QImage.Format.Format_ARGB32)
940
941 return img.scaled(rect.width(), rect.height(), Qt.AspectRatioMode.IgnoreAspectRatio, Qt.TransformationMode.SmoothTransformation)
942
943

◆ translateDictKey()

channels2layers.channels2layers.ChannelsToLayers.translateDictKey ( self,
key,
value )
Translate key from dictionary (mostly internal Krita internal values) to human readable values

Definition at line 877 of file channels2layers.py.

877 def translateDictKey(self, key, value):
878 """Translate key from dictionary (mostly internal Krita internal values) to human readable values"""
879 returned = i18n('Unknown')
880
881 if key in TRANSLATIONS_DICT.keys():
882 if value in TRANSLATIONS_DICT[key].keys():
883 returned = i18n(TRANSLATIONS_DICT[key][value])
884
885 return returned
886
887

Member Data Documentation

◆ __outputOptions

channels2layers.channels2layers.ChannelsToLayers.__outputOptions
private

Definition at line 830 of file channels2layers.py.

◆ __sourceDocument

channels2layers.channels2layers.ChannelsToLayers.__sourceDocument
private

Definition at line 837 of file channels2layers.py.

◆ __sourceLayer

channels2layers.channels2layers.ChannelsToLayers.__sourceLayer
private

Definition at line 838 of file channels2layers.py.

◆ action_triggered

channels2layers.channels2layers.ChannelsToLayers.action_triggered

Definition at line 852 of file channels2layers.py.

◆ layerNum

channels2layers.channels2layers.ChannelsToLayers.layerNum

Definition at line 1235 of file channels2layers.py.

◆ parent

channels2layers.channels2layers.ChannelsToLayers.parent

Definition at line 843 of file channels2layers.py.


The documentation for this class was generated from the following file: