Fixed some bugs and framework for the image filters
This commit is contained in:
parent
9f839fd803
commit
1bde5a6977
13 changed files with 342 additions and 266 deletions
|
|
@ -65,7 +65,7 @@ public abstract class ImageFilterProcessor {
|
||||||
// converts the img to raw data
|
// converts the img to raw data
|
||||||
int[][][] data = convertToArray(img, cols, rows);
|
int[][][] data = convertToArray(img, cols, rows);
|
||||||
//processes the image
|
//processes the image
|
||||||
data = process(data, cols, rows);
|
process(data);
|
||||||
//converts back the image
|
//converts back the image
|
||||||
return convertToImage(data, data[0].length, data.length);
|
return convertToImage(data, data[0].length, data.length);
|
||||||
}
|
}
|
||||||
|
|
@ -147,11 +147,21 @@ public abstract class ImageFilterProcessor {
|
||||||
return img;
|
return img;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Runs the image thrue the processor
|
||||||
|
* @param data The raw image to apply the effect to
|
||||||
|
*/
|
||||||
|
public void process(final int[][][] data){
|
||||||
|
process(data, 0, 0, data[0].length, data.length);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The underlying effect is run here
|
* The underlying effect is run here
|
||||||
* @param data The raw image to apply the effect to
|
* @param data The raw image to apply the effect to
|
||||||
* @param cols Columns of the image
|
* @param startX is the x pixel of the image to start from
|
||||||
* @param rows Rows of the image
|
* @param startY is the y pixel of the image to start from
|
||||||
|
* @param stopX is the x pixel of the image to stop
|
||||||
|
* @param stopY is the y pixel of the image to stop
|
||||||
*/
|
*/
|
||||||
public abstract int[][][] process(final int[][][] data, int cols, int rows);
|
public abstract void process(final int[][][] data, int startX, int startY, int stopX, int stopY);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,18 +6,35 @@ package zutil.image;
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class ImageUtil {
|
public class ImageUtil {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the peek value in the image
|
* Returns the peek value in the image
|
||||||
*
|
*
|
||||||
* @param data The image data
|
* @param data The image data
|
||||||
* @param cols The number of columns
|
* @param startX is the x pixel of the image to start from
|
||||||
* @param rows The number of rows
|
* @param startY is the y pixel of the image to start from
|
||||||
|
* @param stopX is the x pixel of the image to stop
|
||||||
|
* @param stopY is the y pixel of the image to stop
|
||||||
* @return The peak value of the image
|
* @return The peak value of the image
|
||||||
*/
|
*/
|
||||||
public static int peakValue(int[][][] data, int cols, int rows) {
|
public static int peakValue(int[][][] data) {
|
||||||
|
return peakValue(data, 0, 0, data[0].length, data.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the peek value in the image
|
||||||
|
*
|
||||||
|
* @param data The image data
|
||||||
|
* @param startX is the x pixel of the image to start from
|
||||||
|
* @param startY is the y pixel of the image to start from
|
||||||
|
* @param stopX is the x pixel of the image to stop
|
||||||
|
* @param stopY is the y pixel of the image to stop
|
||||||
|
* @return The peak value of the image
|
||||||
|
*/
|
||||||
|
public static int peakValue(int[][][] data, int startX, int startY, int stopX, int stopY) {
|
||||||
int peak = 0;
|
int peak = 0;
|
||||||
for(int y=0; y<rows ;y++){
|
for(int y=startY; y<stopY ;y++){
|
||||||
for(int x=0; x<cols ;x++){
|
for(int x=startX; x<stopX ;x++){
|
||||||
if(data[y][x][1] > peak) peak = data[y][x][1];
|
if(data[y][x][1] > peak) peak = data[y][x][1];
|
||||||
if(data[y][x][2] > peak) peak = data[y][x][2];
|
if(data[y][x][2] > peak) peak = data[y][x][2];
|
||||||
if(data[y][x][3] > peak) peak = data[y][x][3];
|
if(data[y][x][3] > peak) peak = data[y][x][3];
|
||||||
|
|
@ -30,13 +47,15 @@ public class ImageUtil {
|
||||||
* Normalizes the image data by the given scale
|
* Normalizes the image data by the given scale
|
||||||
*
|
*
|
||||||
* @param data The image data
|
* @param data The image data
|
||||||
* @param cols The number of columns
|
* @param startX is the x pixel of the image to start from
|
||||||
* @param rows The number of rows
|
* @param startY is the y pixel of the image to start from
|
||||||
|
* @param stopX is the x pixel of the image to stop
|
||||||
|
* @param stopY is the y pixel of the image to stop
|
||||||
* @param scale The scale to normalize the image by
|
* @param scale The scale to normalize the image by
|
||||||
*/
|
*/
|
||||||
public static void normalize(int[][][] data, int cols, int rows, double scale) {
|
public static void normalize(int[][][] data, int startX, int startY, int stopX, int stopY, double scale) {
|
||||||
for(int y=0; y<rows ;y++){
|
for(int y=startY; y<stopY ;y++){
|
||||||
for(int x=0; x<cols ;x++){
|
for(int x=startX; x<stopX ;x++){
|
||||||
data[y][x][1] = (int)(data[y][x][1] * scale);
|
data[y][x][1] = (int)(data[y][x][1] * scale);
|
||||||
data[y][x][2] = (int)(data[y][x][2] * scale);
|
data[y][x][2] = (int)(data[y][x][2] * scale);
|
||||||
data[y][x][3] = (int)(data[y][x][3] * scale);
|
data[y][x][3] = (int)(data[y][x][3] * scale);
|
||||||
|
|
@ -49,13 +68,15 @@ public class ImageUtil {
|
||||||
*
|
*
|
||||||
* @param output The output data array
|
* @param output The output data array
|
||||||
* @param data The image data
|
* @param data The image data
|
||||||
* @param cols The number of columns
|
* @param startX is the x pixel of the image to start from
|
||||||
* @param rows The number of rows
|
* @param startY is the y pixel of the image to start from
|
||||||
|
* @param stopX is the x pixel of the image to stop
|
||||||
|
* @param stopY is the y pixel of the image to stop
|
||||||
* @param scale The scale to normalize the image by
|
* @param scale The scale to normalize the image by
|
||||||
*/
|
*/
|
||||||
public static void normalize(int[][][] output, int[][][] data, int cols, int rows, double scale) {
|
public static void normalize(int[][][] output, int[][][] data, int startX, int startY, int stopX, int stopY, double scale) {
|
||||||
for(int y=0; y<rows ;y++){
|
for(int y=startY; y<stopY ;y++){
|
||||||
for(int x=0; x<cols ;x++){
|
for(int x=startX; x<stopX ;x++){
|
||||||
output[y][x][1] = (int)(data[y][x][1] * scale);
|
output[y][x][1] = (int)(data[y][x][1] * scale);
|
||||||
output[y][x][2] = (int)(data[y][x][2] * scale);
|
output[y][x][2] = (int)(data[y][x][2] * scale);
|
||||||
output[y][x][3] = (int)(data[y][x][3] * scale);
|
output[y][x][3] = (int)(data[y][x][3] * scale);
|
||||||
|
|
@ -64,19 +85,21 @@ public class ImageUtil {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the rms value of the image
|
* Returns the RMS value of the image
|
||||||
* (The RMS value is a measure of the width of the color distribution.)
|
* (The RMS value is a measure of the width of the color distribution.)
|
||||||
*
|
*
|
||||||
* @param data The image data
|
* @param data is the image data
|
||||||
* @param cols The number of columns
|
* @param startX is the x pixel of the image to start from
|
||||||
* @param rows The number of rows
|
* @param startY is the y pixel of the image to start from
|
||||||
* @return The rms value for the image
|
* @param stopX is the x pixel of the image to stop
|
||||||
|
* @param stopY is the y pixel of the image to stop
|
||||||
|
* @return The RMS value for the image
|
||||||
*/
|
*/
|
||||||
public static int rms(int[][][] data, int cols, int rows){
|
public static int rms(int[][][] data, int startX, int startY, int stopX, int stopY){
|
||||||
int pixelCount = 0;
|
int pixelCount = 0;
|
||||||
long accum = 0;
|
long accum = 0;
|
||||||
for(int y=0; y <rows ;y++){
|
for(int y=startY; y <stopY ;y++){
|
||||||
for(int x=0; x<cols ;x++){
|
for(int x=startX; x<stopX ;x++){
|
||||||
accum += data[y][x][1] * data[y][x][1];
|
accum += data[y][x][1] * data[y][x][1];
|
||||||
accum += data[y][x][2] * data[y][x][2];
|
accum += data[y][x][2] * data[y][x][2];
|
||||||
accum += data[y][x][3] * data[y][x][3];
|
accum += data[y][x][3] * data[y][x][3];
|
||||||
|
|
@ -92,13 +115,15 @@ public class ImageUtil {
|
||||||
* Multiplies the given image data by the given value
|
* Multiplies the given image data by the given value
|
||||||
*
|
*
|
||||||
* @param data The image data
|
* @param data The image data
|
||||||
* @param cols The number of columns
|
* @param startX is the x pixel of the image to start from
|
||||||
* @param rows The number of rows
|
* @param startY is the y pixel of the image to start from
|
||||||
|
* @param stopX is the x pixel of the image to stop
|
||||||
|
* @param stopY is the y pixel of the image to stop
|
||||||
* @param scale The number to scale the image by
|
* @param scale The number to scale the image by
|
||||||
*/
|
*/
|
||||||
public static void scale(int[][][] data, int cols, int rows, double scale){
|
public static void scale(int[][][] data, int startX, int startY, int stopX, int stopY, double scale){
|
||||||
for(int y=0; y<rows ;y++){
|
for(int y=startY; y<stopY ;y++){
|
||||||
for(int x=0; x<cols ;x++){
|
for(int x=startX; x<stopX ;x++){
|
||||||
data[y][x][1] *= scale;
|
data[y][x][1] *= scale;
|
||||||
data[y][x][2] *= scale;
|
data[y][x][2] *= scale;
|
||||||
data[y][x][3] *= scale;
|
data[y][x][3] *= scale;
|
||||||
|
|
@ -110,15 +135,27 @@ public class ImageUtil {
|
||||||
* Returns the mean value of the given image data
|
* Returns the mean value of the given image data
|
||||||
*
|
*
|
||||||
* @param data The image data
|
* @param data The image data
|
||||||
* @param cols The column count
|
|
||||||
* @param rows The row count
|
|
||||||
* @return The mean value of the image
|
* @return The mean value of the image
|
||||||
*/
|
*/
|
||||||
public static int meanValue(int[][][] data,int cols, int rows){
|
public static int meanValue(int[][][] data){
|
||||||
|
return meanValue(data, 0, 0, data[0].length, data.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the mean value of the given image data
|
||||||
|
*
|
||||||
|
* @param data The image data
|
||||||
|
* @param startX is the x pixel of the image to start from
|
||||||
|
* @param startY is the y pixel of the image to start from
|
||||||
|
* @param stopX is the x pixel of the image to stop
|
||||||
|
* @param stopY is the y pixel of the image to stop
|
||||||
|
* @return The mean value of the image
|
||||||
|
*/
|
||||||
|
public static int meanValue(int[][][] data, int startX, int startY, int stopX, int stopY){
|
||||||
int pixelCount = 0;
|
int pixelCount = 0;
|
||||||
long accum = 0;
|
long accum = 0;
|
||||||
for(int y=0; y<rows ;y++){
|
for(int y=startY; y<stopY ;y++){
|
||||||
for(int x=0; x<cols ;x++){
|
for(int x=startX; x<stopX ;x++){
|
||||||
accum += data[y][x][1];
|
accum += data[y][x][1];
|
||||||
accum += data[y][x][2];
|
accum += data[y][x][2];
|
||||||
accum += data[y][x][3];
|
accum += data[y][x][3];
|
||||||
|
|
@ -133,13 +170,15 @@ public class ImageUtil {
|
||||||
* Adds the mean value to the image data
|
* Adds the mean value to the image data
|
||||||
*
|
*
|
||||||
* @param data The image data
|
* @param data The image data
|
||||||
* @param cols The number of columns
|
* @param startX is the x pixel of the image to start from
|
||||||
* @param rows The number of rows
|
* @param startY is the y pixel of the image to start from
|
||||||
|
* @param stopX is the x pixel of the image to stop
|
||||||
|
* @param stopY is the y pixel of the image to stop
|
||||||
* @param mean The mean value
|
* @param mean The mean value
|
||||||
*/
|
*/
|
||||||
public static void addMeanValue(int[][][] data,int cols, int rows, int mean){
|
public static void addMeanValue(int[][][] data, int startX, int startY, int stopX, int stopY, int mean){
|
||||||
for(int y=0; y<rows ;y++){
|
for(int y=startY; y<stopY ;y++){
|
||||||
for(int x=0; x<cols ;x++){
|
for(int x=startX; x<stopX ;x++){
|
||||||
data[y][x][1] += mean;
|
data[y][x][1] += mean;
|
||||||
data[y][x][2] += mean;
|
data[y][x][2] += mean;
|
||||||
data[y][x][3] += mean;
|
data[y][x][3] += mean;
|
||||||
|
|
@ -191,21 +230,48 @@ public class ImageUtil {
|
||||||
* Copies the given array to a new one that it returns
|
* Copies the given array to a new one that it returns
|
||||||
*
|
*
|
||||||
* @param data The data to duplicate
|
* @param data The data to duplicate
|
||||||
* @param cols The amount of columns
|
* @return an copy of the array
|
||||||
* @param rows The amount of rows
|
*/
|
||||||
|
public static int[][][] copyArray(int[][][] data){
|
||||||
|
return copyArray(data, 0, 0, data[0].length, data.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copies the given array to a new one that it returns
|
||||||
|
*
|
||||||
|
* @param data The data to duplicate
|
||||||
|
* @param startX is the x pixel of the image to start from
|
||||||
|
* @param startY is the y pixel of the image to start from
|
||||||
|
* @param stopX is the x pixel of the image to stop
|
||||||
|
* @param stopY is the y pixel of the image to stop
|
||||||
* @return The array copy
|
* @return The array copy
|
||||||
*/
|
*/
|
||||||
public static int[][][] copyArray(int[][][] data,int cols,int rows){
|
public static int[][][] copyArray(int[][][] data, int startX, int startY, int stopX, int stopY){
|
||||||
int[][][] copy = new int[rows][cols][4];
|
int[][][] copy = new int[data.length][data[0].length][4];
|
||||||
for(int y=0; y<rows ;y++){
|
return copyArray(data, copy, startX, startY, stopX, stopY);
|
||||||
for(int x=0; x<cols ;x++){
|
}
|
||||||
copy[y][x][0] = data[y][x][0];
|
|
||||||
copy[y][x][1] = data[y][x][1];
|
/**
|
||||||
copy[y][x][2] = data[y][x][2];
|
* Copies the given array to a new one that it returns
|
||||||
copy[y][x][3] = data[y][x][3];
|
*
|
||||||
|
* @param data The data to duplicate
|
||||||
|
* @param dest is the array to copy the data to
|
||||||
|
* @param startX is the x pixel of the image to start from
|
||||||
|
* @param startY is the y pixel of the image to start from
|
||||||
|
* @param stopX is the x pixel of the image to stop
|
||||||
|
* @param stopY is the y pixel of the image to stop
|
||||||
|
* @return the dest array
|
||||||
|
*/
|
||||||
|
public static int[][][] copyArray(int[][][] data, int[][][] dest, int startX, int startY, int stopX, int stopY){
|
||||||
|
for(int y=startY; y<stopY ;y++){
|
||||||
|
for(int x=startX; x<stopX ;x++){
|
||||||
|
dest[y][x][0] = data[y][x][0];
|
||||||
|
dest[y][x][1] = data[y][x][1];
|
||||||
|
dest[y][x][2] = data[y][x][2];
|
||||||
|
dest[y][x][3] = data[y][x][3];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return copy;
|
return dest;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -213,15 +279,17 @@ public class ImageUtil {
|
||||||
* are in the range 0-255
|
* are in the range 0-255
|
||||||
*
|
*
|
||||||
* @param data The image data
|
* @param data The image data
|
||||||
* @param cols The amount of columns
|
* @param startX is the x pixel of the image to start from
|
||||||
* @param rows The amount of rows
|
* @param startY is the y pixel of the image to start from
|
||||||
|
* @param stopX is the x pixel of the image to stop
|
||||||
|
* @param stopY is the y pixel of the image to stop
|
||||||
*/
|
*/
|
||||||
public static void clip(int[][][] data, int cols, int rows){
|
public static void clip(int[][][] data, int startX, int startY, int stopX, int stopY){
|
||||||
for(int y=0; y<rows ;y++){
|
for(int y=startY; y<stopY ;y++){
|
||||||
for(int x=0; x<cols ;x++){
|
for(int x=startX; x<stopX ;x++){
|
||||||
data[y][x][1] = clip(data[y][x][1]);
|
data[y][x][1] = clip(data[y][x][1]);
|
||||||
data[y][x][1] = clip(data[y][x][2]);
|
data[y][x][2] = clip(data[y][x][2]);
|
||||||
data[y][x][1] = clip(data[y][x][3]);
|
data[y][x][3] = clip(data[y][x][3]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -28,67 +28,64 @@ public class BlurFilter extends ImageFilterProcessor{
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int[][][] process(final int[][][] data, int cols, int rows) {
|
public void process(final int[][][] data, int startX, int startY, int stopX, int stopY) {
|
||||||
int inputPeak = ImageUtil.peakValue(data, cols, rows);
|
int inputPeak = ImageUtil.peakValue(data);
|
||||||
|
|
||||||
int[][][] output = new int[rows][cols][4];
|
int[][][] tmpData = new int[data.length][data[0].length][4];
|
||||||
int[][][] tmpData = ImageUtil.copyArray(data, cols, rows);
|
|
||||||
//Perform the convolution one or more times in succession
|
//Perform the convolution one or more times in succession
|
||||||
int redSum, greenSum, blueSum, outputPeak;
|
int redSum, greenSum, blueSum, outputPeak;
|
||||||
for(int i=0; i<blurValue ;i++){
|
for(int i=0; i<blurValue ;i++){
|
||||||
//Iterate on each pixel as a registration point.
|
//Iterate on each pixel as a registration point.
|
||||||
for(int y=0; y<rows ;y++){
|
for(int y=startY; y<stopY ;y++){
|
||||||
setProgress(ZMath.percent(0, (blurValue-1)*(rows-2), i*(rows-2)+y));
|
setProgress(ZMath.percent(0, (blurValue-1)*(stopY-startY-2), i*(stopY-startY-2)+y));
|
||||||
for(int x=0; x<cols ;x++){
|
for(int x=startX; x<stopX ;x++){
|
||||||
if(x == 0 || x == cols-1 || y == 0 || y == rows-1){
|
if(x == 0 || x == data[0].length-1 || y == 0 || y == data.length-1){
|
||||||
redSum = tmpData[y][x][1] * 9;
|
redSum = data[y][x][1] * 9;
|
||||||
greenSum = tmpData[y][x][2] * 9;
|
greenSum = data[y][x][2] * 9;
|
||||||
blueSum = tmpData[y][x][3] * 9;
|
blueSum = data[y][x][3] * 9;
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
redSum =
|
redSum =
|
||||||
tmpData[y - 1][x - 1][1] +
|
data[y - 1][x - 1][1] +
|
||||||
tmpData[y - 1][x - 0][1] +
|
data[y - 1][x - 0][1] +
|
||||||
tmpData[y - 1][x + 1][1] +
|
data[y - 1][x + 1][1] +
|
||||||
tmpData[y - 0][x - 1][1] +
|
data[y - 0][x - 1][1] +
|
||||||
tmpData[y - 0][x - 0][1] +
|
data[y - 0][x - 0][1] +
|
||||||
tmpData[y - 0][x + 1][1] +
|
data[y - 0][x + 1][1] +
|
||||||
tmpData[y + 1][x - 1][1] +
|
data[y + 1][x - 1][1] +
|
||||||
tmpData[y + 1][x - 0][1] +
|
data[y + 1][x - 0][1] +
|
||||||
tmpData[y + 1][x + 1][1];
|
data[y + 1][x + 1][1];
|
||||||
greenSum =
|
greenSum =
|
||||||
tmpData[y - 1][x - 1][2] +
|
data[y - 1][x - 1][2] +
|
||||||
tmpData[y - 1][x - 0][2] +
|
data[y - 1][x - 0][2] +
|
||||||
tmpData[y - 1][x + 1][2] +
|
data[y - 1][x + 1][2] +
|
||||||
tmpData[y - 0][x - 1][2] +
|
data[y - 0][x - 1][2] +
|
||||||
tmpData[y - 0][x - 0][2] +
|
data[y - 0][x - 0][2] +
|
||||||
tmpData[y - 0][x + 1][2] +
|
data[y - 0][x + 1][2] +
|
||||||
tmpData[y + 1][x - 1][2] +
|
data[y + 1][x - 1][2] +
|
||||||
tmpData[y + 1][x - 0][2] +
|
data[y + 1][x - 0][2] +
|
||||||
tmpData[y + 1][x + 1][2];
|
data[y + 1][x + 1][2];
|
||||||
blueSum =
|
blueSum =
|
||||||
tmpData[y - 1][x - 1][3] +
|
data[y - 1][x - 1][3] +
|
||||||
tmpData[y - 1][x - 0][3] +
|
data[y - 1][x - 0][3] +
|
||||||
tmpData[y - 1][x + 1][3] +
|
data[y - 1][x + 1][3] +
|
||||||
tmpData[y - 0][x - 1][3] +
|
data[y - 0][x - 1][3] +
|
||||||
tmpData[y - 0][x - 0][3] +
|
data[y - 0][x - 0][3] +
|
||||||
tmpData[y - 0][x + 1][3] +
|
data[y - 0][x + 1][3] +
|
||||||
tmpData[y + 1][x - 1][3] +
|
data[y + 1][x - 1][3] +
|
||||||
tmpData[y + 1][x - 0][3] +
|
data[y + 1][x - 0][3] +
|
||||||
tmpData[y + 1][x + 1][3];
|
data[y + 1][x + 1][3];
|
||||||
}
|
}
|
||||||
output[y][x][0] = tmpData[y][x][0];
|
tmpData[y][x][0] = data[y][x][0];
|
||||||
output[y][x][1] = redSum;
|
tmpData[y][x][1] = redSum;
|
||||||
output[y][x][2] = greenSum;
|
tmpData[y][x][2] = greenSum;
|
||||||
output[y][x][3] = blueSum;
|
tmpData[y][x][3] = blueSum;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// getting the new peak value and normalizing the image
|
// getting the new peak value and normalizing the image
|
||||||
outputPeak = ImageUtil.peakValue(output, cols, rows);
|
outputPeak = ImageUtil.peakValue(tmpData);
|
||||||
ImageUtil.normalize(tmpData, output, cols, rows, ((double)inputPeak)/outputPeak );
|
ImageUtil.normalize(data, tmpData, startX, startY, stopX, stopY, ((double)inputPeak)/outputPeak );
|
||||||
}
|
}
|
||||||
|
|
||||||
return tmpData;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -52,7 +52,7 @@ public class ColorIntensityFilter extends ImageFilterProcessor{
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int[][][] process(final int[][][] data, int cols, int rows) {
|
public void process(final int[][][] data, int startX, int startY, int stopX, int stopY) {
|
||||||
// making sure the scales are right
|
// making sure the scales are right
|
||||||
if(redScale > 100) redScale = 100;
|
if(redScale > 100) redScale = 100;
|
||||||
else if(redScale < 0) redScale = 0;
|
else if(redScale < 0) redScale = 0;
|
||||||
|
|
@ -62,29 +62,26 @@ public class ColorIntensityFilter extends ImageFilterProcessor{
|
||||||
|
|
||||||
if(blueScale > 100) blueScale = 100;
|
if(blueScale > 100) blueScale = 100;
|
||||||
else if(blueScale < 0) blueScale = 0;
|
else if(blueScale < 0) blueScale = 0;
|
||||||
|
|
||||||
int[][][] output = new int[rows][cols][4];
|
|
||||||
|
|
||||||
// Applying the color intensity to the image
|
// Applying the color intensity to the image
|
||||||
for(int y=0; y<rows ;y++){
|
for(int y=startY; y<stopY ;y++){
|
||||||
setProgress(ZMath.percent(0, rows-1, y));
|
setProgress(ZMath.percent(0, stopY-startY-1, y));
|
||||||
for(int x=0; x<cols ;x++){
|
for(int x=startX; x<stopX ;x++){
|
||||||
if(!invert){
|
if(!invert){
|
||||||
// inversion
|
// inversion
|
||||||
output[y][x][0] = data[y][x][0];
|
data[y][x][0] = data[y][x][0];
|
||||||
output[y][x][1] = 255 - data[y][x][1] * redScale/100;
|
data[y][x][1] = 255 - data[y][x][1] * redScale/100;
|
||||||
output[y][x][2] = 255 - data[y][x][2] * greenScale/100;
|
data[y][x][2] = 255 - data[y][x][2] * greenScale/100;
|
||||||
output[y][x][3] = 255 - data[y][x][3] * blueScale/100;
|
data[y][x][3] = 255 - data[y][x][3] * blueScale/100;
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
output[y][x][0] = data[y][x][0];
|
data[y][x][0] = data[y][x][0];
|
||||||
output[y][x][1] = data[y][x][1] * redScale/100;
|
data[y][x][1] = data[y][x][1] * redScale/100;
|
||||||
output[y][x][2] = data[y][x][2] * greenScale/100;
|
data[y][x][2] = data[y][x][2] * greenScale/100;
|
||||||
output[y][x][3] = data[y][x][3] * blueScale/100;
|
data[y][x][3] = data[y][x][3] * blueScale/100;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return output;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -30,18 +30,14 @@ public class ContrastBrightnessFilter extends ImageFilterProcessor{
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int[][][] process(final int[][][] data, int cols, int rows) {
|
public void process(final int[][][] data, int startX, int startY, int stopX, int stopY) {
|
||||||
int mean = ImageUtil.meanValue(data, cols, rows);
|
int mean = ImageUtil.meanValue(data);
|
||||||
|
|
||||||
int[][][] output = ImageUtil.copyArray(data, cols, rows);
|
ImageUtil.addMeanValue(data, startX, startY, stopX, stopY, mean*(-1));
|
||||||
|
ImageUtil.scale(data, startX, startY, stopX, stopY, contrast);
|
||||||
ImageUtil.addMeanValue(output, cols, rows, mean*(-1));
|
ImageUtil.addMeanValue(data, startX, startY, stopX, stopY, (int)(brightness*mean));
|
||||||
ImageUtil.scale(output, cols, rows, contrast);
|
|
||||||
ImageUtil.addMeanValue(output, cols, rows, (int)(brightness*mean));
|
|
||||||
|
|
||||||
ImageUtil.clip(output ,cols, rows);
|
ImageUtil.clip(data , startX, startY, stopX, stopY);
|
||||||
|
|
||||||
return output;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -38,36 +38,32 @@ public class DitheringFilter extends ImageFilterProcessor{
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int[][][] process(final int[][][] data, int cols, int rows) {
|
public void process(final int[][][] data, int startX, int startY, int stopX, int stopY) {
|
||||||
int error, index;
|
int error, index;
|
||||||
int[] currentPixel;
|
int[] currentPixel;
|
||||||
|
|
||||||
int[][][] output = ImageUtil.copyArray(data, cols, rows);
|
|
||||||
|
|
||||||
for(int y=0; y<rows ;y++){
|
for(int y=startY; y<stopY ;y++){
|
||||||
setProgress(ZMath.percent(0, rows-1, y));
|
setProgress(ZMath.percent(0, stopY-startY-1, y));
|
||||||
for(int x=0; x<cols ;x++){
|
for(int x=startX; x<stopX ;x++){
|
||||||
currentPixel = output[y][x];
|
currentPixel = data[y][x];
|
||||||
index = findNearestColor(currentPixel, palette);
|
index = findNearestColor(currentPixel, palette);
|
||||||
output[y][x] = palette[index];
|
data[y][x] = palette[index];
|
||||||
|
|
||||||
for (int i = 1; i < 4; i++) {
|
for (int i = 1; i < 4; i++) {
|
||||||
error = currentPixel[i] - palette[index][i];
|
error = currentPixel[i] - palette[index][i];
|
||||||
if (x + 1 < cols) {
|
if (x + 1 < data[0].length) {
|
||||||
output[y+0][x+1][i] = ImageUtil.clip( output[y+0][x+1][i] + (error*7)/16 );
|
data[y+0][x+1][i] = ImageUtil.clip( data[y+0][x+1][i] + (error*7)/16 );
|
||||||
}
|
}
|
||||||
if (y + 1 < rows) {
|
if (y + 1 < data.length) {
|
||||||
if (x - 1 > 0)
|
if (x - 1 > 0)
|
||||||
output[y+1][x-1][i] = ImageUtil.clip( output[y+1][x-1][i] + (error*3)/16 );
|
data[y+1][x-1][i] = ImageUtil.clip( data[y+1][x-1][i] + (error*3)/16 );
|
||||||
output[y+1][x+0][i] = ImageUtil.clip( output[y+1][x+0][i] + (error*5)/16 );
|
data[y+1][x+0][i] = ImageUtil.clip( data[y+1][x+0][i] + (error*5)/16 );
|
||||||
if (x + 1 < cols)
|
if (x + 1 < data[0].length)
|
||||||
output[y+1][x+1][i] = ImageUtil.clip( output[y+1][x+1][i] + (error*1)/16 );
|
data[y+1][x+1][i] = ImageUtil.clip( data[y+1][x+1][i] + (error*1)/16 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return output;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int findNearestColor(int[] color, int[][] palette) {
|
private static int findNearestColor(int[] color, int[][] palette) {
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ import java.awt.Rectangle;
|
||||||
import java.awt.image.BufferedImage;
|
import java.awt.image.BufferedImage;
|
||||||
|
|
||||||
import zutil.image.ImageFilterProcessor;
|
import zutil.image.ImageFilterProcessor;
|
||||||
|
import zutil.image.ImageUtil;
|
||||||
import zutil.math.ZMath;
|
import zutil.math.ZMath;
|
||||||
|
|
||||||
public class FaceDetectionFilter extends ImageFilterProcessor{
|
public class FaceDetectionFilter extends ImageFilterProcessor{
|
||||||
|
|
@ -13,35 +14,37 @@ public class FaceDetectionFilter extends ImageFilterProcessor{
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int[][][] process(int[][][] data, int cols, int rows) {
|
public void process(int[][][] data, int startX, int startY, int stopX, int stopY) {
|
||||||
int[][][] IRgBy = convertARGBToIRgBy(data, cols, rows);
|
int[][][] IRgBy = convertARGBToIRgBy(data, startX, startY, stopX, stopY);
|
||||||
|
|
||||||
MedianFilter median = new MedianFilter(null, 4*getSCALE(cols,rows), new boolean[]{false,false,true,true});
|
MedianFilter median = new MedianFilter(null, 4*getSCALE(stopX-startX, stopY-startY), new boolean[]{false,false,true,true});
|
||||||
IRgBy = median.process(IRgBy, cols, rows);
|
median.process(IRgBy);
|
||||||
setProgress(ZMath.percent(0, 4, 1));
|
setProgress(ZMath.percent(0, 4, 1));
|
||||||
|
|
||||||
//********* Texture Map ********
|
//********* Texture Map ********
|
||||||
median = new MedianFilter(null, 8*getSCALE(cols,rows), new boolean[]{false,true,false,false});
|
median = new MedianFilter(null, 8*getSCALE(stopX-startX, stopY-startY), new boolean[]{false,true,false,false});
|
||||||
int[][][] textureMap = median.process(IRgBy, cols, rows);
|
int[][][] textureMap = ImageUtil.copyArray(IRgBy);
|
||||||
|
median.process(IRgBy);
|
||||||
|
|
||||||
for(int y=0; y<rows ;y++){
|
for(int y=startY; y<stopY ;y++){
|
||||||
for(int x=0; x<cols ;x++){
|
for(int x=startX; x<stopX ;x++){
|
||||||
textureMap[y][x][1] = Math.abs(IRgBy[y][x][1]-textureMap[y][x][1]);
|
textureMap[y][x][1] = Math.abs(IRgBy[y][x][1]-textureMap[y][x][1]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
median = new MedianFilter(null, 12*getSCALE(cols,rows), new boolean[]{false,true,false,false});
|
median = new MedianFilter(null, 12*getSCALE(stopX-startX, stopY-startY), new boolean[]{false,true,false,false});
|
||||||
textureMap = median.process(textureMap, cols, rows);
|
textureMap = ImageUtil.copyArray(IRgBy);
|
||||||
|
median.process(textureMap);
|
||||||
setProgress(ZMath.percent(0, 4, 2));
|
setProgress(ZMath.percent(0, 4, 2));
|
||||||
|
|
||||||
//*********** Hue & Saturation *********
|
//*********** Hue & Saturation *********
|
||||||
int[][] skinMap = new int[rows][cols];
|
int[][] skinMap = new int[data.length][data[0].length];
|
||||||
int[][] hueMap = new int[rows][cols];
|
int[][] hueMap = new int[data.length][data[0].length];
|
||||||
int[][] saturationMap = new int[rows][cols];
|
int[][] saturationMap = new int[data.length][data[0].length];
|
||||||
|
|
||||||
int hue, saturation;
|
int hue, saturation;
|
||||||
for(int y=0; y<rows ;y++){
|
for(int y=startY; y<stopY ;y++){
|
||||||
for(int x=0; x<cols ;x++){
|
for(int x=startX; x<stopX ;x++){
|
||||||
// hue = (atan^2(Rg,By))
|
// hue = (atan^2(Rg,By))
|
||||||
hue = (int)( Math.atan2(IRgBy[y][x][2], IRgBy[y][x][3]) * 360/2*Math.PI);
|
hue = (int)( Math.atan2(IRgBy[y][x][2], IRgBy[y][x][3]) * 360/2*Math.PI);
|
||||||
// saturation = sqrt(Rg^2+By^2)
|
// saturation = sqrt(Rg^2+By^2)
|
||||||
|
|
@ -61,28 +64,30 @@ public class FaceDetectionFilter extends ImageFilterProcessor{
|
||||||
setProgress(ZMath.percent(0, 4, 3));
|
setProgress(ZMath.percent(0, 4, 3));
|
||||||
|
|
||||||
//************** SkinMap dilation ********************
|
//************** SkinMap dilation ********************
|
||||||
skinMap = dilation(skinMap , cols, rows);
|
skinMap = dilation(skinMap , startX, startY, stopX, stopY);
|
||||||
|
|
||||||
|
|
||||||
//*****************************************************
|
//*****************************************************
|
||||||
setProgress(100);
|
setProgress(100);
|
||||||
//return convertArrayToARGBchannel(hueMap, cols, rows, -150, 150, 1);
|
//return convertArrayToARGBchannel(hueMap, startX, startY, stopX, stopY, -150, 150, 1);
|
||||||
//return convertArrayToARGBchannel(saturationMap, cols, rows, 0, 70, 1);
|
//return convertArrayToARGBchannel(saturationMap, startX, startY, stopX, stopY, 0, 70, 1);
|
||||||
return convertArrayToARGBchannel(skinMap, cols, rows, 0, 1, 2);
|
ImageUtil.copyArray(
|
||||||
|
convertArrayToARGBchannel(skinMap, startX, startY, stopX, stopY, 0, 1, 2),
|
||||||
|
data, startX, startY, stopX, stopY);
|
||||||
}
|
}
|
||||||
|
|
||||||
private int[][] dilation(int[][] data, int cols, int rows){
|
private int[][] dilation(int[][] data, int startX, int startY, int stopX, int stopY){
|
||||||
int[][] output = new int[rows][cols];
|
int[][] output = new int[data.length][data[0].length];
|
||||||
int radX = 8;
|
int radX = 8;
|
||||||
int radY = 8;
|
int radY = 8;
|
||||||
|
|
||||||
for(int y=0; y<rows ;y++){
|
for(int y=startY; y<stopY ;y++){
|
||||||
for(int x=0; x<cols ;x++){
|
for(int x=startX; x<stopX ;x++){
|
||||||
if(data[y][x] == 1){
|
if(data[y][x] == 1){
|
||||||
|
|
||||||
for(int dy=y-radY; dy<y+radY ;dy++){
|
for(int dy=y-radY; dy<y+radY ;dy++){
|
||||||
for(int dx=x-radX; dx<x+radX ;dx++){
|
for(int dx=x-radX; dx<x+radX ;dx++){
|
||||||
if(dy >= 0 && dy < rows && dx >= 0 && dx < cols)
|
if(dy >= 0 && dy < data.length && dx >= 0 && dx < data[0].length)
|
||||||
output[dy][dx] = 1;
|
output[dy][dx] = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -99,18 +104,20 @@ public class FaceDetectionFilter extends ImageFilterProcessor{
|
||||||
* Converts the given data array to a color image
|
* Converts the given data array to a color image
|
||||||
*
|
*
|
||||||
* @param data The 2d data
|
* @param data The 2d data
|
||||||
* @param cols The size of the image data
|
* @param startX is the x pixel of the image to start from
|
||||||
* @param rows The size of the image data
|
* @param startY is the y pixel of the image to start from
|
||||||
|
* @param stopX is the x pixel of the image to stop
|
||||||
|
* @param stopY is the y pixel of the image to stop
|
||||||
* @param min The minimum value in the data
|
* @param min The minimum value in the data
|
||||||
* @param max The maximum value in the data
|
* @param max The maximum value in the data
|
||||||
* @param channel The color channel to apply the data to
|
* @param channel The color channel to apply the data to
|
||||||
* @return A ARGB array
|
* @return A ARGB array
|
||||||
*/
|
*/
|
||||||
public int[][][] convertArrayToARGBchannel(int[][] data, int cols, int rows,int min, int max, int channel){
|
public int[][][] convertArrayToARGBchannel(int[][] data, int startX, int startY, int stopX, int stopY,int min, int max, int channel){
|
||||||
int[][][] output = new int[rows][cols][4];
|
int[][][] output = new int[data.length][data[0].length][4];
|
||||||
|
|
||||||
for(int y=0; y<rows ;y++){
|
for(int y=startY; y<stopY ;y++){
|
||||||
for(int x=0; x<cols ;x++){
|
for(int x=startX; x<stopX ;x++){
|
||||||
output[y][x][0] = 255;
|
output[y][x][0] = 255;
|
||||||
output[y][x][channel] = (int) ZMath.percent(min, max, data[y][x]);
|
output[y][x][channel] = (int) ZMath.percent(min, max, data[y][x]);
|
||||||
}
|
}
|
||||||
|
|
@ -126,15 +133,17 @@ public class FaceDetectionFilter extends ImageFilterProcessor{
|
||||||
* By = L(B)-[L(G)+L(R)]/2
|
* By = L(B)-[L(G)+L(R)]/2
|
||||||
*
|
*
|
||||||
* @param data The RGB data
|
* @param data The RGB data
|
||||||
* @param cols The number of columns
|
* @param startX is the x pixel of the image to start from
|
||||||
* @param rows The number of rows
|
* @param startY is the y pixel of the image to start from
|
||||||
|
* @param stopX is the x pixel of the image to stop
|
||||||
|
* @param stopY is the y pixel of the image to stop
|
||||||
* @return IRgBy data
|
* @return IRgBy data
|
||||||
*/
|
*/
|
||||||
public int[][][] convertARGBToIRgBy(int[][][] data, int cols, int rows){
|
public int[][][] convertARGBToIRgBy(int[][][] data, int startX, int startY, int stopX, int stopY){
|
||||||
int[][][] output = new int[rows][cols][4];
|
int[][][] output = new int[data.length][data[0].length][4];
|
||||||
|
|
||||||
for(int y=0; y<rows ;y++){
|
for(int y=startY; y<stopY ;y++){
|
||||||
for(int x=0; x<cols ;x++){
|
for(int x=startX; x<stopX ;x++){
|
||||||
output[y][x][0] = data[y][x][0];
|
output[y][x][0] = data[y][x][0];
|
||||||
// I= [L(R)+L(B)+L(G)]/3
|
// I= [L(R)+L(B)+L(G)]/3
|
||||||
output[y][x][1] = (
|
output[y][x][1] = (
|
||||||
|
|
@ -158,8 +167,8 @@ public class FaceDetectionFilter extends ImageFilterProcessor{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private int getSCALE(int cols, int rows){
|
private int getSCALE(int width, int height){
|
||||||
return (cols+rows)/320;
|
return (width+height)/320;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ import java.awt.image.BufferedImage;
|
||||||
|
|
||||||
import zutil.algo.sort.sortable.SortableDataList;
|
import zutil.algo.sort.sortable.SortableDataList;
|
||||||
import zutil.image.ImageFilterProcessor;
|
import zutil.image.ImageFilterProcessor;
|
||||||
|
import zutil.image.ImageUtil;
|
||||||
import zutil.math.ZMath;
|
import zutil.math.ZMath;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -60,44 +61,42 @@ public class MedianFilter extends ImageFilterProcessor{
|
||||||
pixelValue[x][y] := colorArray[window width / 2][window height / 2];
|
pixelValue[x][y] := colorArray[window width / 2][window height / 2];
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public int[][][] process(int[][][] data, int cols, int rows) {
|
public void process(int[][][] data, int startX, int startY, int stopX, int stopY) {
|
||||||
int[][][] output = new int[rows][cols][4];
|
int[][][] tmpData = ImageUtil.copyArray(data);
|
||||||
|
|
||||||
int edgeX = windowSize / 2;
|
int edgeX = windowSize / 2;
|
||||||
int edgeY = windowSize / 2;
|
int edgeY = windowSize / 2;
|
||||||
|
|
||||||
int[][] tmpArray = new int[4][256*2];
|
int[][] tmpArray = new int[4][256*2];
|
||||||
int pixelCount = 0;
|
int pixelCount = 0;
|
||||||
for(int y=0; y<rows ;y++){
|
for(int y=startY; y<stopY ;y++){
|
||||||
setProgress(ZMath.percent(0, rows-1, y));
|
setProgress(ZMath.percent(0, stopY-startY-1, y));
|
||||||
for(int x=0; x<cols ;x++){
|
for(int x=startX; x<stopX ;x++){
|
||||||
|
|
||||||
pixelCount = 0;
|
pixelCount = 0;
|
||||||
for(int fy=0; fy<windowSize ;fy++){
|
for(int fy=0; fy<windowSize ;fy++){
|
||||||
for(int fx=0; fx<windowSize ;fx++){
|
for(int fx=0; fx<windowSize ;fx++){
|
||||||
if(y+fy-edgeY >= 0 && y+fy-edgeY < rows && x+fx-edgeX >= 0 && x+fx-edgeX < cols){
|
if(y+fy-edgeY >= 0 && y+fy-edgeY < data.length && x+fx-edgeX >= 0 && x+fx-edgeX < data[0].length){
|
||||||
//colorArray[fx][fy] := pixelvalue[x + fx - edgex][y + fy - edgey]
|
//colorArray[fx][fy] := pixelvalue[x + fx - edgex][y + fy - edgey]
|
||||||
if(channels[0]) tmpArray[0][ getMedianIndex( data[y + fy - edgeY][x + fx - edgeX][0] ) ]++;
|
if(channels[0]) tmpArray[0][ getMedianIndex( tmpData[y + fy - edgeY][x + fx - edgeX][0] ) ]++;
|
||||||
if(channels[1]) tmpArray[1][ getMedianIndex( data[y + fy - edgeY][x + fx - edgeX][1] ) ]++;
|
if(channels[1]) tmpArray[1][ getMedianIndex( tmpData[y + fy - edgeY][x + fx - edgeX][1] ) ]++;
|
||||||
if(channels[2]) tmpArray[2][ getMedianIndex( data[y + fy - edgeY][x + fx - edgeX][2] ) ]++;
|
if(channels[2]) tmpArray[2][ getMedianIndex( tmpData[y + fy - edgeY][x + fx - edgeX][2] ) ]++;
|
||||||
if(channels[3]) tmpArray[3][ getMedianIndex( data[y + fy - edgeY][x + fx - edgeX][3] ) ]++;
|
if(channels[3]) tmpArray[3][ getMedianIndex( tmpData[y + fy - edgeY][x + fx - edgeX][3] ) ]++;
|
||||||
pixelCount++;
|
pixelCount++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(channels[0])output[y][x][0] = findMedian(tmpArray[0], pixelCount/2);
|
if(channels[0]) data[y][x][0] = findMedian(tmpArray[0], pixelCount/2);
|
||||||
else output[y][x][0] = data[y][x][0];
|
else data[y][x][0] = tmpData[y][x][0];
|
||||||
if(channels[1])output[y][x][1] = findMedian(tmpArray[1], pixelCount/2);
|
if(channels[1]) data[y][x][1] = findMedian(tmpArray[1], pixelCount/2);
|
||||||
else output[y][x][1] = data[y][x][1];
|
else data[y][x][1] = tmpData[y][x][1];
|
||||||
if(channels[2])output[y][x][2] = findMedian(tmpArray[2], pixelCount/2);
|
if(channels[2]) data[y][x][2] = findMedian(tmpArray[2], pixelCount/2);
|
||||||
else output[y][x][2] = data[y][x][2];
|
else data[y][x][2] = tmpData[y][x][2];
|
||||||
if(channels[3])output[y][x][3] = findMedian(tmpArray[3], pixelCount/2);
|
if(channels[3]) data[y][x][3] = findMedian(tmpArray[3], pixelCount/2);
|
||||||
else output[y][x][3] = data[y][x][3];
|
else data[y][x][3] = tmpData[y][x][3];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return output;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private int getMedianIndex(int i){
|
private int getMedianIndex(int i){
|
||||||
|
|
|
||||||
|
|
@ -3,15 +3,17 @@ package zutil.image.filters;
|
||||||
import java.awt.image.BufferedImage;
|
import java.awt.image.BufferedImage;
|
||||||
|
|
||||||
import zutil.image.ImageFilterProcessor;
|
import zutil.image.ImageFilterProcessor;
|
||||||
|
import zutil.image.ImageUtil;
|
||||||
import zutil.math.ZMath;
|
import zutil.math.ZMath;
|
||||||
|
|
||||||
public class ResizeImage extends ImageFilterProcessor{
|
public class ResizeImage extends ImageFilterProcessor{
|
||||||
private int width;
|
private int width;
|
||||||
private int hight;
|
private int height;
|
||||||
|
|
||||||
|
private int[][][] newData;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Will create a ResizeImage object and fix the hight with the aspect
|
* Will create a ResizeImage object and fix the height with the aspect
|
||||||
* of the width
|
* of the width
|
||||||
*
|
*
|
||||||
* @param img The image to resize
|
* @param img The image to resize
|
||||||
|
|
@ -26,38 +28,45 @@ public class ResizeImage extends ImageFilterProcessor{
|
||||||
*
|
*
|
||||||
* @param img The image to resize
|
* @param img The image to resize
|
||||||
* @param w The new width if -1 then it will be scaled whit aspect of the hight
|
* @param w The new width if -1 then it will be scaled whit aspect of the hight
|
||||||
* @param h The new hight if -1 then it will be scaled whit aspect of the width
|
* @param h The new height if -1 then it will be scaled whit aspect of the width
|
||||||
*/
|
*/
|
||||||
public ResizeImage(BufferedImage img, int w, int h){
|
public ResizeImage(BufferedImage img, int w, int h){
|
||||||
super(img);
|
super(img);
|
||||||
width = w;
|
width = w;
|
||||||
hight = h;
|
height = h;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int[][][] process(final int[][][] data, int cols, int rows) {
|
public void process(final int[][][] data, int startX, int startY, int stopX, int stopY) {
|
||||||
if(width < 1){
|
if(width < 1){
|
||||||
hight = (int)(((double)width/cols)*rows);
|
height = (int)(((double)width/(stopX-startX))*(stopY-startY));
|
||||||
}
|
}
|
||||||
else if(hight < 1){
|
else if(height < 1){
|
||||||
width = (int)(((double)hight/rows)*cols);
|
width = (int)(((double)height/(stopY-startY))*(stopX-startY));
|
||||||
}
|
}
|
||||||
|
|
||||||
int[][][] tmp = new int[hight][width][4];
|
newData = new int[height][width][4];
|
||||||
double xScale = ((double)cols/width);
|
double xScale = ((double)(stopX-startX)/width);
|
||||||
double yScale = ((double)rows/hight);
|
double yScale = ((double)(stopY-startY)/height);
|
||||||
|
|
||||||
for(int y=0; y<width ;y++){
|
for(int y=0; y<width ;y++){
|
||||||
setProgress(ZMath.percent(0, width-1, y));
|
setProgress(ZMath.percent(0, width-1, y));
|
||||||
for(int x=0; x<hight ;x++){
|
for(int x=0; x<height ;x++){
|
||||||
tmp[y][x][0] = data[(int)(y*yScale)][(int)(x*xScale)][0];
|
newData[y][x][0] = data[(int)(y*yScale)][(int)(x*xScale)][0];
|
||||||
tmp[y][x][1] = data[(int)(y*yScale)][(int)(x*xScale)][1];
|
newData[y][x][1] = data[(int)(y*yScale)][(int)(x*xScale)][1];
|
||||||
tmp[y][x][2] = data[(int)(y*yScale)][(int)(x*xScale)][2];
|
newData[y][x][2] = data[(int)(y*yScale)][(int)(x*xScale)][2];
|
||||||
tmp[y][x][3] = data[(int)(y*yScale)][(int)(x*xScale)][3];
|
newData[y][x][3] = data[(int)(y*yScale)][(int)(x*xScale)][3];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return tmp;
|
ImageUtil.copyArray(newData, data, 0, 0, width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the resulting image after processing
|
||||||
|
* @return an image or null if not processed
|
||||||
|
*/
|
||||||
|
public int[][][] getResult(){
|
||||||
|
return newData;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -41,15 +41,14 @@ public class SpotLightFilter extends ImageFilterProcessor{
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int[][][] process(final int[][][] data, int cols, int rows) {
|
public void process(final int[][][] data, int startX, int startY, int stopX, int stopY) {
|
||||||
if(xPos < 0) xPos = cols/2;
|
if(xPos < 0) xPos = data[0].length/2;
|
||||||
if(yPos < 0) yPos = rows/2;
|
if(yPos < 0) yPos = data.length/2;
|
||||||
|
|
||||||
int[][][] output = new int[rows][cols][4];
|
|
||||||
double scale, dx, dy, distance;
|
double scale, dx, dy, distance;
|
||||||
for(int y=0; y<rows ;y++){
|
for(int y=startY; y<stopY ;y++){
|
||||||
setProgress(ZMath.percent(0, rows-1, y));
|
setProgress(ZMath.percent(0, (stopY-startY)-1, y));
|
||||||
for(int x=0; x<cols ;x++){
|
for(int x=startX; x<stopX ;x++){
|
||||||
dx = x-xPos;
|
dx = x-xPos;
|
||||||
dy = y-yPos;
|
dy = y-yPos;
|
||||||
|
|
||||||
|
|
@ -62,13 +61,12 @@ public class SpotLightFilter extends ImageFilterProcessor{
|
||||||
scale = 1-(distance/radius);
|
scale = 1-(distance/radius);
|
||||||
}
|
}
|
||||||
|
|
||||||
output[y][x][0] = data[y][x][0];
|
data[y][x][0] = data[y][x][0];
|
||||||
output[y][x][1] = ImageUtil.clip((int)(scale * data[y][x][1]));
|
data[y][x][1] = ImageUtil.clip((int)(scale * data[y][x][1]));
|
||||||
output[y][x][2] = ImageUtil.clip((int)(scale * data[y][x][2]));
|
data[y][x][2] = ImageUtil.clip((int)(scale * data[y][x][2]));
|
||||||
output[y][x][3] = ImageUtil.clip((int)(scale * data[y][x][3]));
|
data[y][x][3] = ImageUtil.clip((int)(scale * data[y][x][3]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return output;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -58,7 +58,7 @@ public class HttpPrintStream extends PrintStream{
|
||||||
public void sendHeader(String header) throws Exception{
|
public void sendHeader(String header) throws Exception{
|
||||||
if(cookie == null)
|
if(cookie == null)
|
||||||
throw new Exception("Header already sent!!!");
|
throw new Exception("Header already sent!!!");
|
||||||
super.println(header);
|
super.print(header+"\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -69,27 +69,25 @@ public class HttpPrintStream extends PrintStream{
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* NOT TO BE USED!!!!
|
* Prints an string
|
||||||
* use printOrBuffer(String s) instead
|
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
|
||||||
public void print(String s){
|
public void print(String s){
|
||||||
super.print(s);
|
printOrBuffer(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* prints to all
|
* prints to all
|
||||||
*/
|
*/
|
||||||
public void printOrBuffer(String s){
|
private void printOrBuffer(String s){
|
||||||
if(buffer_enabled){
|
if(buffer_enabled){
|
||||||
buffer.append(s);
|
buffer.append(s);
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
if(cookie != null){
|
if(cookie != null){
|
||||||
for(String key : cookie.keySet()){
|
for(String key : cookie.keySet()){
|
||||||
super.println("Set-Cookie: "+key+"="+cookie.get(key)+"; ");
|
super.print("Set-Cookie: "+key+"="+cookie.get(key)+"; \n");
|
||||||
}
|
}
|
||||||
super.println(" \n");
|
super.print(" \n");
|
||||||
cookie = null;
|
cookie = null;
|
||||||
}
|
}
|
||||||
super.print(s);
|
super.print(s);
|
||||||
|
|
@ -115,21 +113,21 @@ public class HttpPrintStream extends PrintStream{
|
||||||
}
|
}
|
||||||
|
|
||||||
public void println(){ println("");}
|
public void println(){ println("");}
|
||||||
public void println(boolean x){ println(""+x);}
|
public void println(boolean x){ println(String.valueOf(x));}
|
||||||
public void println(char x){ println(""+x);}
|
public void println(char x){ println(String.valueOf(x));}
|
||||||
public void println(char[] x){ println(new String(x));}
|
public void println(char[] x){ println(new String(x));}
|
||||||
public void println(double x){ println(""+x);}
|
public void println(double x){ println(String.valueOf(x));}
|
||||||
public void println(float x){ println(""+x);}
|
public void println(float x){ println(String.valueOf(x));}
|
||||||
public void println(int x){ println(""+x);}
|
public void println(int x){ println(String.valueOf(x));}
|
||||||
public void println(long x){ println(""+x);}
|
public void println(long x){ println(String.valueOf(x));}
|
||||||
public void println(Object x){ println(""+x);}
|
public void println(Object x){ println(String.valueOf(x));}
|
||||||
|
|
||||||
public void print(boolean x){ printOrBuffer(""+x);}
|
public void print(boolean x){ printOrBuffer(String.valueOf(x));}
|
||||||
public void print(char x){ printOrBuffer(""+x);}
|
public void print(char x){ printOrBuffer(String.valueOf(x));}
|
||||||
public void print(char[] x){ printOrBuffer(new String(x));}
|
public void print(char[] x){ printOrBuffer(new String(x));}
|
||||||
public void print(double x){ printOrBuffer(""+x);}
|
public void print(double x){ printOrBuffer(String.valueOf(x));}
|
||||||
public void print(float x){ printOrBuffer(""+x);}
|
public void print(float x){ printOrBuffer(String.valueOf(x));}
|
||||||
public void print(int x){ printOrBuffer(""+x);}
|
public void print(int x){ printOrBuffer(String.valueOf(x));}
|
||||||
public void print(long x){ printOrBuffer(""+x);}
|
public void print(long x){ printOrBuffer(String.valueOf(x));}
|
||||||
public void print(Object x){ printOrBuffer(""+x);}
|
public void print(Object x){ printOrBuffer(String.valueOf(x));}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,6 @@ package zutil.test;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
|
||||||
import zutil.FileFinder;
|
|
||||||
import zutil.network.http.HttpPage;
|
import zutil.network.http.HttpPage;
|
||||||
import zutil.network.http.HttpPrintStream;
|
import zutil.network.http.HttpPrintStream;
|
||||||
import zutil.network.http.HttpServer;
|
import zutil.network.http.HttpServer;
|
||||||
|
|
|
||||||
|
|
@ -61,13 +61,13 @@ public class ImageProcessorTest implements ProgressListener{
|
||||||
|
|
||||||
BufferedImage procImg = null;
|
BufferedImage procImg = null;
|
||||||
try {
|
try {
|
||||||
//ImageFilterProcessor processor = new SpotLightFilter(img,100,100,100);
|
//ImageFilterProcessor processor = new BlurFilter(img, 10);
|
||||||
//ImageFilterProcessor processor = new ContrastBrightnessFilter(img);
|
|
||||||
//ImageFilterProcessor processor = new ColorIntensityFilter(img, true);
|
//ImageFilterProcessor processor = new ColorIntensityFilter(img, true);
|
||||||
ImageFilterProcessor processor = new BlurFilter(img, 100);
|
//ImageFilterProcessor processor = new ContrastBrightnessFilter(img);
|
||||||
//ImageFilterProcessor processor = new DitheringFilter(img);
|
ImageFilterProcessor processor = new DitheringFilter(img);
|
||||||
//ImageFilterProcessor processor = new ResizeImage(img,100,100);
|
|
||||||
//ImageFilterProcessor processor = new MedianFilter(img);
|
//ImageFilterProcessor processor = new MedianFilter(img);
|
||||||
|
//ImageFilterProcessor processor = new ResizeImage(img,100,100);
|
||||||
|
//ImageFilterProcessor processor = new SpotLightFilter(img,100,100,100);
|
||||||
//ImageFilterProcessor processor = new FaceDetectionFilter(img);
|
//ImageFilterProcessor processor = new FaceDetectionFilter(img);
|
||||||
|
|
||||||
processor.setProgressListener(this);
|
processor.setProgressListener(this);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue