/* * 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; import pixelitor.filters.gui.BooleanParam; import pixelitor.filters.gui.IntChoiceParam; import pixelitor.filters.gui.IntChoiceParam.Value; import pixelitor.filters.gui.ParamSet; import pixelitor.filters.gui.ShowOriginal; import pixelitor.filters.lookup.FastLookupOp; import pixelitor.filters.lookup.LookupFactory; import java.awt.image.BufferedImage; import java.awt.image.BufferedImageOp; import java.awt.image.LookupTable; import java.awt.image.ShortLookupTable; /** * Extract a channel from the image */ public class ExtractChannel extends FilterWithParametrizedGUI { private static final int RED_CHANNEL = 1; private static final int REMOVE_RED_CHANNEL = 2; private static final int GREEN_CHANNEL = 3; private static final int REMOVE_GREEN_CHANNEL = 4; private static final int BLUE_CHANNEL = 5; private static final int REMOVE_BLUE_CHANNEL = 6; private final IntChoiceParam channelParam = new IntChoiceParam("Channel", new Value[]{ new Value("Red", RED_CHANNEL), new Value("Remove Red", REMOVE_RED_CHANNEL), new Value("Green", GREEN_CHANNEL), new Value("Remove Green", REMOVE_GREEN_CHANNEL), new Value("Blue", BLUE_CHANNEL), new Value("Remove Blue", REMOVE_BLUE_CHANNEL), }); private final BooleanParam bwParam = new BooleanParam("Black and White", false); public ExtractChannel() { super(ShowOriginal.YES); setParamSet(new ParamSet( channelParam, bwParam)); } @Override public BufferedImage doTransform(BufferedImage src, BufferedImage dest) { int channel = channelParam.getValue(); if (bwParam.isChecked()) { dest = bwExtractChannel(src, dest, channel); } else { dest = colorExtractChannel(src, dest, channel); } return dest; } private static BufferedImage bwExtractChannel(BufferedImage src, BufferedImage dest, int channel) { RGBPixelOp rgbOp; switch (channel) { case RED_CHANNEL: rgbOp = (a, r, g, b) -> { g = r; b = r; return (a << 24) | (r << 16) | (g << 8) | b; }; break; case REMOVE_RED_CHANNEL: rgbOp = (a, r, g, b) -> { int val = (g + b) / 2; return (a << 24) | (val << 16) | (val << 8) | val; }; break; case GREEN_CHANNEL: rgbOp = (a, r, g, b) -> { r = g; b = g; return (a << 24) | (r << 16) | (g << 8) | b; }; break; case REMOVE_GREEN_CHANNEL: rgbOp = (a, r, g, b) -> { int val = (r + b) / 2; return (a << 24) | (val << 16) | (val << 8) | val; }; break; case BLUE_CHANNEL: rgbOp = (a, r, g, b) -> { r = b; g = b; return (a << 24) | (r << 16) | (g << 8) | b; }; break; case REMOVE_BLUE_CHANNEL: rgbOp = (a, r, g, b) -> { int val = (r + g) / 2; return (a << 24) | (val << 16) | (val << 8) | val; }; break; default: throw new IllegalStateException("should not het here"); } return FilterUtils.runRGBPixelOp(rgbOp, src, dest); } private static BufferedImage colorExtractChannel(BufferedImage src, BufferedImage dest, int channel) { LookupTable lookupTable; switch (channel) { case RED_CHANNEL: lookupTable = LookupFactory.createLookupForOnlyRed(); break; case REMOVE_RED_CHANNEL: lookupTable = LookupFactory.createLookupForRemoveRed(); break; case GREEN_CHANNEL: lookupTable = LookupFactory.createLookupForOnlyGreen(); break; case REMOVE_GREEN_CHANNEL: lookupTable = LookupFactory.createLookupForRemoveGreen(); break; case BLUE_CHANNEL: lookupTable = LookupFactory.createLookupForOnlyBlue(); break; case REMOVE_BLUE_CHANNEL: lookupTable = LookupFactory.createLookupForRemoveBlue(); break; default: throw new IllegalStateException("should not het here"); } BufferedImageOp filterOp = new FastLookupOp((ShortLookupTable) lookupTable); filterOp.filter(src, dest); return dest; } @Override public boolean supportsGray() { return false; } }