// Catalano Imaging Library
// The Catalano Framework
//
// Copyright © Diego Catalano, 2012-2016
// diego.catalano at live.com
//
//
//    This library is free software; you can redistribute it and/or
//    modify it under the terms of the GNU Lesser General Public
//    License as published by the Free Software Foundation; either
//    version 2.1 of the License, or (at your option) any later version.
//
//    This library 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
//    Lesser General Public License for more details.
//
//    You should have received a copy of the GNU Lesser General Public
//    License along with this library; if not, write to the Free Software
//    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
//

package Catalano.Imaging.Filters;

import Catalano.Imaging.FastBitmap;
import Catalano.Imaging.IApplyInPlace;

/**
 * Stretch histogram across the entire gray level range, which has the effect of increasing the contrast of a low contrast image.
 * 
If a stretch is desired over a smaller range, different MAX and MIN values can be specified. * @see Computer Imaging - Scott E. Umbaugh - Chapter 8 - p. 353 * @author Diego Catalano */ public class HistogramStretch implements IApplyInPlace{ private int max, min; /** * Initialize a new instance of the HistogramStretch class. */ public HistogramStretch() { this.max = 255; this.min = 0; } /** * Initialize a new instance of the HistogramStretch class. * @param min Correspond to the minimum gray level values possible. Range [0..255]. * @param max Correspond to the maximum gray level values possible. Range [0..255]. */ public HistogramStretch(int min, int max) { this.min = Math.max(min, 0); this.max = Math.min(max, 255); } /** * Maximum gray level. * @return Maximum. */ public int getMax() { return max; } /** * Maximum gray level. * @param max Maximum. */ public void setMax(int max) { this.max = Math.min(max, 255); } /** * Minimum gray level. * @return Minimum. */ public int getMin() { return min; } /** * Minimum gray level. * @param min Minimum. */ public void setMin(int min) { this.min = Math.max(min, 0); } @Override public void applyInPlace(FastBitmap fastBitmap){ int size = fastBitmap.getSize(); if (fastBitmap.isGrayscale()) { float grayMax = getMaxGray(fastBitmap); float grayMin = getMinGray(fastBitmap); float gray; float stretch; for (int x = 0; x < size; x++) { gray = fastBitmap.getGray(x); stretch = (((gray - grayMin)/(grayMax - grayMin)) * (max - min)) + min; fastBitmap.setGray(x, (int)stretch); } } else{ float[] colorMax = getMaxRGB(fastBitmap); float[] colorMin = getMinRGB(fastBitmap); float r,g,b; float stretchRed,stretchGreen,stretchBlue; for (int x = 0; x < size; x++) { r = fastBitmap.getRed(x); g = fastBitmap.getGreen(x); b = fastBitmap.getBlue(x); stretchRed = (((r - colorMin[0])/(colorMax[0] - colorMin[0])) * (max - min)) + min; stretchGreen = (((g - colorMin[1])/(colorMax[1] - colorMin[1])) * (max - min)) + min; stretchBlue = (((b - colorMin[2])/(colorMax[2] - colorMin[2])) * (max - min)) + min; fastBitmap.setRGB(x, (int)stretchRed, (int)stretchGreen, (int)stretchBlue); } } } private int getMaxGray(FastBitmap fb){ int size = fb.getSize(); int max = 0; for (int i = 0; i < size; i++) if (fb.getGray(i) > max) max = fb.getGray(i); return max; } private int getMinGray(FastBitmap fb){ int size = fb.getSize(); int min = 255; for (int i = 0; i < size; i++) if (fb.getGray(i) < min) min = fb.getGray(i); return min; } private float[] getMaxRGB(FastBitmap fb){ float[] color = new float[3]; int size = fb.getSize(); int maxR = 0, maxG = 0, maxB = 0; for (int i = 0; i < size; i++){ if (fb.getRed(i) > maxR) maxR = fb.getRed(i); if (fb.getGreen(i) > maxG) maxG = fb.getGreen(i); if (fb.getBlue(i) > maxB) maxB = fb.getBlue(i); } color[0] = (float)maxR; color[1] = (float)maxG; color[2] = (float)maxB; return color; } private float[] getMinRGB(FastBitmap fb){ float[] color = new float[3]; int size = fb.getSize(); int minR = 255, minG = 255, minB = 255; for (int i = 0; i < size; i++){ if (fb.getRed(i) < minR) minR = fb.getRed(i); if (fb.getGreen(i) < minG) minG = fb.getGreen(i); if (fb.getBlue(i) < minB) minB = fb.getBlue(i); } color[0] = (float)minR; color[1] = (float)minG; color[2] = (float)minB; return color; } }

Ads help maintain this website.