You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
101 lines
3.4 KiB
101 lines
3.4 KiB
package com.jotuntech.sketcher.common.filter;
|
|
|
|
import com.jotuntech.sketcher.common.Pixels;
|
|
|
|
public class AutoContrastFilter implements Filter {
|
|
int[] alphaHistogram, colorHistogram;
|
|
int alphaBlackPoint, alphaWhitePoint, colorBlackPoint, colorWhitePoint, totalPixels, alphaRange, colorRange;
|
|
float maxBlackFraction, maxWhiteFraction;
|
|
|
|
public AutoContrastFilter() {
|
|
|
|
}
|
|
|
|
public void setSize(int width, int height) { }
|
|
|
|
public void setParameterA(float a) {
|
|
maxBlackFraction = a;
|
|
}
|
|
|
|
public void setParameterB(float b) {
|
|
maxWhiteFraction = b;
|
|
}
|
|
|
|
public void setParameterC(float c) { }
|
|
|
|
public boolean isPass1ReadOnly() {
|
|
return true;
|
|
}
|
|
|
|
public boolean hasPass2() {
|
|
return true;
|
|
}
|
|
|
|
public boolean isPass2Reversed() {
|
|
return false;
|
|
}
|
|
|
|
public void startPass1() {
|
|
totalPixels = 0;
|
|
alphaHistogram = new int[256];
|
|
colorHistogram = new int[256];
|
|
}
|
|
|
|
public int processPass1Pixel(int pixel) {
|
|
int alpha = Pixels.getChannel0(pixel);
|
|
if(alpha > 0) {
|
|
++alphaHistogram[alpha];
|
|
++colorHistogram[(Pixels.getChannel1(pixel) + (Pixels.getChannel2(pixel) << 1) + Pixels.getChannel3(pixel)) >> 2];
|
|
++totalPixels;
|
|
}
|
|
return pixel;
|
|
}
|
|
|
|
public void startPass2() {
|
|
int maxBlackPixels = (int) Math.ceil(maxBlackFraction * totalPixels);
|
|
int maxWhitePixels = (int) Math.ceil(maxWhiteFraction * totalPixels);
|
|
|
|
alphaBlackPoint = 0;
|
|
for(int alphaBlackPixels = 0; alphaBlackPixels + alphaHistogram[alphaBlackPoint] <= maxBlackPixels && alphaBlackPoint < alphaHistogram.length; alphaBlackPixels += alphaHistogram[alphaBlackPoint++]) { }
|
|
|
|
alphaWhitePoint = alphaHistogram.length - 1;
|
|
for(int alphaWhitePixels = 0; alphaWhitePixels + alphaHistogram[alphaWhitePoint] <= maxWhitePixels && alphaWhitePoint >= 0; alphaWhitePixels += alphaHistogram[alphaWhitePoint--]) { }
|
|
|
|
System.err.println("alphaBlackPoint = " + alphaBlackPoint);
|
|
System.err.println("alphaWhitePoint = " + alphaWhitePoint);
|
|
|
|
alphaRange = alphaWhitePoint - alphaBlackPoint;
|
|
|
|
if(alphaRange <= 0) {
|
|
alphaBlackPoint = 0;
|
|
alphaWhitePoint = 255;
|
|
alphaRange = 255;
|
|
}
|
|
|
|
colorBlackPoint = 0;
|
|
for(int colorBlackPixels = 0; colorBlackPixels + colorHistogram[colorBlackPoint] <= maxBlackPixels && colorBlackPoint < colorHistogram.length; colorBlackPixels += colorHistogram[colorBlackPoint++]) { }
|
|
|
|
colorWhitePoint = colorHistogram.length - 1;
|
|
for(int colorWhitePixels = 0; colorWhitePixels + colorHistogram[colorWhitePoint] <= maxWhitePixels && colorWhitePoint >= 0; colorWhitePixels += colorHistogram[colorWhitePoint--]) { }
|
|
|
|
System.err.println("colorBlackPoint = " + colorBlackPoint);
|
|
System.err.println("colorWhitePoint = " + colorWhitePoint);
|
|
|
|
colorRange = colorWhitePoint - colorBlackPoint;
|
|
|
|
if(colorRange <= 0) {
|
|
colorBlackPoint = 0;
|
|
colorWhitePoint = 255;
|
|
colorRange = 255;
|
|
}
|
|
}
|
|
|
|
public int processPass2Pixel(int pixel) {
|
|
int alpha = Math.min(255, Math.max(0, Pixels.getChannel0(pixel) - alphaBlackPoint) * 255 / alphaRange);
|
|
int red = Math.min(255, Math.max(0, Pixels.getChannel1(pixel) - colorBlackPoint) * 255 / colorRange);
|
|
int green = Math.min(255, Math.max(0, Pixels.getChannel2(pixel) - colorBlackPoint) * 255 / colorRange);
|
|
int blue = Math.min(255, Math.max(0, Pixels.getChannel3(pixel) - colorBlackPoint) * 255 / colorRange);
|
|
return Pixels.pack(alpha, red, green, blue);
|
|
}
|
|
|
|
}
|
|
|