Blur and noise adjustment layers, Image Trim, Inner Glow (12.8c)
This commit is contained in:
1 parent
7ae263de80
commit
31e2dd3864
60 files changed
+1673
-105
No files matched your search
@@ -13,6 +13,9 @@ QString rawValue(AdjustmentKind kind)
|
||||
case AdjustmentKind::exposure: return QStringLiteral("Exposure");
|
||||
case AdjustmentKind::gradientMap: return QStringLiteral("Gradient Map");
|
||||
case AdjustmentKind::grain: return QStringLiteral("Grain");
|
||||
case AdjustmentKind::addNoise: return QStringLiteral("Add Noise");
|
||||
case AdjustmentKind::gaussianBlur: return QStringLiteral("Gaussian Blur");
|
||||
case AdjustmentKind::motionBlur: return QStringLiteral("Motion Blur");
|
||||
case AdjustmentKind::invert: return QStringLiteral("Invert");
|
||||
case AdjustmentKind::blackWhite: return QStringLiteral("Black & White");
|
||||
case AdjustmentKind::colorBalance: return QStringLiteral("Color Balance");
|
||||
@@ -36,6 +39,9 @@ std::optional<FilterKind> filterKind(AdjustmentKind kind)
|
||||
case AdjustmentKind::exposure: return FilterKind::exposure;
|
||||
case AdjustmentKind::gradientMap: return FilterKind::gradientMap;
|
||||
case AdjustmentKind::grain: return FilterKind::grain;
|
||||
case AdjustmentKind::addNoise: return FilterKind::addNoise;
|
||||
case AdjustmentKind::gaussianBlur: return FilterKind::gaussianBlur;
|
||||
case AdjustmentKind::motionBlur: return FilterKind::motionBlur;
|
||||
case AdjustmentKind::blackWhite: return FilterKind::blackWhite;
|
||||
case AdjustmentKind::colorBalance: return FilterKind::colorBalance;
|
||||
// Panels of their own; Invert has nothing to set.
|
||||
@@ -106,6 +112,85 @@ void LayerAdjustment::setColorBalance(const ColorBalanceSettings &value)
|
||||
colorBalanceSettings = value;
|
||||
}
|
||||
|
||||
double LayerAdjustment::gaussianRadius() const
|
||||
{
|
||||
return blurRadius.value_or(10);
|
||||
}
|
||||
|
||||
void LayerAdjustment::setGaussianRadius(double value)
|
||||
{
|
||||
blurRadius = value;
|
||||
}
|
||||
|
||||
double LayerAdjustment::resolvedMotionAngle() const
|
||||
{
|
||||
return motionAngle.value_or(0);
|
||||
}
|
||||
|
||||
void LayerAdjustment::setResolvedMotionAngle(double value)
|
||||
{
|
||||
motionAngle = value;
|
||||
}
|
||||
|
||||
double LayerAdjustment::resolvedMotionDistance() const
|
||||
{
|
||||
return motionDistance.value_or(10);
|
||||
}
|
||||
|
||||
void LayerAdjustment::setResolvedMotionDistance(double value)
|
||||
{
|
||||
motionDistance = value;
|
||||
}
|
||||
|
||||
double LayerAdjustment::resolvedNoiseAmount() const
|
||||
{
|
||||
return noiseAmount.value_or(10);
|
||||
}
|
||||
|
||||
void LayerAdjustment::setResolvedNoiseAmount(double value)
|
||||
{
|
||||
noiseAmount = value;
|
||||
}
|
||||
|
||||
bool LayerAdjustment::resolvedNoiseGaussian() const
|
||||
{
|
||||
return noiseGaussian.value_or(false);
|
||||
}
|
||||
|
||||
void LayerAdjustment::setResolvedNoiseGaussian(bool value)
|
||||
{
|
||||
noiseGaussian = value;
|
||||
}
|
||||
|
||||
bool LayerAdjustment::resolvedNoiseMonochromatic() const
|
||||
{
|
||||
return noiseMonochromatic.value_or(false);
|
||||
}
|
||||
|
||||
void LayerAdjustment::setResolvedNoiseMonochromatic(bool value)
|
||||
{
|
||||
noiseMonochromatic = value;
|
||||
}
|
||||
|
||||
quint32 LayerAdjustment::resolvedNoiseSeed() const
|
||||
{
|
||||
return noiseSeed.value_or(0);
|
||||
}
|
||||
|
||||
void LayerAdjustment::setResolvedNoiseSeed(quint32 value)
|
||||
{
|
||||
noiseSeed = value;
|
||||
}
|
||||
|
||||
double LayerAdjustment::samplingMargin() const
|
||||
{
|
||||
switch (kind) {
|
||||
case AdjustmentKind::gaussianBlur: return gaussianRadius() * 3 + 2;
|
||||
case AdjustmentKind::motionBlur: return resolvedMotionDistance() / 2 + 2;
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Bounds refuse what is no number: no isFinite terms.
|
||||
bool LayerAdjustment::isValid() const
|
||||
{
|
||||
@@ -130,10 +215,11 @@ bool LayerAdjustment::isValid() const
|
||||
return false;
|
||||
}
|
||||
return curves.isValid() && exposure().isValid() && gradientMap().isValid() && grain().isValid() && blackWhite().isValid()
|
||||
&& colorBalance().isValid();
|
||||
&& colorBalance().isValid() && gaussianRadius() >= 0.1 && gaussianRadius() <= 250 && std::abs(resolvedMotionAngle()) <= 90
|
||||
&& resolvedMotionDistance() >= 1 && resolvedMotionDistance() <= 2000 && resolvedNoiseAmount() >= 0.1 && resolvedNoiseAmount() <= 400;
|
||||
}
|
||||
|
||||
QImage LayerAdjustment::apply(const QImage &image, std::optional<QRectF> region) const
|
||||
QImage LayerAdjustment::apply(const QImage &image, std::optional<QRectF> region, double scale) const
|
||||
{
|
||||
switch (kind) {
|
||||
case AdjustmentKind::hsv:
|
||||
@@ -144,6 +230,21 @@ QImage LayerAdjustment::apply(const QImage &image, std::optional<QRectF> region)
|
||||
case AdjustmentKind::gradientMap: return gradientMap().apply(image);
|
||||
case AdjustmentKind::blackWhite: return blackWhite().apply(image);
|
||||
case AdjustmentKind::colorBalance: return colorBalance().apply(image);
|
||||
case AdjustmentKind::addNoise:
|
||||
case AdjustmentKind::gaussianBlur:
|
||||
case AdjustmentKind::motionBlur: {
|
||||
const FilterSettings settings{.radius = gaussianRadius(),
|
||||
.angle = resolvedMotionAngle(),
|
||||
.distance = resolvedMotionDistance(),
|
||||
.amount = resolvedNoiseAmount(),
|
||||
.gaussian = resolvedNoiseGaussian(),
|
||||
.monochromatic = resolvedNoiseMonochromatic()};
|
||||
FilterJob job{filterKind(kind).value(), image, settings, scale, std::nullopt, QTransform(), resolvedNoiseSeed()};
|
||||
// Swift's region origin, counted in the image's own pixels.
|
||||
if (region)
|
||||
job.noiseOrigin = region->topLeft() * (image.width() / region->width());
|
||||
return PixelFilter::run(job);
|
||||
}
|
||||
case AdjustmentKind::invert: return PixelInvert::run(PixelInvert::Job{image, false, QTransform(), std::nullopt});
|
||||
case AdjustmentKind::grain: {
|
||||
// Grain sits in the document, however the image is cut.
|
||||
@@ -169,6 +270,8 @@ void EditorSession::addAdjustment(AdjustmentKind kind)
|
||||
grain.seed = QRandomGenerator::global()->generate();
|
||||
adjustment.setGrain(grain);
|
||||
}
|
||||
if (kind == AdjustmentKind::addNoise)
|
||||
adjustment.setResolvedNoiseSeed(QRandomGenerator::global()->generate());
|
||||
layer.adjustment = adjustment;
|
||||
const std::optional<ImageLayer> active = activeLayer();
|
||||
layer.parentID = active && active->isGroup ? m_activeLayerID : active ? active->parentID : std::nullopt;
|
||||
|
||||
Reference in new issue
Block a user