/*
* 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.gui;
import pixelitor.Composition;
import pixelitor.utils.ImageSwitchListener;
import pixelitor.utils.ImageUtils;
import javax.swing.*;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.image.BufferedImage;
import java.util.Objects;
import static java.awt.Color.BLUE;
import static java.awt.Color.GREEN;
import static java.awt.Color.RED;
public class HistogramsPanel extends JPanel implements ImageSwitchListener {
public static final HistogramsPanel INSTANCE = new HistogramsPanel();
private final HistogramPainter red;
private final HistogramPainter green;
private final HistogramPainter blue;
private static final int HISTOGRAM_RESOLUTION = 256;
private HistogramsPanel() {
setLayout(new BorderLayout());
red = new HistogramPainter(RED);
green = new HistogramPainter(GREEN);
blue = new HistogramPainter(BLUE);
JPanel box = new JPanel();
box.setLayout(new BoxLayout(box, BoxLayout.Y_AXIS));
box.setPreferredSize(new Dimension(256, 300));
box.setMinimumSize(new Dimension(256, 300));
box.add(red);
box.add(green);
box.add(blue);
setBorder(BorderFactory.createTitledBorder("Histograms"));
box.setBorder(BorderFactory.createLineBorder(BLUE));
JScrollPane scrollPane = new JScrollPane(box);
add(scrollPane, BorderLayout.CENTER);
}
public boolean areHistogramsShown() {
return (getParent() != null);
}
@Override
public void noOpenImageAnymore() {
red.setToNoImage();
green.setToNoImage();
blue.setToNoImage();
repaint();
}
@Override
public void newImageOpened(Composition comp) {
}
@Override
public void activeImageHasChanged(ImageComponent oldIC, ImageComponent newIC) {
updateFromCompIfShown(newIC.getComp());
}
public void updateFromCompIfShown(Composition comp) {
Objects.requireNonNull(comp);
if (!areHistogramsShown()) {
return;
}
BufferedImage image = comp.getCompositeImage();
int[] reds = new int[HISTOGRAM_RESOLUTION];
int[] blues = new int[HISTOGRAM_RESOLUTION];
int[] greens = new int[HISTOGRAM_RESOLUTION];
int[] data = ImageUtils.getPixelsAsArray(image);
for (int rgb : data) {
// int a = (rgb >>> 24) & 0xFF;
int r = (rgb >>> 16) & 0xFF;
int g = (rgb >>> 8) & 0xFF;
int b = (rgb) & 0xFF;
reds[r]++;
greens[g]++;
blues[b]++;
}
boolean useLogarithm = false;
if (useLogarithm) {
for (int i = 0; i < HISTOGRAM_RESOLUTION; i++) {
reds[i] = (int) (1000.0 * Math.log(reds[i]));
greens[i] = (int) (1000.0 * Math.log(greens[i]));
blues[i] = (int) (1000.0 * Math.log(blues[i]));
}
}
red.updateData(reds);
green.updateData(greens);
blue.updateData(blues);
repaint();
}
}