Best Python code snippet using pandera_python
ekrita.py
Source:ekrita.py  
1#-----------------------------------------------------------------------------2# PyKritaToolKit3# Copyright (C) 2019-2021 - Grum9994#5# A toolkit to make pykrita plugin coding easier :-)6# -----------------------------------------------------------------------------7# This program is free software: you can redistribute it and/or modify8# it under the terms of the GNU General Public License as published by9# the Free Software Foundation, either version 3 of the License, or10# (at your option) any later version.11#12# This program is distributed in the hope that it will be useful,13# but WITHOUT ANY WARRANTY; without even the implied warranty of14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.15# See the GNU General Public License for more details.16#17# You should have received a copy of the GNU General Public License18# along with this program.19# If not, see https://www.gnu.org/licenses/20# -----------------------------------------------------------------------------21# -----------------------------------------------------------------------------22from enum import Enum23import re24from ..pktk import *25from krita import (26        Document,27        Node,28        Resource29    )30from PyQt5.QtCore import (31        QByteArray,32        QEventLoop,33        QMimeData,34        QPoint,35        QRect,36        QTimer,37        QUuid,38    )39from PyQt5.QtGui import (40        QGuiApplication,41        QKeySequence,42        QImage,43        QPixmap,44        qRgb45    )46from PyQt5.QtWidgets import (47        QWidget,48        QToolButton,49        QListView50    )51from PyQt5.Qt import (QObject, QMdiArea, QAbstractScrollArea)52# -----------------------------------------------------------------------------53class EKritaWindow:54    @staticmethod55    def scrollbars(window=None):56        """Return scrollbar instances of window57        If `window` is None, use active window58        Return a tuple (horizontalScrollBar, verticalScrollBar)59        If there's no active window, return None60        """61        window=Krita.instance().activeWindow()62        if window is None:63            return None64        qtWindow = Krita.instance().activeWindow().qwindow()65        mdiArea = qtWindow.centralWidget().findChild(QMdiArea)66        subWindow = mdiArea.activeSubWindow()67        scrollArea = subWindow.findChild(QAbstractScrollArea)68        return (scrollArea.horizontalScrollBar(), scrollArea.verticalScrollBar())69class EKritaBrushPreset:70    """Allows 'secured' access to brushes preset71    The main cases:72    - Default brush preset used is not availables73    - Brush preset saved (in a plugin) is not available anymore74    In both case, we need to be able to manage properly acces to resources75    The EKritaBrushPreset class provides static methods to acces to brushes in 'secure' way76    There's a third case we won't manage (not a normal case, hope this will be fixed)77        https://krita-artists.org/t/second-beta-for-krita-5-0-help-in-testing-krita/30262/19?u=grum99978    """79    # define some brushes preset we can consider to be used as default80    __DEFAUL_BRUSH_NAMES=['b) Basic-5 Size',81                          'b) Basic-1',82                          'c) Pencil-2',83                          'd) Ink-2 Fineliner',84                          'd) Ink-3 Gpen'85                        ]86    __brushes=None87    __presetChooserWidget=None88    @staticmethod89    def initialise():90        """Initialise brushes names"""91        EKritaBrushPreset.__brushes=Krita.instance().resources("preset")92    @staticmethod93    def getName(name=None):94        """Return preset name from name95        Given `name` can be a <str> or a <Resource> (preset)96        If brush preset is found, return brush preset name97        Otherwise if can't be found in presets, return the default brush name98        """99        if EKritaBrushPreset.__brushes is None:100            EKritaBrushPreset.initialise()101        if isinstance(name, Resource):102            name=name.name()103        if name in EKritaBrushPreset.__brushes:104            # asked brush found, return it105            return name106        else:107            # asked brush not found, search for a default brush108            for brushName in EKritaBrushPreset.__DEFAUL_BRUSH_NAMES:109                if brushName in EKritaBrushPreset.__brushes:110                    # default brush found, return it111                    return brushName112            # default brush not found :-/113            # return current brush from view114            if Krita.instance().activeWindow() and Krita.instance().activeWindow().activeView():115                brushName=Krita.instance().activeWindow().activeView().currentBrushPreset().name()116            else:117                brushName=None118            if brushName in EKritaBrushPreset.__brushes:119                # asked brush found, return it120                return brushName121            # weird..122            # but can happen!123            # https://krita-artists.org/t/second-beta-for-krita-5-0-help-in-testing-krita/30262/19?u=grum999124            if len(EKritaBrushPreset.__brushes)>0:125                # return the first one...126                return EKritaBrushPreset.__brushes[list(EKritaBrushPreset.__brushes.keys())[0]].name()127            # this case should never occurs I hope!!128            raise EInvalidStatus('Something weird happened!\n- Given brush name "'+name+'" was not found\n- Current brush "'+brushName+'" returned bu Krita doesn\'t exist\n- Brush preset list returned by Krita is empty\n\nCan\'t do anything...')129    @staticmethod130    def getPreset(name=None):131        """Return preset for given name132        Given `name` can be a <str> or a <Resource> (preset)133        If brush preset is found, return brush preset134        Otherwise if can't be found in presets, return the default brush preset135        """136        if EKritaBrushPreset.__brushes is None:137            EKritaBrushPreset.initialise()138        return EKritaBrushPreset.__brushes[EKritaBrushPreset.getName(name)]139    @staticmethod140    def found(name):141        """Return if brush preset (from name) exists and can be used"""142        return EKritaBrushPreset.getName(name)==name143    @staticmethod144    def presetChooserWidget():145        """Return preset chooser on which 'currentResourceChanged' signal can be146        connected147        EKritaBrushPreset.presetChooserWidget().currentResourceChanged.connect(myFunction)148        Solution provided by @KnowZero on KA149             https://krita-artists.org/t/it-is-sane-for-a-plugin-to-capture-krita-internal-signal/32475/6150        """151        if EKritaBrushPreset.__presetChooserWidget is None:152            window=Krita.instance().activeWindow().qwindow()153            widget=window.findChild(QWidget, 'ResourceChooser')154            EKritaBrushPreset.__presetChooserWidget=widget.findChild(QListView,'ResourceItemview')155        return EKritaBrushPreset.__presetChooserWidget156class EKritaShortcuts:157    """Manage shortcuts"""158    @staticmethod159    def checkIfExists(keySequence):160        """Check if given `keySequence` is already used by a Krita action161        Return a list of action using the sequence162        """163        returned=[]164        actions=Krita.instance().actions()165        for action in actions:166            shortcuts=action.shortcuts()167            for shortcut in shortcuts:168                if keySequence.matches(shortcut)==QKeySequence.ExactMatch:169                    returned.append(action)170                    break171        return returned172class EKritaPaintToolsId:173    """Paint tools Id"""174    TOOL_BRUSH=          'KritaShape/KisToolBrush'175    TOOL_LINE=           'KritaShape/KisToolLine'176    TOOL_RECTANGLE=      'KritaShape/KisToolRectangle'177    TOOL_ELLIPSE=        'KritaShape/KisToolEllipse'178    TOOL_POLYGON=        'KisToolPolygon'179    TOOL_POLYLINE=       'KisToolPolyline'180    TOOL_PATH=           'KritaShape/KisToolPath'181    TOOL_PENCIL=         'KisToolPencil'182    TOOL_DYNAMIC_BRUSH=  'KritaShape/KisToolDyna'183    TOOL_MULTI_BRUSH=    'KritaShape/KisToolMultiBrush'184class EKritaPaintTools:185    """Quick access to paint tools"""186    __TOOLS={187            EKritaPaintToolsId.TOOL_BRUSH:           i18n("Freehand Brush Tool"),188            EKritaPaintToolsId.TOOL_LINE:            i18n("Line Tool"),189            EKritaPaintToolsId.TOOL_RECTANGLE:       i18n("Rectangle Tool"),190            EKritaPaintToolsId.TOOL_ELLIPSE:         i18n("Ellipse Tool"),191            EKritaPaintToolsId.TOOL_POLYGON:         i18n("Polygon Tool: Shift-mouseclick ends the polygon."),192            EKritaPaintToolsId.TOOL_POLYLINE:        i18n("Polyline Tool: Shift-mouseclick ends the polyline."),193            EKritaPaintToolsId.TOOL_PATH:            i18n("Bezier Curve Tool: Shift-mouseclick ends the curve."),194            EKritaPaintToolsId.TOOL_PENCIL:          i18n("Freehand Path Tool"),195            EKritaPaintToolsId.TOOL_DYNAMIC_BRUSH:   i18n("Dynamic Brush Tool"),196            EKritaPaintToolsId.TOOL_MULTI_BRUSH:     i18n("Multibrush Tool")197        }198    @staticmethod199    def idList():200        """Return list of tools identifiers"""201        return list(EKritaPaintTools.__TOOLS)202    @staticmethod203    def name(id):204        """Return (translated) name for paint tools205        None value return 'None' string206        Otherwise Raise an error is tools is not found207        """208        if id is None:209            return i18n('None')210        elif id in EKritaPaintTools.__TOOLS:211            return re.sub('\s*:.*', '', EKritaPaintTools.__TOOLS[id])212        else:213            raise EInvalidValue("Given `id` is not valid")214    @staticmethod215    def current():216        """return id of current paint tool, if any active217        Otherwise return None218        """219        window=Krita.instance().activeWindow()220        if window:221            for id in EKritaPaintTools.__TOOLS:222                toolButton=window.qwindow().findChild(QToolButton, id)223                if toolButton and toolButton.isChecked():224                    return id225        return None226class EKritaBlendingModesId:227    """Blending modes Id"""228    # list from:229    #   https://invent.kde.org/graphics/krita/-/blob/master/libs/pigment/KoCompositeOpRegistry.h230    COMPOSITE_OVER=                             "normal"231    COMPOSITE_ERASE=                            "erase"232    COMPOSITE_IN=                               "in"233    COMPOSITE_OUT=                              "out"234    COMPOSITE_ALPHA_DARKEN=                     "alphadarken"235    COMPOSITE_DESTINATION_IN=                   "destination-in"236    COMPOSITE_DESTINATION_ATOP=                 "destination-atop"237    COMPOSITE_XOR=                              "xor"238    COMPOSITE_OR=                               "or"239    COMPOSITE_AND=                              "and"240    COMPOSITE_NAND=                             "nand"241    COMPOSITE_NOR=                              "nor"242    COMPOSITE_XNOR=                             "xnor"243    COMPOSITE_IMPLICATION=                      "implication"244    COMPOSITE_NOT_IMPLICATION=                  "not_implication"245    COMPOSITE_CONVERSE=                         "converse"246    COMPOSITE_NOT_CONVERSE=                     "not_converse"247    COMPOSITE_PLUS=                             "plus"248    COMPOSITE_MINUS=                            "minus"249    COMPOSITE_ADD=                              "add"250    COMPOSITE_SUBTRACT=                         "subtract"251    COMPOSITE_INVERSE_SUBTRACT=                 "inverse_subtract"252    COMPOSITE_DIFF=                             "diff"253    COMPOSITE_MULT=                             "multiply"254    COMPOSITE_DIVIDE=                           "divide"255    COMPOSITE_ARC_TANGENT=                      "arc_tangent"256    COMPOSITE_GEOMETRIC_MEAN=                   "geometric_mean"257    COMPOSITE_ADDITIVE_SUBTRACTIVE=             "additive_subtractive"258    COMPOSITE_NEGATION=                         "negation"259    COMPOSITE_MOD=                              "modulo"260    COMPOSITE_MOD_CON=                          "modulo_continuous"261    COMPOSITE_DIVISIVE_MOD=                     "divisive_modulo"262    COMPOSITE_DIVISIVE_MOD_CON=                 "divisive_modulo_continuous"263    COMPOSITE_MODULO_SHIFT=                     "modulo_shift"264    COMPOSITE_MODULO_SHIFT_CON=                 "modulo_shift_continuous"265    COMPOSITE_EQUIVALENCE=                      "equivalence"266    COMPOSITE_ALLANON=                          "allanon"267    COMPOSITE_PARALLEL=                         "parallel"268    COMPOSITE_GRAIN_MERGE=                      "grain_merge"269    COMPOSITE_GRAIN_EXTRACT=                    "grain_extract"270    COMPOSITE_EXCLUSION=                        "exclusion"271    COMPOSITE_HARD_MIX=                         "hard mix"272    COMPOSITE_HARD_MIX_PHOTOSHOP=               "hard_mix_photoshop"273    COMPOSITE_HARD_MIX_SOFTER_PHOTOSHOP=        "hard_mix_softer_photoshop"274    COMPOSITE_OVERLAY=                          "overlay"275    COMPOSITE_BEHIND=                           "behind"276    COMPOSITE_GREATER=                          "greater"277    COMPOSITE_HARD_OVERLAY=                     "hard overlay"278    COMPOSITE_INTERPOLATION=                    "interpolation"279    COMPOSITE_INTERPOLATIONB=                   "interpolation 2x"280    COMPOSITE_PENUMBRAA=                        "penumbra a"281    COMPOSITE_PENUMBRAB=                        "penumbra b"282    COMPOSITE_PENUMBRAC=                        "penumbra c"283    COMPOSITE_PENUMBRAD=                        "penumbra d"284    COMPOSITE_DARKEN=                           "darken"285    COMPOSITE_BURN=                             "burn"          #color burn286    COMPOSITE_LINEAR_BURN=                      "linear_burn"287    COMPOSITE_GAMMA_DARK=                       "gamma_dark"288    COMPOSITE_SHADE_IFS_ILLUSIONS=              "shade_ifs_illusions"289    COMPOSITE_FOG_DARKEN_IFS_ILLUSIONS=         "fog_darken_ifs_illusions"290    COMPOSITE_EASY_BURN=                        "easy burn"291    COMPOSITE_LIGHTEN=                          "lighten"292    COMPOSITE_DODGE=                            "dodge"293    COMPOSITE_LINEAR_DODGE=                     "linear_dodge"294    COMPOSITE_SCREEN=                           "screen"295    COMPOSITE_HARD_LIGHT=                       "hard_light"296    COMPOSITE_SOFT_LIGHT_IFS_ILLUSIONS=         "soft_light_ifs_illusions"297    COMPOSITE_SOFT_LIGHT_PEGTOP_DELPHI=         "soft_light_pegtop_delphi"298    COMPOSITE_SOFT_LIGHT_PHOTOSHOP=             "soft_light"299    COMPOSITE_SOFT_LIGHT_SVG=                   "soft_light_svg"300    COMPOSITE_GAMMA_LIGHT=                      "gamma_light"301    COMPOSITE_GAMMA_ILLUMINATION=               "gamma_illumination"302    COMPOSITE_VIVID_LIGHT=                      "vivid_light"303    COMPOSITE_FLAT_LIGHT=                       "flat_light"304    COMPOSITE_LINEAR_LIGHT=                     "linear light"305    COMPOSITE_PIN_LIGHT=                        "pin_light"306    COMPOSITE_PNORM_A=                          "pnorm_a"307    COMPOSITE_PNORM_B=                          "pnorm_b"308    COMPOSITE_SUPER_LIGHT=                      "super_light"309    COMPOSITE_TINT_IFS_ILLUSIONS=               "tint_ifs_illusions"310    COMPOSITE_FOG_LIGHTEN_IFS_ILLUSIONS=        "fog_lighten_ifs_illusions"311    COMPOSITE_EASY_DODGE=                       "easy dodge"312    COMPOSITE_LUMINOSITY_SAI=                   "luminosity_sai"313    COMPOSITE_HUE=                              "hue"314    COMPOSITE_COLOR=                            "color"315    COMPOSITE_SATURATION=                       "saturation"316    COMPOSITE_INC_SATURATION=                   "inc_saturation"317    COMPOSITE_DEC_SATURATION=                   "dec_saturation"318    COMPOSITE_LUMINIZE=                         "luminize"319    COMPOSITE_INC_LUMINOSITY=                   "inc_luminosity"320    COMPOSITE_DEC_LUMINOSITY=                   "dec_luminosity"321    COMPOSITE_HUE_HSV=                          "hue_hsv"322    COMPOSITE_COLOR_HSV=                        "color_hsv"323    COMPOSITE_SATURATION_HSV=                   "saturation_hsv"324    COMPOSITE_INC_SATURATION_HSV=               "inc_saturation_hsv"325    COMPOSITE_DEC_SATURATION_HSV=               "dec_saturation_hsv"326    COMPOSITE_VALUE=                            "value"327    COMPOSITE_INC_VALUE=                        "inc_value"328    COMPOSITE_DEC_VALUE=                        "dec_value"329    COMPOSITE_HUE_HSL=                          "hue_hsl"330    COMPOSITE_COLOR_HSL=                        "color_hsl"331    COMPOSITE_SATURATION_HSL=                   "saturation_hsl"332    COMPOSITE_INC_SATURATION_HSL=               "inc_saturation_hsl"333    COMPOSITE_DEC_SATURATION_HSL=               "dec_saturation_hsl"334    COMPOSITE_LIGHTNESS=                        "lightness"335    COMPOSITE_INC_LIGHTNESS=                    "inc_lightness"336    COMPOSITE_DEC_LIGHTNESS=                    "dec_lightness"337    COMPOSITE_HUE_HSI=                          "hue_hsi"338    COMPOSITE_COLOR_HSI=                        "color_hsi"339    COMPOSITE_SATURATION_HSI=                   "saturation_hsi"340    COMPOSITE_INC_SATURATION_HSI=               "inc_saturation_hsi"341    COMPOSITE_DEC_SATURATION_HSI=               "dec_saturation_hsi"342    COMPOSITE_INTENSITY=                        "intensity"343    COMPOSITE_INC_INTENSITY=                    "inc_intensity"344    COMPOSITE_DEC_INTENSITY=                    "dec_intensity"345    COMPOSITE_COPY=                             "copy"346    COMPOSITE_COPY_RED=                         "copy_red"347    COMPOSITE_COPY_GREEN=                       "copy_green"348    COMPOSITE_COPY_BLUE=                        "copy_blue"349    COMPOSITE_TANGENT_NORMALMAP=                "tangent_normalmap"350    COMPOSITE_COLORIZE=                         "colorize"351    COMPOSITE_BUMPMAP=                          "bumpmap"352    COMPOSITE_COMBINE_NORMAL=                   "combine_normal"353    COMPOSITE_CLEAR=                            "clear"354    COMPOSITE_DISSOLVE=                         "dissolve"355    COMPOSITE_DISPLACE=                         "displace"356    COMPOSITE_NO=                               "nocomposition"357    COMPOSITE_PASS_THROUGH=                     "pass through" # XXX: not implemented anywhere yet?358    COMPOSITE_DARKER_COLOR=                     "darker color"359    COMPOSITE_LIGHTER_COLOR=                    "lighter color"360    #COMPOSITE_UNDEF=                            "undefined"361    COMPOSITE_REFLECT=                          "reflect"362    COMPOSITE_GLOW=                             "glow"363    COMPOSITE_FREEZE=                           "freeze"364    COMPOSITE_HEAT=                             "heat"365    COMPOSITE_GLEAT=                            "glow_heat"366    COMPOSITE_HELOW=                            "heat_glow"367    COMPOSITE_REEZE=                            "reflect_freeze"368    COMPOSITE_FRECT=                            "freeze_reflect"369    COMPOSITE_FHYRD=                            "heat_glow_freeze_reflect_hybrid"370    CATEGORY_ARITHMETIC=                        "arithmetic"371    CATEGORY_BINARY=                            "binary"372    CATEGORY_DARK=                              "dark"373    CATEGORY_LIGHT=                             "light"374    CATEGORY_MODULO=                            "modulo"375    CATEGORY_NEGATIVE=                          "negative"376    CATEGORY_MIX=                               "mix"377    CATEGORY_MISC=                              "misc"378    CATEGORY_HSY=                               "hsy"379    CATEGORY_HSI=                               "hsi"380    CATEGORY_HSL=                               "hsl"381    CATEGORY_HSV=                               "hsv"382    CATEGORY_QUADRATIC=                         "quadratic"383class EKritaBlendingModes:384    """Blending modes"""385    # tables & translations from386    #   https://invent.kde.org/graphics/krita/-/blob/master/libs/pigment/KoCompositeOpRegistry.cpp387    __CATEGORIES={388            EKritaBlendingModesId.CATEGORY_ARITHMETIC:                          i18nc("Blending mode - category Arithmetic", "Arithmetic"),389            EKritaBlendingModesId.CATEGORY_BINARY:                              i18nc("Blending mode - category Binary", "Binary"),390            EKritaBlendingModesId.CATEGORY_DARK:                                i18nc("Blending mode - category Darken", "Darken"),391            EKritaBlendingModesId.CATEGORY_LIGHT:                               i18nc("Blending mode - category Lighten", "Lighten"),392            EKritaBlendingModesId.CATEGORY_MODULO:                              i18nc("Blending mode - category Modulo", "Modulo"),393            EKritaBlendingModesId.CATEGORY_NEGATIVE:                            i18nc("Blending mode - category Negative", "Negative"),394            EKritaBlendingModesId.CATEGORY_MIX:                                 i18nc("Blending mode - category Mix", "Mix"),395            EKritaBlendingModesId.CATEGORY_MISC:                                i18nc("Blending mode - category Misc", "Misc"),396            EKritaBlendingModesId.CATEGORY_HSY:                                 i18nc("Blending mode - category HSY", "HSY"),397            EKritaBlendingModesId.CATEGORY_HSI:                                 i18nc("Blending mode - category HSI", "HSI"),398            EKritaBlendingModesId.CATEGORY_HSL:                                 i18nc("Blending mode - category HSL", "HSL"),399            EKritaBlendingModesId.CATEGORY_HSV:                                 i18nc("Blending mode - category HSV", "HSV"),400            EKritaBlendingModesId.CATEGORY_QUADRATIC:                           i18nc("Blending mode - category Quadratic", "Quadratic")401        }402    __CATEGORIES_BLENDING_MODES={403            EKritaBlendingModesId.CATEGORY_ARITHMETIC: [404                    EKritaBlendingModesId.COMPOSITE_ADD,405                    EKritaBlendingModesId.COMPOSITE_SUBTRACT,406                    EKritaBlendingModesId.COMPOSITE_MULT,407                    EKritaBlendingModesId.COMPOSITE_DIVIDE,408                    EKritaBlendingModesId.COMPOSITE_INVERSE_SUBTRACT409                ],410            EKritaBlendingModesId.CATEGORY_BINARY: [411                    EKritaBlendingModesId.COMPOSITE_XOR,412                    EKritaBlendingModesId.COMPOSITE_OR,413                    EKritaBlendingModesId.COMPOSITE_AND,414                    EKritaBlendingModesId.COMPOSITE_NAND,415                    EKritaBlendingModesId.COMPOSITE_NOR,416                    EKritaBlendingModesId.COMPOSITE_XNOR,417                    EKritaBlendingModesId.COMPOSITE_IMPLICATION,418                    EKritaBlendingModesId.COMPOSITE_NOT_IMPLICATION,419                    EKritaBlendingModesId.COMPOSITE_CONVERSE,420                    EKritaBlendingModesId.COMPOSITE_NOT_CONVERSE421                ],422            EKritaBlendingModesId.CATEGORY_DARK: [423                    EKritaBlendingModesId.COMPOSITE_BURN,424                    EKritaBlendingModesId.COMPOSITE_LINEAR_BURN,425                    EKritaBlendingModesId.COMPOSITE_DARKEN,426                    EKritaBlendingModesId.COMPOSITE_GAMMA_DARK,427                    EKritaBlendingModesId.COMPOSITE_DARKER_COLOR,428                    EKritaBlendingModesId.COMPOSITE_SHADE_IFS_ILLUSIONS,429                    EKritaBlendingModesId.COMPOSITE_FOG_DARKEN_IFS_ILLUSIONS,430                    EKritaBlendingModesId.COMPOSITE_EASY_BURN431                ],432            EKritaBlendingModesId.CATEGORY_LIGHT: [433                    EKritaBlendingModesId.COMPOSITE_DODGE,434                    EKritaBlendingModesId.COMPOSITE_LINEAR_DODGE,435                    EKritaBlendingModesId.COMPOSITE_LIGHTEN,436                    EKritaBlendingModesId.COMPOSITE_LINEAR_LIGHT,437                    EKritaBlendingModesId.COMPOSITE_SCREEN,438                    EKritaBlendingModesId.COMPOSITE_PIN_LIGHT,439                    EKritaBlendingModesId.COMPOSITE_VIVID_LIGHT,440                    EKritaBlendingModesId.COMPOSITE_FLAT_LIGHT,441                    EKritaBlendingModesId.COMPOSITE_HARD_LIGHT,442                    EKritaBlendingModesId.COMPOSITE_SOFT_LIGHT_IFS_ILLUSIONS,443                    EKritaBlendingModesId.COMPOSITE_SOFT_LIGHT_PEGTOP_DELPHI,444                    EKritaBlendingModesId.COMPOSITE_SOFT_LIGHT_PHOTOSHOP,445                    EKritaBlendingModesId.COMPOSITE_SOFT_LIGHT_SVG,446                    EKritaBlendingModesId.COMPOSITE_GAMMA_LIGHT,447                    EKritaBlendingModesId.COMPOSITE_GAMMA_ILLUMINATION,448                    EKritaBlendingModesId.COMPOSITE_LIGHTER_COLOR,449                    EKritaBlendingModesId.COMPOSITE_PNORM_A,450                    EKritaBlendingModesId.COMPOSITE_PNORM_B,451                    EKritaBlendingModesId.COMPOSITE_SUPER_LIGHT,452                    EKritaBlendingModesId.COMPOSITE_TINT_IFS_ILLUSIONS,453                    EKritaBlendingModesId.COMPOSITE_FOG_LIGHTEN_IFS_ILLUSIONS,454                    EKritaBlendingModesId.COMPOSITE_EASY_DODGE,455                    EKritaBlendingModesId.COMPOSITE_LUMINOSITY_SAI456                ],457            EKritaBlendingModesId.CATEGORY_MODULO: [458                    EKritaBlendingModesId.COMPOSITE_MOD,459                    EKritaBlendingModesId.COMPOSITE_MOD_CON,460                    EKritaBlendingModesId.COMPOSITE_DIVISIVE_MOD,461                    EKritaBlendingModesId.COMPOSITE_DIVISIVE_MOD_CON,462                    EKritaBlendingModesId.COMPOSITE_MODULO_SHIFT,463                    EKritaBlendingModesId.COMPOSITE_MODULO_SHIFT_CON464                ],465            EKritaBlendingModesId.CATEGORY_NEGATIVE: [466                    EKritaBlendingModesId.COMPOSITE_DIFF,467                    EKritaBlendingModesId.COMPOSITE_EQUIVALENCE,468                    EKritaBlendingModesId.COMPOSITE_ADDITIVE_SUBTRACTIVE,469                    EKritaBlendingModesId.COMPOSITE_EXCLUSION,470                    EKritaBlendingModesId.COMPOSITE_ARC_TANGENT,471                    EKritaBlendingModesId.COMPOSITE_NEGATION472                ],473            EKritaBlendingModesId.CATEGORY_MIX: [474                    EKritaBlendingModesId.COMPOSITE_OVER,475                    EKritaBlendingModesId.COMPOSITE_BEHIND,476                    EKritaBlendingModesId.COMPOSITE_GREATER,477                    EKritaBlendingModesId.COMPOSITE_OVERLAY,478                    EKritaBlendingModesId.COMPOSITE_ERASE,479                    EKritaBlendingModesId.COMPOSITE_ALPHA_DARKEN,480                    EKritaBlendingModesId.COMPOSITE_HARD_MIX,481                    EKritaBlendingModesId.COMPOSITE_HARD_MIX_PHOTOSHOP,482                    EKritaBlendingModesId.COMPOSITE_HARD_MIX_SOFTER_PHOTOSHOP,483                    EKritaBlendingModesId.COMPOSITE_GRAIN_MERGE,484                    EKritaBlendingModesId.COMPOSITE_GRAIN_EXTRACT,485                    EKritaBlendingModesId.COMPOSITE_PARALLEL,486                    EKritaBlendingModesId.COMPOSITE_ALLANON,487                    EKritaBlendingModesId.COMPOSITE_GEOMETRIC_MEAN,488                    EKritaBlendingModesId.COMPOSITE_DESTINATION_ATOP,489                    EKritaBlendingModesId.COMPOSITE_DESTINATION_IN,490                    EKritaBlendingModesId.COMPOSITE_HARD_OVERLAY,491                    EKritaBlendingModesId.COMPOSITE_INTERPOLATION,492                    EKritaBlendingModesId.COMPOSITE_INTERPOLATIONB,493                    EKritaBlendingModesId.COMPOSITE_PENUMBRAA,494                    EKritaBlendingModesId.COMPOSITE_PENUMBRAB,495                    EKritaBlendingModesId.COMPOSITE_PENUMBRAC,496                    EKritaBlendingModesId.COMPOSITE_PENUMBRAD497                ],498            EKritaBlendingModesId.CATEGORY_MISC: [499                    EKritaBlendingModesId.COMPOSITE_BUMPMAP,500                    EKritaBlendingModesId.COMPOSITE_COMBINE_NORMAL,501                    EKritaBlendingModesId.COMPOSITE_DISSOLVE,502                    EKritaBlendingModesId.COMPOSITE_COPY_RED,503                    EKritaBlendingModesId.COMPOSITE_COPY_GREEN,504                    EKritaBlendingModesId.COMPOSITE_COPY_BLUE,505                    EKritaBlendingModesId.COMPOSITE_COPY,506                    EKritaBlendingModesId.COMPOSITE_TANGENT_NORMALMAP507                ],508            EKritaBlendingModesId.CATEGORY_HSY: [509                    EKritaBlendingModesId.COMPOSITE_COLOR,510                    EKritaBlendingModesId.COMPOSITE_HUE,511                    EKritaBlendingModesId.COMPOSITE_SATURATION,512                    EKritaBlendingModesId.COMPOSITE_LUMINIZE,513                    EKritaBlendingModesId.COMPOSITE_DEC_SATURATION,514                    EKritaBlendingModesId.COMPOSITE_INC_SATURATION,515                    EKritaBlendingModesId.COMPOSITE_DEC_LUMINOSITY,516                    EKritaBlendingModesId.COMPOSITE_INC_LUMINOSITY517                ],518            EKritaBlendingModesId.CATEGORY_HSI: [519                    EKritaBlendingModesId.COMPOSITE_COLOR_HSI,520                    EKritaBlendingModesId.COMPOSITE_HUE_HSI,521                    EKritaBlendingModesId.COMPOSITE_SATURATION_HSI,522                    EKritaBlendingModesId.COMPOSITE_INTENSITY,523                    EKritaBlendingModesId.COMPOSITE_DEC_SATURATION_HSI,524                    EKritaBlendingModesId.COMPOSITE_INC_SATURATION_HSI,525                    EKritaBlendingModesId.COMPOSITE_DEC_INTENSITY,526                    EKritaBlendingModesId.COMPOSITE_INC_INTENSITY527                ],528            EKritaBlendingModesId.CATEGORY_HSL: [529                    EKritaBlendingModesId.COMPOSITE_COLOR_HSL,530                    EKritaBlendingModesId.COMPOSITE_HUE_HSL,531                    EKritaBlendingModesId.COMPOSITE_SATURATION_HSL,532                    EKritaBlendingModesId.COMPOSITE_LIGHTNESS,533                    EKritaBlendingModesId.COMPOSITE_DEC_SATURATION_HSL,534                    EKritaBlendingModesId.COMPOSITE_INC_SATURATION_HSL,535                    EKritaBlendingModesId.COMPOSITE_DEC_LIGHTNESS,536                    EKritaBlendingModesId.COMPOSITE_INC_LIGHTNESS537                ],538            EKritaBlendingModesId.CATEGORY_HSV: [539                    EKritaBlendingModesId.COMPOSITE_COLOR_HSV,540                    EKritaBlendingModesId.COMPOSITE_HUE_HSV,541                    EKritaBlendingModesId.COMPOSITE_SATURATION_HSV,542                    EKritaBlendingModesId.COMPOSITE_VALUE,543                    EKritaBlendingModesId.COMPOSITE_DEC_SATURATION_HSV,544                    EKritaBlendingModesId.COMPOSITE_INC_SATURATION_HSV,545                    EKritaBlendingModesId.COMPOSITE_DEC_VALUE,546                    EKritaBlendingModesId.COMPOSITE_INC_VALUE547                ],548            EKritaBlendingModesId.CATEGORY_QUADRATIC: [549                    EKritaBlendingModesId.COMPOSITE_REFLECT,550                    EKritaBlendingModesId.COMPOSITE_GLOW,551                    EKritaBlendingModesId.COMPOSITE_FREEZE,552                    EKritaBlendingModesId.COMPOSITE_HEAT,553                    EKritaBlendingModesId.COMPOSITE_GLEAT,554                    EKritaBlendingModesId.COMPOSITE_HELOW,555                    EKritaBlendingModesId.COMPOSITE_REEZE,556                    EKritaBlendingModesId.COMPOSITE_FRECT,557                    EKritaBlendingModesId.COMPOSITE_FHYRD558                ]559        }560    __BLENDING_MODES={561            EKritaBlendingModesId.COMPOSITE_ADD:                        i18nc("Blending mode - Addition", "Addition"),562            EKritaBlendingModesId.COMPOSITE_SUBTRACT:                   i18nc("Blending mode - Subtract", "Subtract"),563            EKritaBlendingModesId.COMPOSITE_MULT:                       i18nc("Blending mode - Multiply", "Multiply"),564            EKritaBlendingModesId.COMPOSITE_DIVIDE:                     i18nc("Blending mode - Divide", "Divide"),565            EKritaBlendingModesId.COMPOSITE_INVERSE_SUBTRACT:           i18nc("Blending mode - Inverse Subtract", "Inverse Subtract"),566            EKritaBlendingModesId.COMPOSITE_XOR:                        i18nc("Blending mode - XOR", "XOR"),567            EKritaBlendingModesId.COMPOSITE_OR:                         i18nc("Blending mode - OR", "OR"),568            EKritaBlendingModesId.COMPOSITE_AND:                        i18nc("Blending mode - AND", "AND"),569            EKritaBlendingModesId.COMPOSITE_NAND:                       i18nc("Blending mode - NAND", "NAND"),570            EKritaBlendingModesId.COMPOSITE_NOR:                        i18nc("Blending mode - NOR", "NOR"),571            EKritaBlendingModesId.COMPOSITE_XNOR:                       i18nc("Blending mode - XNOR", "XNOR"),572            EKritaBlendingModesId.COMPOSITE_IMPLICATION:                i18nc("Blending mode - IMPLICATION", "IMPLICATION"),573            EKritaBlendingModesId.COMPOSITE_NOT_IMPLICATION:            i18nc("Blending mode - NOT IMPLICATION", "NOT IMPLICATION"),574            EKritaBlendingModesId.COMPOSITE_CONVERSE:                   i18nc("Blending mode - CONVERSE", "CONVERSE"),575            EKritaBlendingModesId.COMPOSITE_NOT_CONVERSE:               i18nc("Blending mode - NOT CONVERSE", "NOT CONVERSE"),576            EKritaBlendingModesId.COMPOSITE_BURN:                       i18nc("Blending mode - Burn", "Burn"),577            EKritaBlendingModesId.COMPOSITE_LINEAR_BURN:                i18nc("Blending mode - Linear Burn", "Linear Burn"),578            EKritaBlendingModesId.COMPOSITE_DARKEN:                     i18nc("Blending mode - Darken", "Darken"),579            EKritaBlendingModesId.COMPOSITE_GAMMA_DARK:                 i18nc("Blending mode - Gamma Dark", "Gamma Dark"),580            EKritaBlendingModesId.COMPOSITE_DARKER_COLOR:               i18nc("Blending mode - Darker Color", "Darker Color"),581            EKritaBlendingModesId.COMPOSITE_SHADE_IFS_ILLUSIONS:        i18nc("Blending mode - Shade (IFS Illusions)", "Shade (IFS Illusions)"),582            EKritaBlendingModesId.COMPOSITE_FOG_DARKEN_IFS_ILLUSIONS:   i18nc("Blending mode - Fog Darken (IFS Illusions)", "Fog Darken (IFS Illusions)"),583            EKritaBlendingModesId.COMPOSITE_EASY_BURN:                  i18nc("Blending mode - Easy Burn", "Easy Burn"),584            EKritaBlendingModesId.COMPOSITE_DODGE:                      i18nc("Blending mode - Color Dodge", "Color Dodge"),585            EKritaBlendingModesId.COMPOSITE_LINEAR_DODGE:               i18nc("Blending mode - Linear Dodge", "Linear Dodge"),586            EKritaBlendingModesId.COMPOSITE_LIGHTEN:                    i18nc("Blending mode - Lighten", "Lighten"),587            EKritaBlendingModesId.COMPOSITE_LINEAR_LIGHT:               i18nc("Blending mode - Linear Light", "Linear Light"),588            EKritaBlendingModesId.COMPOSITE_SCREEN:                     i18nc("Blending mode - Screen", "Screen"),589            EKritaBlendingModesId.COMPOSITE_PIN_LIGHT:                  i18nc("Blending mode - Pin Light", "Pin Light"),590            EKritaBlendingModesId.COMPOSITE_VIVID_LIGHT:                i18nc("Blending mode - Vivid Light", "Vivid Light"),591            EKritaBlendingModesId.COMPOSITE_FLAT_LIGHT:                 i18nc("Blending mode - Flat Light", "Flat Light"),592            EKritaBlendingModesId.COMPOSITE_HARD_LIGHT:                 i18nc("Blending mode - Hard Light", "Hard Light"),593            EKritaBlendingModesId.COMPOSITE_SOFT_LIGHT_IFS_ILLUSIONS:   i18nc("Blending mode - Soft Light (IFS Illusions)", "Soft Light (IFS Illusions)"),594            EKritaBlendingModesId.COMPOSITE_SOFT_LIGHT_PEGTOP_DELPHI:   i18nc("Blending mode - Soft Light (Pegtop-Delphi)", "Soft Light (Pegtop-Delphi)"),595            EKritaBlendingModesId.COMPOSITE_SOFT_LIGHT_PHOTOSHOP:       i18nc("Blending mode - Soft Light (Photoshop)", "Soft Light (Photoshop)"),596            EKritaBlendingModesId.COMPOSITE_SOFT_LIGHT_SVG:             i18nc("Blending mode - Soft Light (SVG)", "Soft Light (SVG)"),597            EKritaBlendingModesId.COMPOSITE_GAMMA_LIGHT:                i18nc("Blending mode - Gamma Light", "Gamma Light"),598            EKritaBlendingModesId.COMPOSITE_GAMMA_ILLUMINATION:         i18nc("Blending mode - Gamma Illumination", "Gamma Illumination"),599            EKritaBlendingModesId.COMPOSITE_LIGHTER_COLOR:              i18nc("Blending mode - Lighter Color", "Lighter Color"),600            EKritaBlendingModesId.COMPOSITE_PNORM_A:                    i18nc("Blending mode - P-Norm A", "P-Norm A"),601            EKritaBlendingModesId.COMPOSITE_PNORM_B:                    i18nc("Blending mode - P-Norm B", "P-Norm B"),602            EKritaBlendingModesId.COMPOSITE_SUPER_LIGHT:                i18nc("Blending mode - Super Light", "Super Light"),603            EKritaBlendingModesId.COMPOSITE_TINT_IFS_ILLUSIONS:         i18nc("Blending mode - Tint (IFS Illusions)", "Tint (IFS Illusions)"),604            EKritaBlendingModesId.COMPOSITE_FOG_LIGHTEN_IFS_ILLUSIONS:  i18nc("Blending mode - Fog Lighten (IFS Illusions)", "Fog Lighten (IFS Illusions)"),605            EKritaBlendingModesId.COMPOSITE_EASY_DODGE:                 i18nc("Blending mode - Easy Dodge", "Easy Dodge"),606            EKritaBlendingModesId.COMPOSITE_LUMINOSITY_SAI:             i18nc("Blending mode - Luminosity/Shine (SAI)", "Luminosity/Shine (SAI)"),607            EKritaBlendingModesId.COMPOSITE_MOD:                        i18nc("Blending mode - Modulo", "Modulo"),608            EKritaBlendingModesId.COMPOSITE_MOD_CON:                    i18nc("Blending mode - Modulo - Continuous", "Modulo - Continuous"),609            EKritaBlendingModesId.COMPOSITE_DIVISIVE_MOD:               i18nc("Blending mode - Divisive Modulo", "Divisive Modulo"),610            EKritaBlendingModesId.COMPOSITE_DIVISIVE_MOD_CON:           i18nc("Blending mode - Divisive Modulo - Continuous", "Divisive Modulo - Continuous"),611            EKritaBlendingModesId.COMPOSITE_MODULO_SHIFT:               i18nc("Blending mode - Modulo Shift", "Modulo Shift"),612            EKritaBlendingModesId.COMPOSITE_MODULO_SHIFT_CON:           i18nc("Blending mode - Modulo Shift - Continuous", "Modulo Shift - Continuous"),613            EKritaBlendingModesId.COMPOSITE_DIFF:                       i18nc("Blending mode - Difference", "Difference"),614            EKritaBlendingModesId.COMPOSITE_EQUIVALENCE:                i18nc("Blending mode - Equivalence", "Equivalence"),615            EKritaBlendingModesId.COMPOSITE_ADDITIVE_SUBTRACTIVE:       i18nc("Blending mode - Additive Subtractive", "Additive Subtractive"),616            EKritaBlendingModesId.COMPOSITE_EXCLUSION:                  i18nc("Blending mode - Exclusion", "Exclusion"),617            EKritaBlendingModesId.COMPOSITE_ARC_TANGENT:                i18nc("Blending mode - Arcus Tangent", "Arcus Tangent"),618            EKritaBlendingModesId.COMPOSITE_NEGATION:                   i18nc("Blending mode - Negation", "Negation"),619            EKritaBlendingModesId.COMPOSITE_OVER:                       i18nc("Blending mode - Normal", "Normal"),620            EKritaBlendingModesId.COMPOSITE_BEHIND:                     i18nc("Blending mode - Behind", "Behind"),621            EKritaBlendingModesId.COMPOSITE_GREATER:                    i18nc("Blending mode - Greater", "Greater"),622            EKritaBlendingModesId.COMPOSITE_OVERLAY:                    i18nc("Blending mode - Overlay", "Overlay"),623            EKritaBlendingModesId.COMPOSITE_ERASE:                      i18nc("Blending mode - Erase", "Erase"),624            EKritaBlendingModesId.COMPOSITE_ALPHA_DARKEN:               i18nc("Blending mode - Alpha Darken", "Alpha Darken"),625            EKritaBlendingModesId.COMPOSITE_HARD_MIX:                   i18nc("Blending mode - Hard Mix", "Hard Mix"),626            EKritaBlendingModesId.COMPOSITE_HARD_MIX_PHOTOSHOP:         i18nc("Blending mode - Hard Mix (Photoshop)", "Hard Mix (Photoshop)"),627            EKritaBlendingModesId.COMPOSITE_HARD_MIX_SOFTER_PHOTOSHOP:  i18nc("Blending mode - Hard Mix Softer (Photoshop)", "Hard Mix Softer (Photoshop)"),628            EKritaBlendingModesId.COMPOSITE_GRAIN_MERGE:                i18nc("Blending mode - Grain Merge", "Grain Merge"),629            EKritaBlendingModesId.COMPOSITE_GRAIN_EXTRACT:              i18nc("Blending mode - Grain Extract", "Grain Extract"),630            EKritaBlendingModesId.COMPOSITE_PARALLEL:                   i18nc("Blending mode - Parallel", "Parallel"),631            EKritaBlendingModesId.COMPOSITE_ALLANON:                    i18nc("Blending mode - Allanon", "Allanon"),632            EKritaBlendingModesId.COMPOSITE_GEOMETRIC_MEAN:             i18nc("Blending mode - Geometric Mean", "Geometric Mean"),633            EKritaBlendingModesId.COMPOSITE_DESTINATION_ATOP:           i18nc("Blending mode - Destination Atop", "Destination Atop"),634            EKritaBlendingModesId.COMPOSITE_DESTINATION_IN:             i18nc("Blending mode - Destination In", "Destination In"),635            EKritaBlendingModesId.COMPOSITE_HARD_OVERLAY:               i18nc("Blending mode - Hard Overlay", "Hard Overlay"),636            EKritaBlendingModesId.COMPOSITE_INTERPOLATION:              i18nc("Blending mode - Interpolation", "Interpolation"),637            EKritaBlendingModesId.COMPOSITE_INTERPOLATIONB:             i18nc("Blending mode - Interpolation - 2X", "Interpolation - 2X"),638            EKritaBlendingModesId.COMPOSITE_PENUMBRAA:                  i18nc("Blending mode - Penumbra A", "Penumbra A"),639            EKritaBlendingModesId.COMPOSITE_PENUMBRAB:                  i18nc("Blending mode - Penumbra B", "Penumbra B"),640            EKritaBlendingModesId.COMPOSITE_PENUMBRAC:                  i18nc("Blending mode - Penumbra C", "Penumbra C"),641            EKritaBlendingModesId.COMPOSITE_PENUMBRAD:                  i18nc("Blending mode - Penumbra D", "Penumbra D"),642            EKritaBlendingModesId.COMPOSITE_BUMPMAP:                    i18nc("Blending mode - Bumpmap", "Bumpmap"),643            EKritaBlendingModesId.COMPOSITE_COMBINE_NORMAL:             i18nc("Blending mode - Combine Normal Map", "Combine Normal Map"),644            EKritaBlendingModesId.COMPOSITE_DISSOLVE:                   i18nc("Blending mode - Dissolve", "Dissolve"),645            EKritaBlendingModesId.COMPOSITE_COPY_RED:                   i18nc("Blending mode - Copy Red", "Copy Red"),646            EKritaBlendingModesId.COMPOSITE_COPY_GREEN:                 i18nc("Blending mode - Copy Green", "Copy Green"),647            EKritaBlendingModesId.COMPOSITE_COPY_BLUE:                  i18nc("Blending mode - Copy Blue", "Copy Blue"),648            EKritaBlendingModesId.COMPOSITE_COPY:                       i18nc("Blending mode - Copy", "Copy"),649            EKritaBlendingModesId.COMPOSITE_TANGENT_NORMALMAP:          i18nc("Blending mode - Tangent Normalmap", "Tangent Normalmap"),650            EKritaBlendingModesId.COMPOSITE_COLOR:                      i18nc("Blending mode - Color HSY", "Color"),651            EKritaBlendingModesId.COMPOSITE_HUE:                        i18nc("Blending mode - Hue HSY", "Hue"),652            EKritaBlendingModesId.COMPOSITE_SATURATION:                 i18nc("Blending mode - Saturation HSY", "Saturation"),653            EKritaBlendingModesId.COMPOSITE_LUMINIZE:                   i18nc("Blending mode - Luminosity HSY", "Luminosity"),654            EKritaBlendingModesId.COMPOSITE_DEC_SATURATION:             i18nc("Blending mode - Decrease Saturation HSY", "Decrease Saturation"),655            EKritaBlendingModesId.COMPOSITE_INC_SATURATION:             i18nc("Blending mode - Increase Saturation HSY", "Increase Saturation"),656            EKritaBlendingModesId.COMPOSITE_DEC_LUMINOSITY:             i18nc("Blending mode - Decrease Luminosity HSY", "Decrease Luminosity"),657            EKritaBlendingModesId.COMPOSITE_INC_LUMINOSITY:             i18nc("Blending mode - Increase Luminosity HSY", "Increase Luminosity"),658            EKritaBlendingModesId.COMPOSITE_COLOR_HSI:                  i18nc("Blending mode - Color HSI", "Color HSI"),659            EKritaBlendingModesId.COMPOSITE_HUE_HSI:                    i18nc("Blending mode - Hue HSI", "Hue HSI"),660            EKritaBlendingModesId.COMPOSITE_SATURATION_HSI:             i18nc("Blending mode - Saturation HSI", "Saturation HSI"),661            EKritaBlendingModesId.COMPOSITE_INTENSITY:                  i18nc("Blending mode - Intensity HSI", "Intensity"),662            EKritaBlendingModesId.COMPOSITE_DEC_SATURATION_HSI:         i18nc("Blending mode - Decrease Saturation HSI", "Decrease Saturation HSI"),663            EKritaBlendingModesId.COMPOSITE_INC_SATURATION_HSI:         i18nc("Blending mode - Increase Saturation HSI", "Increase Saturation HSI"),664            EKritaBlendingModesId.COMPOSITE_DEC_INTENSITY:              i18nc("Blending mode - Decrease Intensity", "Decrease Intensity"),665            EKritaBlendingModesId.COMPOSITE_INC_INTENSITY:              i18nc("Blending mode - Increase Intensity", "Increase Intensity"),666            EKritaBlendingModesId.COMPOSITE_COLOR_HSL:                  i18nc("Blending mode - Color HSL", "Color HSL"),667            EKritaBlendingModesId.COMPOSITE_HUE_HSL:                    i18nc("Blending mode - Hue HSL", "Hue HSL"),668            EKritaBlendingModesId.COMPOSITE_SATURATION_HSL:             i18nc("Blending mode - Saturation HSL", "Saturation HSL"),669            EKritaBlendingModesId.COMPOSITE_LIGHTNESS:                  i18nc("Blending mode - Lightness HSI", "Lightness"),670            EKritaBlendingModesId.COMPOSITE_DEC_SATURATION_HSL:         i18nc("Blending mode - Decrease Saturation HSL", "Decrease Saturation HSL"),671            EKritaBlendingModesId.COMPOSITE_INC_SATURATION_HSL:         i18nc("Blending mode - Increase Saturation HSL", "Increase Saturation HSL"),672            EKritaBlendingModesId.COMPOSITE_DEC_LIGHTNESS:              i18nc("Blending mode - Decrease Lightness", "Decrease Lightness"),673            EKritaBlendingModesId.COMPOSITE_INC_LIGHTNESS:              i18nc("Blending mode - Increase Lightness", "Increase Lightness"),674            EKritaBlendingModesId.COMPOSITE_COLOR_HSV:                  i18nc("Blending mode - Color HSV", "Color HSV"),675            EKritaBlendingModesId.COMPOSITE_HUE_HSV:                    i18nc("Blending mode - Hue HSV", "Hue HSV"),676            EKritaBlendingModesId.COMPOSITE_SATURATION_HSV:             i18nc("Blending mode - Saturation HSV", "Saturation HSV"),677            EKritaBlendingModesId.COMPOSITE_VALUE:                      i18nc("Blending mode - Value HSV", "Value"),678            EKritaBlendingModesId.COMPOSITE_DEC_SATURATION_HSV:         i18nc("Blending mode - Decrease Saturation HSV", "Decrease Saturation HSV"),679            EKritaBlendingModesId.COMPOSITE_INC_SATURATION_HSV:         i18nc("Blending mode - Increase Saturation HSV", "Increase Saturation HSV"),680            EKritaBlendingModesId.COMPOSITE_DEC_VALUE:                  i18nc("Blending mode - Decrease Value HSV", "Decrease Value"),681            EKritaBlendingModesId.COMPOSITE_INC_VALUE:                  i18nc("Blending mode - Increase Value HSV", "Increase Value"),682            EKritaBlendingModesId.COMPOSITE_REFLECT:                    i18nc("Blending mode - Reflect", "Reflect"),683            EKritaBlendingModesId.COMPOSITE_GLOW:                       i18nc("Blending mode - Glow", "Glow"),684            EKritaBlendingModesId.COMPOSITE_FREEZE:                     i18nc("Blending mode - Freeze", "Freeze"),685            EKritaBlendingModesId.COMPOSITE_HEAT:                       i18nc("Blending mode - Heat", "Heat"),686            EKritaBlendingModesId.COMPOSITE_GLEAT:                      i18nc("Blending mode - Glow-Heat", "Glow-Heat"),687            EKritaBlendingModesId.COMPOSITE_HELOW:                      i18nc("Blending mode - Heat-Glow", "Heat-Glow"),688            EKritaBlendingModesId.COMPOSITE_REEZE:                      i18nc("Blending mode - Reflect-Freeze", "Reflect-Freeze"),689            EKritaBlendingModesId.COMPOSITE_FRECT:                      i18nc("Blending mode - Freeze-Reflect", "Freeze-Reflect"),690            EKritaBlendingModesId.COMPOSITE_FHYRD:                      i18nc("Blending mode - Heat-Glow & Freeze-Reflect Hybrid", "Heat-Glow & Freeze-Reflect Hybrid")691        }692    @staticmethod693    def categoriesIdList():694        """Return list of available categories"""695        return list(EKritaBlendingModes.__CATEGORIES)696    @staticmethod697    def categoryName(id):698        """Return (translated) name for category"""699        if id is None:700            return i18n('None')701        elif id in EKritaBlendingModes.__CATEGORIES:702            return EKritaBlendingModes.__CATEGORIES[id]703        else:704            raise EInvalidValue("Given `id` is not valid")705    @staticmethod706    def categoryBlendingMode(id):707        """Return a list of blending mode Id for given category"""708        if id is None:709            return []710        elif id in EKritaBlendingModes.__CATEGORIES_BLENDING_MODES:711            return list(EKritaBlendingModes.__CATEGORIES_BLENDING_MODES[id])712        else:713            raise EInvalidValue("Given `id` is not valid")714    @staticmethod715    def blendingModeIdList():716        """Return list of available blending mode (without link to category)"""717        return list(EKritaBlendingModes.__BLENDING_MODES)718    @staticmethod719    def blendingModeName(id):720        """Return (translated) name for blending mode"""721        if id is None:722            return []723        elif id in EKritaBlendingModes.__BLENDING_MODES:724            return EKritaBlendingModes.__BLENDING_MODES[id]725        else:726            raise EInvalidValue("Given `id` is not valid")727class EKritaDocument:728    """Provides methods to manage Krita Documents"""729    @staticmethod730    def findLayerById(document, layerId):731        """Find a layer by ID in document732        because Document.nodeByUniqueID() returns a QObject instead of a Node object... :-/733        """734        def find(layerId, parentLayer):735            """sub function called recursively to search layer in document tree"""736            for layer in parentLayer.childNodes():737                if layerId == layer.uniqueId():738                    return layer739                elif len(layer.childNodes()) > 0:740                    returned = find(layerId, layer)741                    if not returned is None:742                        return returned743            return None744        if not isinstance(document, Document):745            raise EInvalidType("Given `document` must be a Krita <Document> type")746        elif not isinstance(layerId, QUuid):747            raise EInvalidType("Given `layerId` must be a valid <QUuid>")748        return find(layerId, document.rootNode())749    @staticmethod750    def findFirstLayerByName(searchFrom, layerName):751        """Find a layer by name in document752        If more than one layer is found in document layers tree, will return the first layer found753        If no layer is found, return None754        The `searchFrom` parameter can be:755        - A Krita Layer (in this case, search in made in sub-nodes)756        - A Krita Document (in this case, search is made from document root node)757        The `layerName` can be a regular expression; just provide layer name with the following form:758        - "re://my_regular_expression759        """760        def find(layerName, isRegex, parentLayer):761            """sub function called recursively to search layer in document tree"""762            for layer in reversed(parentLayer.childNodes()):763                if isRegex == False and layerName == layer.name():764                    return layer765                elif isRegex == True and (reResult := re.match(layerName, layer.name())):766                    return layer767                elif len(layer.childNodes()) > 0:768                    returned = find(layerName, isRegex, layer)769                    if not returned is None:770                        return returned771            return None772        if not (isinstance(searchFrom, Document) or isinstance(searchFrom, Layer)):773            raise EInvalidType("Given `searchFrom` must be a Krita <Layer> or a Krita <Document> type")774        elif not isinstance(layerName, str):775            raise EInvalidType("Given `layerName` must be a valid <str>")776        parentLayer = searchFrom777        if isinstance(searchFrom, Document):778            # a document has been provided, use document root layer779            parentLayer = searchFrom.rootNode()780        if (reResult := re.match("^re://(.*)", layerName)):781            # retrieve given regular expression782            layerName = reResult.group(1)783            return find(layerName, True, parentLayer)784        else:785            return find(layerName, False, parentLayer)786        return None787    @staticmethod788    def findLayersByName(searchFrom, layerName):789        """Find layer(s) by name790        Return a list of all layers for which name is matching given layer name791        If no layer is found, return empty list792        The `searchFrom` parameter can be:793        - A Krita Layer (in this case, search in made in sub-nodes)794        - A Krita Document (in this case, search is made from document root node)795        The `layerName` can be a regular expression; just provide layer name with the following form:796        - "re://my_regular_expression797        """798        def find(layerName, isRegex, parentLayer):799            """sub function called recursively to search layer in document tree"""800            returned=[]801            for layer in reversed(parentLayer.childNodes()):802                if isRegex == False and layerName == layer.name():803                    returned.append(layer)804                elif isRegex == True and (reResult := re.match(layerName, layer.name())):805                    returned.append(layer)806                elif len(layer.childNodes()) > 0:807                    found = find(layerName, isRegex, layer)808                    if not found is None:809                        returned+=found810            return returned811        if not (isinstance(searchFrom, Document) or isinstance(searchFrom, Layer)):812            raise EInvalidType("Given `searchFrom` must be a Krita <Layer> or a Krita <Document> type")813        elif not isinstance(layerName, str):814            raise EInvalidType("Given `layerName` must be a valid <str> (current: {0})".format(type(layerName)))815        parentLayer = searchFrom816        if isinstance(searchFrom, Document):817            # a document has been provided, use document root layer818            parentLayer = searchFrom.rootNode()819        if (reResult := re.match("^re://(.*)", layerName)):820            # retrieve given regular expression821            layerName = reResult.group(1)822            return find(layerName, True, parentLayer)823        else:824            return find(layerName, False, parentLayer)825        return []826    @staticmethod827    def getLayers(searchFrom, recursiveSubLayers=False):828        """Return a list of all layers829        The `searchFrom` parameter can be:830        - A Krita Layer (in this case, return all sub-nodes from given layer)831        - A Krita Document (in this case, return all sub-nodes from document root node)832        If `recursiveSubLayers` is True, also return all subLayers833        """834        def find(recursiveSubLayers, parentLayer):835            """sub function called recursively to search layer in document tree"""836            returned=[]837            for layer in reversed(parentLayer.childNodes()):838                returned.append(layer)839                if recursiveSubLayers and len(layer.childNodes()) > 0:840                    found = find(recursiveSubLayers, layer)841                    if not found is None:842                        returned+=found843            return returned844        if not (isinstance(searchFrom, Document) or isinstance(searchFrom, Layer)):845            raise EInvalidType("Given `searchFrom` must be a Krita <Layer> or a Krita <Document> type")846        elif not isinstance(recursiveSubLayers, bool):847            raise EInvalidType("Given `recursiveSubLayers` must be a <bool>")848        parentLayer = searchFrom849        if isinstance(searchFrom, Document):850            # a document has been provided, use document root layer851            parentLayer = searchFrom.rootNode()852        return find(recursiveSubLayers, parentLayer)853    @staticmethod854    def getLayerFromPath(searchFrom, path):855        """Return a layer from given path856        If no layer is found, return None857        The `searchFrom` parameter can be:858        - A Krita Document (in this case, return all sub-nodes from document root node)859        """860        def find(pathNodes, level, parentLayer):861            """sub function called recursively to search layer in document tree"""862            for layer in reversed(parentLayer.childNodes()):863                if layer.name() == pathNodes[level]:864                    if level == len(pathNodes) - 1:865                        return layer866                    elif len(layer.childNodes()) > 0:867                        return find(pathNodes, level + 1, layer)868            return None869        if not isinstance(searchFrom, Document):870            raise EInvalidType("Given `searchFrom` must be a Krita <Document> type")871        elif not isinstance(path, str):872            raise EInvalidType("Given `path` must be a <str>")873        pathNodes = re.findall(r'(?:[^/"]|"(?:\\.|[^"])*")+', path)874        if not pathNodes is None:875            pathNodes = [re.sub(r'^"|"$', '', pathNode) for pathNode in pathNodes]876        return find(pathNodes, 0, searchFrom.rootNode())877class EKritaNode:878    """Provides methods to manage Krita Nodes"""879    class ProjectionMode(Enum):880        """Projection modes for toQImage(), toQPixmap()"""881        FALSE = 0882        TRUE = 1883        AUTO = 2884    __projectionMode = ProjectionMode.AUTO885    @staticmethod886    def __sleep(value):887        """Sleep for given number of milliseconds"""888        loop = QEventLoop()889        QTimer.singleShot(value, loop.quit)890        loop.exec()891    @staticmethod892    def path(layerNode):893        """Return `layerNode` path in tree894        Example895        =======896            rootnode897             +-- groupLayer1898                 +-- groupLayer2899                     +-- theNode900                     +-- theNode with / character901            return '/groupLayer1/groupLayer2/theNode'902            return '/groupLayer1/groupLayer2/"theNode with / character"'903        """904        def parentPath(layerNode):905            if layerNode.parentNode() is None or layerNode.parentNode().parentNode() is None:906                return ''907            else:908                if '/' in layerNode.name():909                    return f'{parentPath(layerNode.parentNode())}/"{layerNode.name()}"'910                else:911                    return f'{parentPath(layerNode.parentNode())}/{layerNode.name()}'912        if not isinstance(layerNode, Node):913            raise EInvalidType("Given `layerNode` must be a valid Krita <Node> ")914        return parentPath(layerNode)915    @staticmethod916    def toQImage(layerNode, rect=None, projectionMode=None):917        """Return `layerNode` content as a QImage (as ARGB32)918        The `rect` value can be:919        - None, in this case will return all `layerNode` content920        - A QRect() object, in this case return `layerNode` content reduced to given rectangle bounds921        - A Krita document, in this case return `layerNode` content reduced to document bounds922        """923        if layerNode is None:924            raise EInvalidValue("Given `layerNode` can't be None")925        if type(layerNode)==QObject:926            # NOTE: layerNode can be a QObject...927            #       that's weird, but document.nodeByUniqueID() return a QObject for a paintlayer (other Nodes seems to be Ok...)928            #       it can sound strange but in this case the returned QObject is a QObject iwht Node properties929            #       so, need to check if QObject have expected methods930            if hasattr(layerNode, 'type') and hasattr(layerNode, 'bounds') and hasattr(layerNode, 'childNodes') and hasattr(layerNode, 'colorModel') and hasattr(layerNode, 'colorDepth') and hasattr(layerNode, 'colorProfile') and hasattr(layerNode, 'setColorSpace') and hasattr(layerNode, 'setPixelData'):931                pass932            else:933                # consider that it's not a node934                raise EInvalidType("Given `layerNode` must be a valid Krita <Node> ")935        elif not isinstance(layerNode, Node):936            raise EInvalidType("Given `layerNode` must be a valid Krita <Node> ")937        if rect is None:938            rect = layerNode.bounds()939        elif isinstance(rect, Document):940            rect = rect.bounds()941        elif not isinstance(rect, QRect):942            raise EInvalidType("Given `rect` must be a valid Krita <Document>, a <QRect> or None")943        if projectionMode is None:944            projectionMode = EKritaNode.__projectionMode945        if projectionMode == EKritaNode.ProjectionMode.AUTO:946            childNodes=layerNode.childNodes()947            # childNodes can return be None!?948            if childNodes and len(childNodes) == 0:949                projectionMode = EKritaNode.ProjectionMode.FALSE950            else:951                projectionMode = EKritaNode.ProjectionMode.TRUE952        # Need to check what todo for:953        # - masks (8bit/pixels)954        # - other color space (need to convert to 8bits/rgba...?)955        if (layerNode.type() in ('transparencymask', 'filtermask', 'transformmask', 'selectionmask') or956            layerNode.colorModel() != 'RGBA' or957            layerNode.colorDepth() != 'U8'):958            # pixelData/projectionPixelData return a 8bits/pixel matrix959            # didn't find how to convert pixel data to QImlage then use thumbnail() function960            return layerNode.thumbnail(rect.width(), rect.height())961        else:962            if projectionMode == EKritaNode.ProjectionMode.TRUE:963                return QImage(layerNode.projectionPixelData(rect.left(), rect.top(), rect.width(), rect.height()), rect.width(), rect.height(), QImage.Format_ARGB32)964            else:965                return QImage(layerNode.pixelData(rect.left(), rect.top(), rect.width(), rect.height()), rect.width(), rect.height(), QImage.Format_ARGB32)966    @staticmethod967    def toQPixmap(layerNode, rect=None, projectionMode=None):968        """Return `layerNode` content as a QPixmap (as ARGB32)969        If the `projection` value is True, returned :970        The `rect` value can be:971        - None, in this case will return all `layerNode` content972        - A QRect() object, in this case return `layerNode` content reduced to given rectangle bounds973        - A Krita document, in this case return `layerNode` content reduced to document bounds974        """975        return QPixmap.fromImage(EKritaNode.toQImage(layerNode, rect, projectionMode))976    @staticmethod977    def fromQImage(layerNode, image, position=None):978        """Paste given `image` to `position` in '`layerNode`979        The `position` value can be:980        - None, in this case, pixmap will be pasted at position (0, 0)981        - A QPoint() object, pixmap will be pasted at defined position982        """983        # NOTE: layerNode can be a QObject...984        #       that's weird, but document.nodeByUniqueID() return a QObject for a paintlayer (other Nodes seems to be Ok...)985        #       it can sound strange but in this case the returned QObject is a QObject iwht Node properties986        #       so, need to check if QObject have expected methods987        if type(layerNode)==QObject():988            if hasattr(layerNode, 'type') and hasattr(layerNode, 'colorModel') and hasattr(layerNode, 'colorDepth') and hasattr(layerNode, 'colorProfile') and hasattr(layerNode, 'setColorSpace') and hasattr(layerNode, 'setPixelData'):989                pass990            else:991                # consider that it's not a node992                raise EInvalidType("Given `layerNode` must be a valid Krita <Node> ")993        elif not isinstance(layerNode, Node):994            raise EInvalidType("Given `layerNode` must be a valid Krita <Node> ")995        if not isinstance(image, QImage):996            raise EInvalidType("Given `image` must be a valid <QImage> ")997        if position is None:998            position = QPoint(0, 0)999        if not isinstance(position, QPoint):1000            raise EInvalidType("Given `position` must be a valid <QPoint> ")1001        layerNeedBackConversion=False1002        layerColorModel=layerNode.colorModel()1003        layerColorDepth=layerNode.colorDepth()1004        layerColorProfile=layerNode.colorProfile()1005        if layerColorModel != "RGBA" or layerColorDepth != 'U8':1006            # we need to convert layer to RGBA/U81007            layerNode.setColorSpace("RGBA", "U8", "sRGB-elle-V2-srgbtrc.icc")1008            layerNeedBackConversion=True1009        ptr = image.bits()1010        ptr.setsize(image.byteCount())1011        layerNode.setPixelData(QByteArray(ptr.asstring()), position.x(), position.y(), image.width(), image.height())1012        if layerNeedBackConversion:1013            layerNode.setColorSpace(layerColorModel, layerColorDepth, layerColorProfile)1014    @staticmethod1015    def fromQPixmap(layerNode, pixmap, position=None):1016        """Paste given `pixmap` to `position` in '`layerNode`1017        The `position` value can be:1018        - None, in this case, pixmap will be pasted at position (0, 0)1019        - A QPoint() object, pixmap will be pasted at defined position1020        """1021        if not isinstance(pixmap, QPixmap):1022            raise EInvalidType("Given `pixmap` must be a valid <QPixmap> ")1023        if position is None:1024            position = QPoint(0, 0)1025        EKritaNode.fromQImage(layerNode, pixmap.toImage(), position)1026    @staticmethod1027    def fromSVG(layerNode, svgContent, document=None):1028        """Paste given `svgContent` to `position` in '`layerNode`1029        Given `layerNode` must be a 'vectorlayer'1030        The `position` value can be:1031        - None, in this case, pixmap will be pasted at position (0, 0)1032        - A QPoint() object, pixmap will be pasted at defined position1033        Note:1034        - If document is None, consider that active document contains layer1035        - If document is provided, it must contains layerNode1036        Method return a list of shapes (shape inserted into layer)1037        """1038        if isinstance(svgContent, str):1039            svgContent=svgContent.encode()1040        if not isinstance(svgContent, bytes):1041            raise EInvalidType("Given `svgContent` must be a valid <str> or <bytes> SVG document")1042        if not isinstance(layerNode, Node) or layerNode.type()!='vectorlayer':1043            raise EInvalidType("Given `layerNode` must be a valid <VectorLayer>")1044        if document is None:1045            document=Krita.instance().activeDocument()1046        if not isinstance(document, Document):1047            raise EInvalidType("Given `layerNode` must be a valid <Document>")1048        shapes=[shape for shape in layerNode.shapes()]1049        activeNode=document.activeNode()1050        document.setActiveNode(layerNode)1051        document.waitForDone()1052        # Note: following sleep() is here because waitForDone() doesn't seems to1053        #       wait for active node changed...1054        #       set an arbitrary sleep() delay allows to ensure that node is active1055        #       at the end of method execution1056        #       hope current delay is not too short (works for me... but can't put1057        #       a too long delay)1058        #1059        #       Problem occurs with krita 4.4.2 & and tested Krita plus/next tested [2020-01-05]1060        EKritaNode.__sleep(100)1061        mimeContent=QMimeData()1062        mimeContent.setData('image/svg', svgContent)1063        mimeContent.setData('BCIGNORE', b'')1064        QGuiApplication.clipboard().setMimeData(mimeContent)1065        Krita.instance().action('edit_paste').trigger()1066        newShapes=[shape for shape in layerNode.shapes() if not shape in shapes]1067        return newShapes1068    @staticmethod1069    def above(layerNode):1070        """Return node above given `layerNode`1071        If there's no node above given layer, return None"""1072        if layerNode is None:1073            return None1074        if not isinstance(layerNode, Node):1075            raise EInvalidType("Given `layerNode` must be a valid Krita <Node> ")1076        returnNext = False1077        for layer in layerNode.parentNode().childNodes():1078            if returnNext:1079                return layer1080            elif layer == layerNode:1081                returnNext = True1082        return None1083    @staticmethod1084    def below(layerNode):1085        """Return node below given `layerNode`1086        If there's no node below given layer, return None"""1087        if layerNode is None:1088            return None1089        if not isinstance(layerNode, Node):1090            raise EInvalidType("Given `layerNode` must be a valid Krita <Node> ")1091        prevNode = None1092        for layer in layerNode.parentNode().childNodes():1093            if layer == layerNode:1094                return prevNode1095            prevNode = layer...process_mosaics.py
Source:process_mosaics.py  
1# from glob import glob2import glob3import numpy as np4from PIL import Image5import os6import matplotlib.pyplot as plt7import cv2  # pip install opencv-contrib-python8import collections9from sklearn import preprocessing10from sklearn.cluster import KMeans11from ordered_set import OrderedSet12from skimage.io import imread, imsave13from skimage import data, exposure14from skimage.exposure import match_histograms15N_OPTICS_BANDS = 416def plot_histogram(histogram, title):17    plt.figure()18    plt.title(title + " Normalized Histogram")19    #ax = h.add_axes([0,0,1,1])20    range = np.arange(256)21    #plt.ylabel('Number of Pixels')22    #plt.xlabel('Pixel Value')23    #plt.show()24    plt.bar(range, histogram[:,0], width = 1, fc=(1, 0, 0, 0.5), align='center')25    plt.bar(range, histogram[:,1], width = 1, fc=(0, 1, 0, 0.5), align='center')26    plt.bar(range, histogram[:,2], width = 1, fc=(0, 0, 1, 0.5), align='center')27    #h.set_ylim([0, 1])28    plt.show()29def match_histogram(chref, hist, title): 30    # base: cumulative histogram of the reference base map sections of the composite31    # hist: 32    F = np.zeros_like(hist, dtype = float) # create an empty array with same size as base/ref 33    i, j, c, ch = 0, 0, 0, 034    while ch < 3:35        ch_ref_hist = chref[:, ch]36        ch_hist = hist[:, ch]37        n = np.sum(ch_hist) # get number of pixels contributing to the histo38        r = n/max(ch_ref_hist)39        while i in range(0, 256): # for each brightness value40            if c <= r*ch_ref_hist[j]: # c measures the total number of pixels iterated over41                c = c+ch_hist[i]42                F[i, ch] = j43                print(j)44                i = i+145            else:46                j = j+147        i = 048        j = 049        c = 050        ch = ch+151    plot_histogram(F, title+ " Matched")52    return F53def range_0_256(band):54    min = np.amin(band)55    band = band - min56    max = np.amax(band)57    band = band*255/max58    return band59tile_path = "./tiles/accra_-0.2_5.4_0.2_5.6/"60for date_dir_name in os.listdir(tile_path):61    if os.path.isdir(os.path.join(tile_path, date_dir_name)): # ensure is a directory62        date_dir_path = tile_path+date_dir_name+"/" 63        #if date_dir_path != "./tiles/accra_-0.2_5.4_0.2_5.6/2021-08-17/": # uncommenting these two lines will result in only this tile being processed64        #    continue65        # ------------------------- Add Bands Map For Cloud Detection 66        b04 = np.asarray(Image.open(date_dir_path+'l2a_b04.png'), dtype = np.float32)67        b03 = np.asarray(Image.open(date_dir_path+'l2a_b03.png'), dtype = np.float32)68        b02 = np.asarray(Image.open(date_dir_path+'l2a_b02.png'), dtype = np.float32)69        b01 = np.asarray(Image.open(date_dir_path+'l2a_b01.png'), dtype = np.float32)70        b08 = np.asarray(Image.open(date_dir_path+'l1c_b08.png'), dtype = np.float32)71        b09 = np.asarray(Image.open(date_dir_path+'l1c_b09.png'), dtype = np.float32)72        b10 = np.asarray(Image.open(date_dir_path+'l1c_b10.png'), dtype = np.float32)73        clp = np.asarray(Image.open(date_dir_path+'cloud_prob.png'), dtype = np.float32)74        scl = np.asarray(Image.open(date_dir_path+'l2a_scl.png'), dtype = np.float32)75        # ------------------------- Get Colour Image76        rgb_img = b04[:, :, np.newaxis]77        rgb_img = np.insert(rgb_img, rgb_img.shape[2], b03, axis = 2) 78        rgb_img = np.insert(rgb_img, rgb_img.shape[2], b02, axis = 2) 79        rgb_img = rgb_img.astype(np.uint8)80        im = Image.fromarray(rgb_img[:, :, [0,1,2]])81        im.save(date_dir_path+"rgb.png")82        # ------------------------- Create Composite(s)83        max_clp = np.amax(clp) # create a tuple of pixel coords indicating location of highest cloudiness84        min_clp = np.amin(clp) # create a tuple of pixel coords indicating location of lowest cloudiness85        86        # ------------------------- Add Bands 87        #img = clp[:, :, np.newaxis]88        #img = clp89        img = b0190        img = (img * (1+b09/255))91        img = np.clip(img, 0, 255)92        img = img+clp93        #img = b0194        #img = img + b0995        img = img/296        #img = np.insert(img, img.shape[2], b01, axis = 2) 97        #img = np.insert(img, img.shape[2], b09, axis = 2) 98        img = img.astype(np.uint8)99        #im = Image.fromarray(img).show()100        print("SHAPE: ", img.shape) # make sure shape is (3, a, b) -> (b, a, 3), where 3 is RGB101        # ------------------------- Save Shape102        og_shape = img.shape103        # ------------------------- Denoise 104        img = img.astype(np.uint8)105        img = cv2.fastNlMeansDenoising(img, None, 30, 21, 7)106        '''107        img2 = cv2.fastNlMeansDenoisingColored(img[:,:,0:3], None, 10, 30, 21, 7)108        if img.shape[2]>=4:109            alpha = cv2.fastNlMeansDenoising(img[:,:,3], None, 30, 21, 7)110            img2= np.insert(img2, 3, alpha, axis = 2) # insert b09 band to alpha layer111        if img.shape[2]>=5:112            alpha = cv2.fastNlMeansDenoising(img[:,:,4], None, 30, 21, 7)113            img2= np.insert(img2, 4, alpha, axis = 2) # insert b09 band to alpha layer114        if img.shape[2]>=6:115            alpha = cv2.fastNlMeansDenoising(img[:,:,5], None, 30, 21, 7)116            img2= np.insert(img2, 5, alpha, axis = 2) # insert b09 band to alpha layer117        img = img2118        '''119        im = Image.fromarray(img)120        #im = Image.fromarray(img[:, :, [2,1,0]])121        im.save(date_dir_path+"denoised.png")122        # ------------------------- Blur Images123        img = cv2.GaussianBlur(img, (15, 15), 0)124        #for band in range(0, img.shape[2]):125        #    img[:,:, band] = range_0_256(img[:,:, band])126        im = img.astype(np.uint8)127        #im = Image.fromarray(im[:, :, [2,1,0]])128        im = Image.fromarray(im)129        im.save(date_dir_path+"clp.png")130        '''131        # ------------------------- Clustering through K-Means132        # re-shape to get 1D array for each layer (a*b, number of bands)133        img = img.reshape((-1, img.shape[2]))134        print("IMAGE RE-SHAPED: ", img.shape)135        attempts = 10136        K = 12137        ret, label, center = cv2.kmeans(138            img, K, None, None, attempts, cv2.KMEANS_PP_CENTERS)139        center = np.uint8(center)140        res = center[label.flatten()]141        # print("RES: ", res.shape)142        # print(images.reshape((images.shape[1], images.shape[2], 3)).shape)143        img = res.reshape(og_shape)144        img = img.astype(np.float32)145        # ------------------------- Increase image range to 0, 255146        147        #for band in range(0, img.shape[2]):148        #    img[:,:, band] = range_0_256(img[:,:, band])149        # ------------------------- Save cluster150        grey = img[:, :, 0]151        grey = grey.astype(np.float32)152        shades = set() # create a set153        for band in range(1, img.shape[2]):154            grey += img[:, :, band]155        #grey = range_0_256(grey/img.shape[2])156        grey = grey/img.shape[2]157        grey = grey.astype(np.uint8)158        for i in range(0, grey.shape[0]):159            for j in range(0, grey.shape[1]):160                shades.add(grey[i,j])161        print(shades)162        im = Image.fromarray(grey)163        im.save(date_dir_path+"clustered.png")164        '''165# ------------------------- Mosaicing166# TODO: also swap based on cloud probability, whoever has lowest cloud prob167# Load in cloud mask from each day168scl_imgs = {}169rgb_imgs = {}170#cluster_imgs = {}171clp_imgs = {}172clp_counts = {}173histograms = {}174c_histograms = {}175# Load in cloud mask files and get cloud cover count for each image176for date_dir in os.listdir(tile_path):177    if os.path.isdir(os.path.join(tile_path, date_dir)): # ensure is a directory178        for file_name in os.listdir(tile_path+date_dir+"/"):179            if file_name == "clp.png":180                #print(tile_path+date_dir+"/l1c_b09.png")181                clp_imgs[tile_path+date_dir] = np.array(Image.open(tile_path+date_dir+"/clp.png"))182                clp_counts[tile_path+date_dir] = clp_imgs[tile_path+date_dir].sum() # Count number of pixels that is (probably) a cloud183            #if file_name == "clustered.png":184                #print(tile_path+date_dir+"/l1c_b09.png")185                #cluster_imgs[tile_path+date_dir] = np.array(Image.open(tile_path+date_dir+"/clustered.png")) # sub this in for cluster map later186            elif file_name == "rgb.png":187                #print(tile_path+date_dir+"/rgb.png")188                rgb_imgs[tile_path+date_dir] = np.array(Image.open(tile_path+date_dir+"/rgb.png"))189            elif file_name == "l2a_scl.png":190                #print(tile_path+date_dir+"/l2a_scl.png")191                scl_imgs[tile_path+date_dir] = np.array(Image.open(tile_path+date_dir+"/l2a_scl.png"))192            histograms[tile_path+date_dir] = np.zeros((256, 3)) # one for each of R, G, B193            c_histograms[tile_path+date_dir] = np.zeros((256, 3), dtype = float) # one for each of R, G, B194# Choose least cloudy image as base image195#print("CLP COUNTS: ", clp_counts)196clp_counts = {k: v for k, v in sorted(clp_counts.items(), key=lambda item: item[1])} # now sorted in order of least to most cloudy197#print("SORTED CLP COUNTS: ", clp_counts)198 #{k: v for k, v in sorted(clp_counts.items(), key=lambda item: item[1])}199least_cloudy_img_path = min(clp_counts, key=clp_counts.get)200print("Least cloud image is: ", least_cloudy_img_path)201print("Number of clp images: ", len(clp_imgs))202# --------------------------------------------- Create/get composite SCL (water/land classification)203composite_scl = scl_imgs[least_cloudy_img_path] 204if os.path.isfile(tile_path+"scl_composite.png"):205    composite_scl = np.asarray(Image.open(tile_path+"scl_composite.png"), dtype = np.float32)206else:207    composite_bins = np.empty((composite_scl.shape[0], composite_scl.shape[1]), dtype=object)208    for row in range(0, composite_bins.shape[0]):209        for col in range(0, composite_bins.shape[1]):210            composite_bins[row, col] = []211            composite_bins[row, col].append(composite_scl[row, col])212    for scl in scl_imgs:213        print(scl)214        if scl == least_cloudy_img_path:215            continue216        s = scl_imgs[scl] # get scl image217        for row in range(0, s.shape[0]):218            for col in range(0, s.shape[1]):219                if s[row, col] == 139 or s[row, col] == 115 or s[row, col] == 92:220                    composite_bins[row, col].append(s[row, col])221    for row in range(0, composite_bins.shape[0]):222        for col in range(0, composite_bins.shape[1]):223            composite_scl[row, col] = max(composite_bins[row, col], key = composite_bins[row, col].count)224            if composite_scl[row, col] == 139:225                composite_scl[row, col] = 0226            elif composite_scl[row, col] == 115 or composite_scl[row, col] == 92: # land or vegetation227                composite_scl[row, col] = 255 228            else:229                composite_scl[row, col] = 0 # paint unknown as black  230    Image.fromarray(composite_scl).show() # show composite scl image, which has pixels categorized mainly as water/land231    im = Image.fromarray(composite_scl)232    im.save(tile_path+"scl_composite.png")233# at this point we have an scl image from all other images (mostly) defining water and land234# np.save("composite_scl", composite_scl)235# ---------------------------------------------  Create true final RGB image236composite_rgb = rgb_imgs[least_cloudy_img_path].copy() # base rgb image237composite_clp = clp_imgs[least_cloudy_img_path][:,:] # lowest cloud prob image238composite_map = np.zeros(composite_clp.shape, dtype=int) # lowest cloud prob image - fill with zeros indicating base layer239# np.save("cloud_masks", cloud_masks)240# np.save("composite_rgb", composite_rgb)241# composite_rgb = np.load("composite_rgb.npy")242# cloud_masks = np.load("cloud_masks.npy", allow_pickle=True)243# ---------------------------------------------  stack CLPs; get lowest cloud prob pixels and overlay244#Image.fromarray(rgb_imgs[least_cloudy_img_path]).show()245# store histograms of only pixel values that are actually used in final composite246# Loop through base image and start the mosaicing process!247keys = list(clp_counts.keys())248print(keys)249#print(clp_counts)250#print(composite_rgb.shape)251for i in range(0, composite_rgb.shape[0]): 252    for j in range(0, composite_rgb.shape[1]): # for each pixel253        for idx, k in enumerate(clp_counts): # for each clp image in order of lowest cloud probability254            #print(k)255            if k == least_cloudy_img_path:256                continue # skip self257            #print("%d, %d" % (clp_imgs[k][i, j], composite_clp[i, j]))258            if clp_imgs[k][i, j] < composite_clp[i, j]: # Check if there is a cloud at this pixel of the base image259                composite_clp[i, j] = clp_imgs[k][i, j] # fill in the clp composite260                composite_map[i, j] = idx # paint new colour indicative as originating from a map w/ a given index261                composite_rgb[i, j] = rgb_imgs[k][i, j]262                break #try this again after fixing cloud_prob layer detection?263'''264# now count histograms for pixels of composite265for i in range(0, composite_rgb.shape[0]): 266    for j in range(0, composite_rgb.shape[1]): # for each pixel267        m = keys[composite_map[i, j]]268        histograms[m][composite_rgb[i, j, 0], 0] += 1 # add pixel from non composite269        histograms[m][composite_rgb[i, j, 1], 1] += 1270        histograms[m][composite_rgb[i, j, 2], 2] += 1271# at this point we have our true composite img and the individual sections that define the composite. Now create normalized cumulative histograms based on the sections272for h in histograms:273    c_hist = histograms[h].copy()274    for ch in range(0,3):275        sum = 0276        total = np.sum(c_hist[:, ch]) # s should be the same count for all r,g,b histos277        if total != 0:278            for i in range(0, 256):279                sum = sum + c_hist[i, ch]280                c_hist[i, ch] = sum/total # normalization step281    #plot_histogram(c_hist, h)282    c_histograms[h] = c_hist283'''284# hard limit of 255 maps contributing to a single composite (for now)285num_maps = len(clp_counts)286print(num_maps)287composite_map_img = composite_map * 255/num_maps288#composite_map = np.uint8(composite_map)289Image.fromarray(composite_map_img).show()290# count frequency of clp_map values291clp_map_counts = [0] * num_maps292for i in range(0, composite_map.shape[0]): 293    for j in range(0, composite_map.shape[1]): 294        clp_map_counts[composite_map[i,j]] += 1 # find most prevalent maps contributing to composite295# determine base histogram296print(clp_map_counts) 297max_map_count = max(clp_map_counts)298#base_histogram = clp_map_counts.index(max_map_count) #  index of what will be our reference histogram299#print("BASE: ", base_histogram)300#Image.fromarray(composite_rgb).show()301# match other map histogram channels to normalized base histogram channels302'''303for map_idx, h in enumerate(histograms):304    if h != keys[base_histogram]: # for every histogram that isn't the base: match to the base305        #print(histograms[keys[base_histogram]])306        F = match_histogram(c_histograms[keys[base_histogram]], histograms[h], h) # pass in c_hist of reference, hist of img to be modded307        print("MATCHED")308        for ch in range(0, composite_rgb.shape[2]):309            for i in range(0, composite_rgb.shape[0]):310                for j in range(0, composite_rgb.shape[1]):311                    if composite_map[i, j] == map_idx: # Manipulate only the pixels belonging to a non-base map; change all pixels with value h to value b312                            composite_rgb[i, j, ch] = F[composite_rgb[i, j, ch], ch]313        print("COMPOSED")314        Image.fromarray(composite_rgb).show()315'''316#print(histograms[least_cloudy_img_path])317composite_rgb = composite_rgb.astype(np.float32)318for band in range(0, composite_rgb.shape[2]):319    composite_rgb[:,:,band] = range_0_256(composite_rgb[:,:,band])320composite_rgb = composite_rgb.astype(np.uint8)321Image.fromarray(composite_clp).show()322rgb_img = Image.fromarray(composite_rgb[:,:,[0,1,2]])323rgb_img.show()324# ------------------------- Edge detecting with Canny325# using float here since np.nan requires floating points326'''327edge = cv2.Canny(img, 2, 5).astype("float")328print("EDGE SHAPE: ", edge.shape)329print("EDGE: ", edge)330# Not entirely sure why he wanted to replace 0s with "Not a Number" values331# edge[edge == 0] = np.nan #np.nan only exists with floating-point data types332edge = np.uint8(edge)  # converting back to 8 bit for viewing (0-255)333# print("EDGE np.nan: ", edge)334# print("List all indices that have nan value: ", np.argwhere(np.isnan(edge)))335image = Image.open(f)336bckgndImg = np.asarray(image, dtype=np.uint8)337if bckgndImg.ndim == 2:338    bckgndImg = np.stack((bckgndImg,)*3, axis=-1)339elif bckgndImg.shape[2] == 4:340    bckgndImg = bckgndImg[:,:,0:3] # get rid of alpha layer341# Make edge into 3 channel, bgr or rgb image342# RGB for matplotlib, BGR for imshow()343rgb = cv2.cvtColor(edge, cv2.COLOR_GRAY2RGB)344# Dilate the lines so we can see them clearer on the overlay345kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))346thicBoiEdgeRGB = cv2.dilate(rgb, kernel, iterations=1)347# Now all edges are white (255,255,255). to make it red, multiply with another array:348thicBoiEdgeRGB *= np.array((1, 0, 0), np.uint8)  # Leave R = 1, G, B = 0349# Overlay350overlayedImg = np.bitwise_or(bckgndImg, thicBoiEdgeRGB)351im = Image.fromarray(overlayedImg)352im.save("./maps/"+"_edge_overlay.png")...pg_composite.py
Source:pg_composite.py  
...192            checkfirst and193            bind.dialect.has_type(bind, self.name, schema=self.schema)194        ):195            bind.execute(DropCompositeType(self))196def register_psycopg2_composite(dbapi_connection, composite):197    psycopg2.extras.register_composite(198        composite.name,199        dbapi_connection,200        globally=True,201        factory=composite.caster202    )203    def adapt_composite(value):204        adapted = [205            adapt(206                getattr(value, column.name)207                if not isinstance(column.type, TypeDecorator)208                else column.type.process_bind_param(209                    getattr(value, column.name),210                    PGDialect_psycopg2()211                )212            )213            for column in214            composite.columns215        ]216        for value in adapted:217            if hasattr(value, 'prepare'):218                value.prepare(dbapi_connection)219        values = [220            value.getquoted().decode(dbapi_connection.encoding)221            if six.PY3222            else value.getquoted()223            for value in adapted224        ]225        return AsIs("(%s)::%s" % (', '.join(values), composite.name))226    register_adapter(composite.type_cls, adapt_composite)227def before_create(target, connection, **kw):228    for name, composite in registered_composites.items():229        composite.create(connection, checkfirst=True)230        register_psycopg2_composite(231            connection.connection.connection,232            composite233        )234def after_drop(target, connection, **kw):235    for name, composite in registered_composites.items():236        composite.drop(connection, checkfirst=True)237def register_composites(connection):238    for name, composite in registered_composites.items():239        register_psycopg2_composite(240            connection.connection.connection,241            composite242        )243def attach_composite_listeners():244    listeners = [245        (sa.MetaData, 'before_create', before_create),246        (sa.MetaData, 'after_drop', after_drop),247    ]248    for listener in listeners:249        if not sa.event.contains(*listener):250            sa.event.listen(*listener)251def remove_composite_listeners():252    listeners = [253        (sa.MetaData, 'before_create', before_create),...wscript_build
Source:wscript_build  
1#!/usr/bin/env python2bld.RECURSE('ldap')3bld.RECURSE('wbclient')4bld.SAMBA_LIBRARY('errors',5                  source='../../libcli/util/doserr.c util/errormap.c util/nterr.c',6                  public_headers='../../libcli/util/error.h ../../libcli/util/ntstatus.h ../../libcli/util/doserr.h ../../libcli/util/werror.h',7                  header_path='core',8                  deps='talloc',9                  private_library=True10                  )11bld.SAMBA_SUBSYSTEM('LIBSAMBA_TSOCKET',12	source='../../libcli/util/tstream.c',13	public_deps='LIBTSOCKET UTIL_TEVENT'14	)15bld.SAMBA_SUBSYSTEM('LIBCLI_LSA',16	source='util/clilsa.c',17	autoproto='util/clilsa.h',18	public_deps='RPC_NDR_LSA',19	deps='security'20	)21bld.SAMBA_SUBSYSTEM('LIBCLI_COMPOSITE',22	source='composite/composite.c',23	autoproto='composite/proto.h',24	public_deps='events'25	)26bld.SAMBA_SUBSYSTEM('LIBCLI_SMB_COMPOSITE',27	source='smb_composite/loadfile.c smb_composite/savefile.c smb_composite/connect.c smb_composite/sesssetup.c smb_composite/fetchfile.c smb_composite/appendacl.c smb_composite/fsinfo.c smb_composite/smb2.c',28	autoproto='smb_composite/proto.h',29	deps='LIBCLI_SMB2',30	public_deps='LIBCLI_COMPOSITE credentials gensec LIBCLI_RESOLVE'31	)32bld.SAMBA_SUBSYSTEM('LIBCLI_DGRAM',33	source='dgram/dgramsocket.c dgram/mailslot.c dgram/netlogon.c dgram/browse.c',34	public_deps='cli-nbt ndr LIBCLI_RESOLVE LIBCLI_NETLOGON LIBCLI_RESOLVE'35	)36bld.SAMBA_SUBSYSTEM('LIBCLI_WREPL',37	source='wrepl/winsrepl.c',38	autoproto='wrepl/winsrepl_proto.h',39	public_deps='NDR_WINSREPL samba_socket events LIBPACKET LIBSAMBA_TSOCKET'40	)41bld.SAMBA_SUBSYSTEM('LIBCLI_RESOLVE',42	source='resolve/resolve.c',43	autoproto='resolve/proto.h',44	deps='roken',45	public_deps='NDR_NBT LIBTSOCKET'46	)47bld.SAMBA_SUBSYSTEM('LP_RESOLVE',48	source='resolve/bcast.c resolve/nbtlist.c resolve/wins.c resolve/dns_ex.c resolve/file.c resolve/host.c resolve/resolve_lp.c',49	autoproto='resolve/lp_proto.h',50	deps='cli-nbt samba-hostconfig netif'51	)52bld.SAMBA_SUBSYSTEM('LIBCLI_FINDDCS',53	source='finddcs_nbt.c finddcs_cldap.c',54	autoproto='finddcs_proto.h',55	public_deps='cli-nbt MESSAGING RPC_NDR_IRPC LIBCLI_CLDAP'56	)57bld.SAMBA_SUBSYSTEM('LIBCLI_SMB',58	source='clireadwrite.c cliconnect.c clifile.c clilist.c clitrans2.c climessage.c clideltree.c',59	autoproto='libcli_proto.h',60	public_deps='LIBCLI_RAW errors LIBCLI_AUTH LIBCLI_SMB_COMPOSITE cli-nbt security LIBCLI_RESOLVE LIBCLI_DGRAM LIBCLI_SMB2 LIBCLI_FINDDCS samba_socket'61	)62bld.SAMBA_SUBSYSTEM('LIBCLI_RAW',63	source='raw/rawfile.c raw/smb_signing.c raw/clisocket.c raw/clitransport.c raw/clisession.c raw/clitree.c raw/clierror.c raw/rawrequest.c raw/rawreadwrite.c raw/rawsearch.c raw/rawsetfileinfo.c raw/raweas.c raw/rawtrans.c raw/clioplock.c raw/rawnegotiate.c raw/rawfsinfo.c raw/rawfileinfo.c raw/rawnotify.c raw/rawioctl.c raw/rawacl.c raw/rawdate.c raw/rawlpq.c raw/rawshadow.c',64	autoproto='raw/raw_proto.h',65	public_deps='samba_socket LIBPACKET LIBCRYPTO',66	deps='LIBCLI_COMPOSITE LIBCLI_RESOLVE security ndr samba-util errors CHARSET talloc LIBCLI_SMB_COMPOSITE tevent NDR_NBT_BUF LIBCLI_SMB_COMMON'67	)68bld.RECURSE('smb2')...Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!
