/*******************************************************************************
* Copyright (c) 2016 Weasis Team and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Nicolas Roduit - initial API and implementation
*******************************************************************************/
package org.weasis.core.api.image.op;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.image.DataBuffer;
import java.awt.image.renderable.ParameterBlock;
import java.util.Hashtable;
import javax.media.jai.JAI;
import javax.media.jai.PlanarImage;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.border.TitledBorder;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import org.weasis.core.api.Messages;
import org.weasis.core.api.gui.util.JMVUtils;
import org.weasis.core.api.util.StringUtil;
public class Contrast extends JPanel {
public static final String[] sliderLabels = { "Low -127", "0", "High 127" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
public static final String[] gammaLabels = { "0.01", "1", "2" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
private GridBagLayout gridBagLayout1 = new GridBagLayout();
private JSlider jSliderContrast = new JSlider(-127, 127, 0);
private JSlider jSliderLum = new JSlider(-127, 127, 0);
private JSlider jSliderGamma = new JSlider(1, 200, 100);
private TitledBorder title1 = new TitledBorder(Messages.getString("Contrast.contrast") + StringUtil.COLON); //$NON-NLS-1$
private TitledBorder title2 = new TitledBorder(Messages.getString("Contrast.lum" + StringUtil.COLON)); //$NON-NLS-1$
private TitledBorder title3 = new TitledBorder(Messages.getString("Contrast.gamma" + StringUtil.COLON)); //$NON-NLS-1$
private JButton jButtonReset = new JButton();
private ChangeListener sliderListener = new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
updateValues();
}
};
public Contrast() {
try {
jbInit();
} catch (Exception ex) {
ex.printStackTrace();
}
}
private void jbInit() throws Exception {
this.setLayout(gridBagLayout1);
Hashtable labels = new Hashtable();
Hashtable glabels = new Hashtable();
int[] gammaVal = { 1, 100, 200 };
for (int label = -127, k = 0; label < 128; label += 127, k++) {
JLabel aLabel = new JLabel(sliderLabels[k]);
labels.put(label, aLabel);
JLabel gLabel = new JLabel(gammaLabels[k]);
glabels.put(gammaVal[k], gLabel);
}
jSliderContrast.setMajorTickSpacing(127);
jSliderContrast.setPaintTicks(true);
jSliderContrast.setLabelTable(labels);
jSliderContrast.setPaintLabels(true);
jSliderContrast.setBorder(title1);
JMVUtils.setPreferredWidth(jSliderContrast, 80);
jSliderContrast.addChangeListener(sliderListener);
jSliderLum.setMajorTickSpacing(127);
jSliderLum.setPaintTicks(true);
jSliderLum.setLabelTable(labels);
jSliderLum.setPaintLabels(true);
jSliderLum.setBorder(title2);
JMVUtils.setPreferredWidth(jSliderLum, 80);
jSliderLum.addChangeListener(sliderListener);
jSliderGamma.setMajorTickSpacing(99);
jSliderGamma.setPaintTicks(true);
jSliderGamma.setLabelTable(glabels);
jSliderGamma.setPaintLabels(true);
jSliderGamma.setBorder(title3);
JMVUtils.setPreferredWidth(jSliderGamma, 80);
jSliderGamma.addChangeListener(sliderListener);
jButtonReset.setText(Messages.getString("Contrast.reset")); //$NON-NLS-1$
jButtonReset.addActionListener(new java.awt.event.ActionListener() {
@Override
public void actionPerformed(java.awt.event.ActionEvent e) {
reset();
}
});
this.add(jSliderContrast, new GridBagConstraints(0, 0, 1, 1, 1.0, 0.0, GridBagConstraints.CENTER,
GridBagConstraints.HORIZONTAL, new Insets(0, 5, 0, 5), 0, 0));
this.add(jSliderLum, new GridBagConstraints(0, 1, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER,
GridBagConstraints.HORIZONTAL, new Insets(10, 5, 0, 5), 0, 0));
this.add(jSliderGamma, new GridBagConstraints(0, 2, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER,
GridBagConstraints.HORIZONTAL, new Insets(10, 5, 0, 5), 0, 0));
this.add(jButtonReset, new GridBagConstraints(0, 3, 1, 1, 0.0, 0.0, GridBagConstraints.EAST,
GridBagConstraints.NONE, new Insets(10, 0, 10, 20), 0, 0));
}
public final void reset() {
setSliderValues(0, 0, 100);
}
public void addSilersListener(ChangeListener sliderListener) {
jSliderContrast.addChangeListener(sliderListener);
jSliderLum.addChangeListener(sliderListener);
jSliderGamma.addChangeListener(sliderListener);
}
/** returns a 3band byte image */
public static final PlanarImage getRescaledImage(PlanarImage image, double slope, double y_int) {
if (image == null) {
return null;
}
PlanarImage dst = null;
int bands = image.getSampleModel().getNumBands();
// use a lookup table for rescaling
double[] slopes = new double[bands];
double[] y_ints = new double[bands];
for (int i = 0; i < bands; i++) {
slopes[i] = slope;
y_ints[i] = y_int;
}
// rescale from xxx to byte range
ParameterBlock pb = new ParameterBlock();
pb.addSource(image);
pb.add(slopes);
pb.add(y_ints);
dst = JAI.create("rescale", pb, null); //$NON-NLS-1$
// produce a byte image
pb = new ParameterBlock();
pb.addSource(dst);
pb.add(DataBuffer.TYPE_BYTE);
dst = JAI.create("format", pb, null); //$NON-NLS-1$
return dst;
}
private void updateValues() {
title1.setTitle(Messages.getString("Contrast.contrast") + jSliderContrast.getValue() + " "); //$NON-NLS-1$ //$NON-NLS-2$
title2.setTitle(Messages.getString("Contrast.lum") + jSliderLum.getValue() + " "); //$NON-NLS-1$ //$NON-NLS-2$
title3.setTitle(Messages.getString("Contrast.gamma") + jSliderGamma.getValue() / 100f + " "); //$NON-NLS-1$ //$NON-NLS-2$
jSliderContrast.repaint();
jSliderLum.repaint();
jSliderGamma.repaint();
}
public PlanarImage updateSlider(PlanarImage image) {
image = setBrightness(image, jSliderLum.getValue());
// image = setContrast(image, jSliderContrast.getValue());
// return setGamma(image, (float) (jSliderGamma.getValue() / 100.0));
return image;
}
public void setSliderValues(int brightness, int contrast, int gamma) {
jSliderContrast.setValue(contrast);
jSliderLum.setValue(brightness);
jSliderGamma.setValue(gamma);
}
public static PlanarImage setBrightness(PlanarImage image, int value) {
if (value == 0) {
return image;
}
double adjConstants[] = { value };
ParameterBlock pb = new ParameterBlock();
pb.addSource(image);
pb.add(adjConstants);
return JAI.create("addconst", pb, null); //$NON-NLS-1$
}
// public static PlanarImage setContrast(PlanarImage image, int value) {
// if (value == 0) {
// return image;
// }
// byte[] lut = new byte[256];
// for (int i = 0; i < 256; i++) {
// double scale = i + (value * Math.sin((0.0245 * i) - 3.14));
// if (scale > 255.0) {
// scale = 255.0;
// }
// else if (scale < 0.0) {
// scale = 0.0;
// }
//
// lut[i] = (byte) scale;
// }
// return PseudoColorOp.applyLookupTable(image, new LookupTableJAI(lut));
// }
//
// public static PlanarImage setGamma(PlanarImage image, float value) {
// byte lut[][] = createGammaLUT(value, image.getNumBands());
// return PseudoColorOp.applyLookupTable(image, new LookupTableJAI(lut));
// }
private static byte[][] createGammaLUT(float f, int nbBand) {
byte lut[][] = new byte[nbBand][256];
for (int i = 0; i < 256; i++) {
int j = (int) (Math.pow(i / 255F, f) * 255D);
if (j > 255) {
j = 255;
} else if (j < 0) {
j = 0;
}
for (int k = 0; k < lut.length; k++) {
lut[k][i] = (byte) j;
}
}
return lut;
}
}