/**
* グレースケールフィルタ
*/
package jp.crwdev.app.imagefilter;
import java.awt.image.BufferedImage;
import java.util.Date;
import jp.crwdev.app.interfaces.IImageFilter;
public class GrayscaleFilter implements IImageFilter {
@SuppressWarnings("unused")
@Override
public BufferedImage filter(BufferedImage image, ImageFilterParam param) {
if(param == null || !param.isGrayscale()){
return image;
}
/*
* Grayscale
*/
// GrayscaleOp grayOp = new GrayscaleOp();
// return grayOp.filter(image, null);
final double Rparam = 0.298912 * 1024;
final double Gparam = 0.586611 * 1024;
final double Bparam = 0.114478 * 1024;
// 元画像に影響が出ないようにコピーを作成
BufferedImage dest = image;
try {
dest = new BufferedImage(image.getWidth(), image.getHeight(), image.getType());
}
catch(OutOfMemoryError e){
e.printStackTrace();
// メモリ不足の場合は仕方ないので直接編集する
}
Date startDate = new Date();
long starttime = startDate.getTime();
if(false){
int width = image.getWidth();
int height = image.getHeight();
for( int y = 0; y < height; y ++ ) {
for( int x = 0; x < width; x ++ ) {
int rgb = image.getRGB(x, y);
int r = (rgb >> 16) & 0xff;
int g = (rgb >> 8) & 0xff;
int b = rgb & 0xff;
int n = (((int)( r*Rparam + g*Gparam + b*Bparam )) >> 10);
int gray = ((n << 16) | (n << 8) | n);
dest.setRGB(x, y, gray);
}
}
}
else{
// スレッドで並列処理させる
final int threadNum = 2; // 3つ以上作ってもあまり変わらなかった(CPU次第か)
final BufferedImage destCopy = dest;
final BufferedImage srcCopy = image;
Thread[] threads = new Thread[threadNum-1];
for(int i=1; i<threadNum; i++){
final int start = i;
threads[i-1] = new Thread( new Runnable(){
public void run(){
convertThreadProcess(destCopy, srcCopy, start, threadNum);
}
});
threads[i-1].setPriority(8);
threads[i-1].start();
}
convertThreadProcess(destCopy, srcCopy, 0, threadNum);
waitForAllThreads(threads);
}
Date end = new Date();
long endtime = end.getTime();
System.out.println(String.format("convertTime = %d", endtime - starttime));
return dest;
}
private void convertThreadProcess(BufferedImage dest, BufferedImage src, int startLine, int offset){
final double Rparam = 0.298912 * 1024;
final double Gparam = 0.586611 * 1024;
final double Bparam = 0.114478 * 1024;
int height = src.getHeight();
int width = src.getWidth();
int[] rgbArray = new int[width];
for(int y=startLine; y<height; y+=offset){
src.getRGB(0, y, width, 1, rgbArray, 0, width);
for(int x=0; x<width; x++){
int rgb = rgbArray[x];
int r = (rgb >> 16) & 0xff;
int g = (rgb >> 8) & 0xff;
int b = rgb & 0xff;
int n = (((int)( r*Rparam + g*Gparam + b*Bparam )) >> 10);
int gray = ((n << 16) | (n << 8) | n);
rgbArray[x] = gray;
}
dest.setRGB(0, y, width, 1, rgbArray, 0, width);
}
}
private void waitForAllThreads(Thread[] threads) {
try {
for (Thread t:threads){
t.join(Long.MAX_VALUE);
}
} catch (InterruptedException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
}