File indexing completed on 2024-05-12 15:58:49
0001 /* 0002 * This file is part of Krita 0003 * 0004 * SPDX-FileCopyrightText: 2021 Deif Lou <ginoba@gmail.com> 0005 * 0006 * SPDX-License-Identifier: GPL-2.0-or-later 0007 */ 0008 0009 #ifndef KIS_AUTO_LEVELS_H 0010 #define KIS_AUTO_LEVELS_H 0011 0012 #include <QVector> 0013 0014 #include <KoColor.h> 0015 #include <kis_paint_device.h> 0016 #include <KisLevelsCurve.h> 0017 #include <kritaimage_export.h> 0018 0019 class KisHistogram; 0020 0021 /** 0022 * @brief This namespace contains functions to compute the levels adjustment 0023 * parameters automatically from a histogram 0024 */ 0025 namespace KisAutoLevels 0026 { 0027 0028 /** 0029 * @brief The different methods to enhance the contrast 0030 */ 0031 enum ShadowsAndHighlightsAdjustmentMethod { 0032 ShadowsAndHighlightsAdjustmentMethod_MonochromaticContrast, 0033 ShadowsAndHighlightsAdjustmentMethod_PerChannelContrast 0034 }; 0035 0036 /** 0037 * @brief The different methods to enhance the mid tones 0038 */ 0039 enum MidtonesAdjustmentMethod { 0040 MidtonesAdjustmentMethod_None, 0041 MidtonesAdjustmentMethod_UseMedian, 0042 MidtonesAdjustmentMethod_UseMean 0043 }; 0044 0045 /** 0046 * @brief Convenience class that associates a KisHistogram and a channel index. 0047 * This is useful because setting a channel on the histogram mutates it. This 0048 * way the functions can change the histogram channel by looking at the 0049 * "channel" field 0050 * 0051 */ 0052 struct KRITAIMAGE_EXPORT ChannelHistogram 0053 { 0054 KisHistogram *histogram{nullptr}; 0055 int channel{0}; 0056 }; 0057 0058 /** 0059 * @brief Takes a reference histogram (luma, lightness) and computes the black 0060 * and white points to maximize the contrast having into account 0061 * the clipping. 0062 * @return A pair containing the black and white points indices 0063 */ 0064 QPair<qreal, qreal> KRITAIMAGE_EXPORT getInputBlackAndWhitePoints(ChannelHistogram histogram, 0065 qreal shadowsClipping, 0066 qreal highlightsClipping); 0067 0068 /** 0069 * @brief Finds the darkest and whitest colors in the device having into account 0070 * the clipping 0071 * @return A pair containing the "darkest" and "lighter" colors 0072 */ 0073 QPair<KoColor, KoColor> KRITAIMAGE_EXPORT getDarkestAndWhitestColors(const KisPaintDeviceSP device, 0074 qreal shadowsClipping, 0075 qreal highlightsClipping); 0076 0077 /** 0078 * @brief Computes a gamma value that "moves" the input midpoint towards 0079 * the output midpoint 0080 * @param blackPoint If this gamma value will be part of a more complex levels 0081 * adjustment, set its black point here. Set it to 0 0082 * otherwhise. Since the gamma correction is applied after 0083 * the linear mapping given by the black and white points in a 0084 * levels adjustment, you have to provide those here to get 0085 * the correct gamma 0086 * @param whitePoint same as with blackPoint but for the white point 0087 * @param inputIntensity This is the intensity value that we want to map to the 0088 * output value. Sensible values are the mean and the median 0089 * @param outputIntensity This is the intensity value to which the input value 0090 * will be mapped to after the gamma correction. Use 0.5 0091 * to neutralize the midtones 0092 * @return the gamma value that, when applied after the lineat mapping given by 0093 * the black and white points, will map the input intensity to the 0094 * output intensity 0095 */ 0096 qreal KRITAIMAGE_EXPORT getGamma(qreal blackPoint, 0097 qreal whitePoint, 0098 qreal inputIntensity, 0099 qreal outputIntensity); 0100 0101 /** 0102 * @brief Creates a KisLevelsCurve for every channel in "channelsHistograms". 0103 * Computes the input black and white points from the intensity histogram. 0104 * Computes the gamma from each channels histogram and "outputMidtones" 0105 * if the method is not "None". The output black and white points are 0106 * computed from "outputBlackPoints" and "outputWhitePoints" 0107 * @param lightnessHistogram histogram to compute the input black and white 0108 * points from 0109 * @param channelsHistograms list of histograms to compute the gammas from. This 0110 * is also used to know the number of output levels infos 0111 * @param shadowsClipping A normalized perentage that is used to know how many 0112 * samples should be clipped on the shadows side of the 0113 * histogram by the input black point 0114 * @param highlightsClipping A normalized perentage that is used to know how 0115 * many samples should be clipped on the highlights 0116 * side of the histogram by the input white point 0117 * @param maximumInputBlackAndWhiteOffset A maximum value for the input black 0118 * and white points. The black point won't 0119 * be greater than this, and the white 0120 * point won't be lesser than 1 - this 0121 * @param midtonesAdjustmentMethod The method used to get the gamma 0122 * @param midtonesAdjustmentAmount The strength of the midtone adjustment 0123 * @param outputBlackPoints The output black points used in each levels info 0124 * @param outputWhitePoints The output white points used in each levels info 0125 * @param outputMidtones The desired output midtone values for the gamma adjustment 0126 * @return A list of levels infos containing parameters for the levels adjustment 0127 */ 0128 QVector<KisLevelsCurve> KRITAIMAGE_EXPORT adjustMonochromaticContrast(ChannelHistogram lightnessHistogram, 0129 QVector<ChannelHistogram> &channelsHistograms, 0130 qreal shadowsClipping, 0131 qreal highlightsClipping, 0132 qreal maximumInputBlackAndWhiteOffset, 0133 MidtonesAdjustmentMethod midtonesAdjustmentMethod, 0134 qreal midtonesAdjustmentAmount, 0135 const QVector<qreal> &outputBlackPoints, 0136 const QVector<qreal> &outputWhitePoints, 0137 const QVector<qreal> &outputMidtones); 0138 0139 /** 0140 * @brief Creates a KisLevelsCurve for every channel in "channelsHistograms". 0141 * Computes the input black and white points from each channels 0142 * histogram separately. Computes the gamma from each channels histogram 0143 * and "outputMidtones" if the method is not "None". The 0144 * output black and white points are computed from "outputBlackPoints" 0145 * and "outputWhitePoints" 0146 * @param channelsHistograms list of histograms to compute the gammas from. This 0147 * is also used to know the number of output levels infos 0148 * @param shadowsClipping A normalized perentage that is used to know how many 0149 * samples should be clipped on the shadows side of the 0150 * histogram by the input black point 0151 * @param highlightsClipping A normalized perentage that is used to know how 0152 * many samples should be clipped on the highlights 0153 * side of the histogram by the input white point 0154 * @param maximumInputBlackAndWhiteOffset A maximum value for the input black 0155 * and white points. The black point won't 0156 * be greater than this, and the white 0157 * point won't be lesser than 1 - this 0158 * @param midtonesAdjustmentMethod The method used to get the gamma 0159 * @param midtonesAdjustmentAmount The strength of the midtone adjustment 0160 * @param outputBlackPoints The output black points used in each levels info 0161 * @param outputWhitePoints The output white points used in each levels info 0162 * @param outputMidtones The desired output midtone values for the gamma adjustment 0163 * @return A list of levels infos containing parameters for the levels adjustment 0164 */ 0165 QVector<KisLevelsCurve> KRITAIMAGE_EXPORT adjustPerChannelContrast(QVector<ChannelHistogram> &channelsHistograms, 0166 qreal shadowsClipping, 0167 qreal highlightsClipping, 0168 qreal maximumInputBlackAndWhiteOffset, 0169 MidtonesAdjustmentMethod midtonesAdjustmentMethod, 0170 qreal midtonesAdjustmentAmount, 0171 const QVector<qreal> &outputBlackPoints, 0172 const QVector<qreal> &outputWhitePoints, 0173 const QVector<qreal> &outputMidtones); 0174 0175 } 0176 0177 #endif