/*
* Copyright 2017 Laszlo Balazs-Csiki
*
* This file is part of Pixelitor. Pixelitor is free software: you
* can redistribute it and/or modify it under the terms of the GNU
* General Public License, version 3 as published by the Free
* Software Foundation.
*
* Pixelitor is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Pixelitor. If not, see <http://www.gnu.org/licenses/>.
*/
package pixelitor.filters.jhlabsproxies;
import com.jhlabs.image.OilFilter;
import pixelitor.filters.FilterWithParametrizedGUI;
import pixelitor.filters.ResizingFilterHelper;
import pixelitor.filters.gui.GroupedRangeParam;
import pixelitor.filters.gui.IntChoiceParam;
import pixelitor.filters.gui.IntChoiceParam.Value;
import pixelitor.filters.gui.ParamSet;
import pixelitor.filters.gui.RangeParam;
import pixelitor.filters.gui.ShowOriginal;
import pixelitor.utils.BasicProgressTracker;
import pixelitor.utils.ProgressTracker;
import java.awt.image.BufferedImage;
import static pixelitor.filters.ResizingFilterHelper.ScaleUpQuality;
import static pixelitor.filters.gui.RandomizePolicy.IGNORE_RANDOMIZE;
/**
* Oil Painting based on the JHLabs OilFilter
*/
public class JHOilPainting extends FilterWithParametrizedGUI {
public static final String NAME = "Oil Painting";
private static final int FASTER = 0;
private static final int BETTER = 1;
private final GroupedRangeParam brushSize = new GroupedRangeParam("Brush Size", 0, 1, 10, false);
private final RangeParam coarseness = new RangeParam("Coarseness", 2, 25, 255);
private final IntChoiceParam detailQuality = new IntChoiceParam("Detail Quality", new Value[]{
new Value("Faster", FASTER),
new Value("Better", BETTER),
}, IGNORE_RANDOMIZE);
public JHOilPainting() {
super(ShowOriginal.YES);
setParamSet(new ParamSet(
brushSize.withAdjustedRange(0.04),
coarseness,
detailQuality
));
}
@Override
public BufferedImage doTransform(BufferedImage src, BufferedImage dest) {
int brushX = brushSize.getValue(0);
int brushY = brushSize.getValue(1);
if (brushX == 0 && brushY == 0) {
return src;
}
// important to re-create because the progress tracker
// is different for big and small images
OilFilter filter = new OilFilter(NAME);
filter.setLevels(coarseness.getValue());
ResizingFilterHelper r = new ResizingFilterHelper(src);
if (r.shouldResize()) {
ScaleUpQuality scaleUpQuality;
if (detailQuality.getValue() == BETTER) {
scaleUpQuality = ScaleUpQuality.BILINEAR11;
} else if (detailQuality.getValue() == FASTER) {
scaleUpQuality = ScaleUpQuality.BILINEAR_FAST;
} else {
throw new IllegalStateException("unexpected value" + detailQuality.getValue());
}
double resizeFactor = r.getResizeFactor();
// these will determine the real running time of the filter
int downScaledBrushX = (int) (brushX / resizeFactor);
int downScaledBrushY = (int) (brushY / resizeFactor);
int resizeUnits = r.getResizeWorkUnits(scaleUpQuality);
long filterWorkAmount = downScaledBrushX * downScaledBrushY;
int filterUnits = (int) (filterWorkAmount / 4);
int workUnits = resizeUnits + filterUnits;
ProgressTracker pt = new BasicProgressTracker(NAME, workUnits);
// ProgressTracker pt = new DebugProgressTracker("Oil, brushX = " + downScaledBrushX + ", brushY = " + downScaledBrushY, workUnits);
ProgressTracker filterTracker = r.createFilterTracker(pt, filterUnits);
filter.setProgressTracker(filterTracker);
filter.setRangeX(downScaledBrushX);
filter.setRangeY(downScaledBrushY);
dest = r.invoke(scaleUpQuality, filter, pt, 0);
pt.finish();
} else {
// normal case, no resizing
filter.setRangeX(brushX);
filter.setRangeY(brushY);
dest = filter.filter(src, dest);
}
return dest;
}
@Override
public boolean excludeFromAnimation() {
return true;
}
}