/*
* HaoRan ImageFilter Classes v0.1
* Copyright (C) 2012 Zhenjun Dai
*
* 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.
*/
package com.marshalchen.common.uimodule.ImageFilter;
/**
* �Զ�У��Ч��
* @author daizhj
*
*/
public class AutoLevelFilter implements IImageFilter{
public float Intensity = 1f;
private static float[] ComputeGamma(int[] lo, int[] md, int[] hi)
{
float[] array = new float[3];
for (int i = 0; i < 3; i++){
if (lo[i] < md[i] && md[i] < hi[i]) {
double log = Math.log1p(/*0.5, */(double) (((float) (md[i] - lo[i])) / ((float) (hi[i] - lo[i]))));
array[i] = (log > 10.0) ? ((float) 10.0) : ((log < 0.1) ? ((float) 0.1) : ((float) log));
}
else{
array[i] = 1f;
}
}
return array;
}
public int[] GetMeanColor(int[][] h)
{
float[] array = new float[3];
for (int i = 0; i < 3; i++) {
long sum1 = 0L;
long sum2 = 0L;
for (int j = 0; j < 256; j++){
sum1 += j * h[i][j];
sum2 += h[i][j];
}
array[i] = (sum2 == 0L) ? 0f : (((float) sum1) / ((float) sum2));
}
return new int[] { (((int) (array[0] + 0.5f)) & 255), (((int) (array[1] + 0.5f)) & 255), (((int) (array[2] + 0.5f)) & 255) };
}
public int[] GetPercentileColor(int[][] h, float fraction)
{
int[] array = new int[3];
for (int i = 0; i < 3; i++)
{
long sum1 = 0L;
long sum2 = 0L;
for (int j = 0; j < 256; j++) {
sum2 += h[i][j];
}
for (int k = 0; k < 256; k++) {
sum1 += h[i][k];
if (sum1 > (sum2 * fraction)) {
array[i] = k;
break;
}
}
}
return array;
}
//@Override
public Image process(Image imageIn) {
int[][] h = new int[3][256];
int[] array = new int[3];
int[] rgb = new int[] { 255, 255, 255 };
int[] bb = new int[256];
int[] gg = new int[256];
int[] rr = new int[256];
int intensity = (int) (this.Intensity * 255f);
int intensity_invert = 255 - intensity;
for (int x = 0; x < imageIn.getWidth() - 1; x++){
for (int y = 0; y < imageIn.getHeight() - 1; y++) {
h[0][imageIn.getRComponent(x, y)]++;
h[1][imageIn.getGComponent(x, y)]++;
h[2][imageIn.getBComponent(x, y)]++;
}
}
int[] percentileColor = GetPercentileColor(h, 0.005f);
int[] meanColor = GetMeanColor(h);
int[] hi = GetPercentileColor(h, 0.995f);
float[] gamma = ComputeGamma(percentileColor, meanColor, hi);
for (int i = 0; i < 3; i++){
for (int j = 0; j < 256; j++){
int[] arr = new int[3];
for (int n = 0; n < 3; n++){
float percent = j - percentileColor[n];
if (percent < 0f){
arr[n] = array[n];
}
else if ((percent + percentileColor[n]) >= hi[n]){
arr[n] = rgb[n];
}
else {
double adjust = array[n] + ((rgb[n] - array[n]) * Math.pow((double) (percent / ((float) (hi[n] - percentileColor[n]))), (double) gamma[n]));
arr[n] = (adjust > 255.0) ? ((int) 255.0) : ((adjust < 0.0) ? ((int) 0.0) : ((int) adjust));
}
}
rr[j] = arr[0];
gg[j] = arr[1];
bb[j] = arr[2];
}
}
Image clone = imageIn.clone();
int r,g,b;
for (int x = 0; x < imageIn.getWidth() - 1; x++){
for (int y = 0; y < imageIn.getHeight() - 1; y++) {
r = clone.getRComponent(x, y);
g = clone.getGComponent(x, y);
b = clone.getBComponent(x, y);
r = (r * intensity_invert + rr[r] * intensity) >> 8;
g = (g * intensity_invert + gg[g] * intensity) >> 8;
b = (b * intensity_invert + bb[b] * intensity) >> 8;
imageIn.setPixelColor(x, y, r, g, b);
}
}
return imageIn;//��ֱ��ͼģʽ��ǿ
}
}