File indexing completed on 2024-05-19 04:26:54

0001 /*
0002  *  SPDX-FileCopyrightText: 2017 Wolthera van Hövell tot Westerflier <griffinvalley@gmail.com>
0003  *
0004  *  SPDX-License-Identifier: LGPL-2.0-or-later
0005  */
0006 #ifndef LIBKIS_COLORIZEMASK_H
0007 #define LIBKIS_COLORIZEMASK_H
0008 
0009 #include <QObject>
0010 #include "Node.h"
0011 #include "ManagedColor.h"
0012 
0013 #include <kis_types.h>
0014 
0015 #include "kritalibkis_export.h"
0016 #include "libkis.h"
0017 
0018 /**
0019  * @brief The ColorizeMask class
0020  * A colorize mask is a mask type node that can be used
0021  * to color in line art.
0022  *
0023 @code
0024 window = Krita.instance().activeWindow()
0025 doc = Krita.instance().createDocument(10, 3, "Test", "RGBA", "U8", "", 120.0)
0026 window.addView(doc)
0027 root = doc.rootNode();
0028 node = doc.createNode("layer", "paintLayer")
0029 root.addChildNode(node, None)
0030 nodeData = QByteArray.fromBase64(b"AAAAAAAAAAAAAAAAEQYMBhEGDP8RBgz/EQYMAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAARBgz5EQYM/xEGDAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEQYMAhEGDAkRBgwCAAAAAAAAAAAAAAAA");
0031 node.setPixelData(nodeData,0,0,10,3)
0032 
0033 cols = [ ManagedColor('RGBA','U8',''), ManagedColor('RGBA','U8','') ]
0034 cols[0].setComponents([0.65490198135376, 0.345098048448563, 0.474509805440903, 1.0]);
0035 cols[1].setComponents([0.52549022436142, 0.666666686534882, 1.0, 1.0]);
0036 keys = [
0037         QByteArray.fromBase64(b"/48AAAAAAAAAAAAAAAAAAAAAAACmCwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"),
0038         QByteArray.fromBase64(b"AAAAAAAAAACO9ocAAAAAAAAAAAAAAAAAAAAAAMD/uQAAAAAAAAAAAAAAAAAAAAAAGoMTAAAAAAAAAAAA")
0039         ]
0040 
0041 mask = doc.createColorizeMask('c1')
0042 node.addChildNode(mask,None)
0043 mask.setEditKeyStrokes(True)
0044 
0045 mask.setUseEdgeDetection(True)
0046 mask.setEdgeDetectionSize(4.0)
0047 mask.setCleanUpAmount(70.0)
0048 mask.setLimitToDeviceBounds(True)
0049 mask.initializeKeyStrokeColors(cols)
0050 
0051 for col,key in zip(cols,keys):
0052     mask.setKeyStrokePixelData(key,col,0,0,20,3)
0053 
0054 mask.updateMask()
0055 mask.setEditKeyStrokes(False);
0056 mask.setShowOutput(True);
0057 @endcode
0058  */
0059 class KRITALIBKIS_EXPORT ColorizeMask : public Node
0060 {
0061     Q_OBJECT
0062     Q_DISABLE_COPY(ColorizeMask)
0063 
0064 public:
0065     explicit ColorizeMask(KisImageSP image, QString name, QObject *parent = 0);
0066     explicit ColorizeMask(KisImageSP image, KisColorizeMaskSP mask, QObject *parent = 0);
0067     ~ColorizeMask() override;
0068 public Q_SLOTS:
0069 
0070     /**
0071      * @brief type Krita has several types of nodes, split in layers and masks. Group
0072      * layers can contain other layers, any layer can contain masks.
0073      *
0074      * @return colorizemask
0075      *
0076      * If the Node object isn't wrapping a valid Krita layer or mask object, and
0077      * empty string is returned.
0078      */
0079     virtual QString type() const override;
0080 
0081     /**
0082      * @brief keyStrokesColors
0083      * Colors used in the Colorize Mask's keystrokes.
0084      * @return a ManagedColor list containing the colors of keystrokes.
0085      */
0086     QList<ManagedColor*> keyStrokesColors() const;
0087 
0088     /**
0089      * @brief initializeKeyStrokeColors
0090      * Set the colors to use for the Colorize Mask's keystrokes.
0091      * @param colors a list of ManagedColor to use for the keystrokes.
0092      * @param transparentIndex index of the color that should be marked as transparent.
0093      */
0094     void initializeKeyStrokeColors(QList<ManagedColor*> colors, int transparentIndex = -1);
0095 
0096     /**
0097      * @brief removeKeyStroke
0098      * Remove a color from the Colorize Mask's keystrokes.
0099      * @param color a ManagedColor to be removed from the keystrokes.
0100      */
0101     void removeKeyStroke(ManagedColor* color);
0102 
0103     /**
0104      * @brief transparencyIndex
0105      * Index of the transparent color.
0106      * @return an integer containing the index of the current color marked as transparent.
0107      */
0108     int transparencyIndex() const;
0109 
0110     /**
0111      * @brief keyStrokePixelData
0112      * reads the given rectangle from the keystroke image data and returns it as a byte
0113      * array. The pixel data starts top-left, and is ordered row-first.
0114      * @param color a ManagedColor to get keystrokes pixeldata from.
0115      * @param x x position from where to start reading
0116      * @param y y position from where to start reading
0117      * @param w row length to read
0118      * @param h number of rows to read
0119      * @return a QByteArray with the pixel data. The byte array may be empty.
0120      */
0121     QByteArray keyStrokePixelData(ManagedColor* color, int x, int y, int w, int h) const;
0122 
0123     /**
0124      * @brief setKeyStrokePixelData
0125      * writes the given bytes, of which there must be enough, into the
0126      * keystroke, the keystroke's original pixels are overwritten
0127      *
0128      * @param value the byte array representing the pixels. There must be enough bytes available.
0129      * Krita will take the raw pointer from the QByteArray and start reading, not stopping before
0130      * (number of channels * size of channel * w * h) bytes are read.
0131      *
0132      * @param color a ManagedColor to set keystrokes pixeldata for.
0133      * @param x the x position to start writing from
0134      * @param y the y position to start writing from
0135      * @param w the width of each row
0136      * @param h the number of rows to write
0137      * @return true if writing the pixeldata worked
0138      */
0139     bool setKeyStrokePixelData(QByteArray value, ManagedColor* color, int x, int y, int w, int h);
0140 
0141     /**
0142      * @brief setUseEdgeDetection
0143      * Activate this for line art with large solid areas, for example shadows on an object.
0144      * @param value true to enable edge detection, false to disable.
0145      */
0146     void setUseEdgeDetection(bool value);
0147 
0148     /**
0149      * @brief useEdgeDetection
0150      * @return true if Edge detection is enabled, false if disabled.
0151      */
0152     bool useEdgeDetection() const;
0153 
0154     /**
0155      * @brief setEdgeDetectionSize
0156      * Set the value to the thinnest line on the image.
0157      * @param value a float value of the edge size to detect in pixels.
0158      */
0159     void setEdgeDetectionSize(qreal value);
0160 
0161     /**
0162      * @brief edgeDetectionSize
0163      * @return a float value of the edge detection size in pixels.
0164      */
0165     qreal edgeDetectionSize() const;
0166 
0167     /**
0168      * @brief setCleanUpAmount
0169      * This will attempt to handle messy strokes that overlap the line art where they shouldn't.
0170      * @param value a float value from 0.0 to 100.00 where 0.0 is no cleanup is done and 100.00 is most aggressive.
0171      */
0172     void setCleanUpAmount(qreal value);
0173 
0174     /**
0175      * @brief cleanUpAmount
0176      * @return a float value of 0.0 to 100.0 representing the cleanup amount where 0.0 is no cleanup is done and 100.00 is most aggressive.
0177      */
0178     qreal cleanUpAmount() const;
0179 
0180     /**
0181      * @brief setLimitToDeviceBounds
0182      * Limit the colorize mask to the combined layer bounds of the strokes and the line art it is filling. This can speed up the use of the mask on complicated compositions, such as comic pages.
0183      * @param value set true to enabled limit bounds, false to disable.
0184      */
0185     void setLimitToDeviceBounds(bool value);
0186 
0187     /**
0188      * @brief limitToDeviceBounds
0189      * @return true if limit bounds is enabled, false if disabled.
0190      */
0191     bool limitToDeviceBounds() const;
0192 
0193     /**
0194      * @brief updateMask
0195      * Process the Colorize Mask's keystrokes and generate a projection of the computed colors.
0196      * @param force force an update
0197      */
0198     void updateMask(bool force = false);
0199 
0200     void resetCache();
0201 
0202     /**
0203      * @brief showOutput
0204      * Show output mode allows the user to see the result of the Colorize Mask's algorithm.
0205      * @return true if edit show coloring mode is enabled, false if disabled.
0206      */
0207     bool showOutput() const;
0208 
0209     /**
0210      * @brief setShowOutput
0211      * Toggle Colorize Mask's show output mode.
0212      * @param enabled set true to enable show coloring mode and false to disable it.
0213      */
0214     void setShowOutput(bool enabled);
0215 
0216     /**
0217      * @brief editKeyStrokes
0218      * Edit keystrokes mode allows the user to modify keystrokes on the active Colorize Mask.
0219      * @return true if edit keystrokes mode is enabled, false if disabled.
0220      */
0221     bool editKeyStrokes() const;
0222 
0223     /**
0224      * @brief setEditKeyStrokes
0225      * Toggle Colorize Mask's edit keystrokes mode.
0226      * @param enabled set true to enable edit keystrokes mode and false to disable it.
0227      */
0228     void setEditKeyStrokes(bool enabled);
0229 
0230 };
0231 
0232 #endif // LIBKIS_COLORIZEMASK_H
0233 
0234