java 7 fork/join模糊图像示例, java 8 lambda 并行聚合函数 parallelSort()

fork/join 线程模型 被用来实现了java.util.Arrays 的 parallelSort() ,该方法功能类似sort().

java 8 的java.util.streams 包里的聚合操作的并行方法都是用它来实现的,如 

parallelStream()

思路:

if (我的工作是小于一个阀值的)
  直接做我的工作
else
  把我的工作分解成两部分
  调用这两个部分并等待它们返回结果
这是如下标红字体所实现的思路,也是核心

调用它



ForkBlur fb = new ForkBlur(src, 0, src.length, dst);

ForkJoinPool pool = new ForkJoinPool();

pool.invoke(fb);


以下代码是把一张图片弄浑浊。总的思路:

划定算平均值的范围,一个像素点用它周围的每个点的红,绿,蓝的平均值来代替

具体注释如下


import java.awt.image.BufferedImage;
import java.io.File;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveAction;


import javax.imageio.ImageIO;


public class ForkBlur extends RecursiveAction {
	private int[] mSource;
	private int mStart;
	private int mLength;
	private int[] mDestination;


	// Processing window size; should be odd.划定算平均值的范围
	private int mBlurWidth = 3;


	public ForkBlur(int[] src, int start, int length, int[] dst) {
		mSource = src;
		mStart = start;
		mLength = length;
		mDestination = dst;
	}


	protected void computeDirectly() {
		int sidePixels = (mBlurWidth - 1) / 2;
		for (int index = mStart; index < mStart + mLength; index++) {
			// Calculate average.一个像素点用它周围的每个点的红,绿,蓝的平均值来代替
			float rt = 0, gt = 0, bt = 0;
			for (int mi = -sidePixels; mi <= sidePixels; mi++) {
				int mindex = Math.min(Math.max(mi + index, 0), mSource.length - 1);//在选取的范围之内,但不能超过总的边界
				int pixel = mSource[mindex];
				rt += (float) ((pixel & 0x00ff0000) >> 16) / mBlurWidth;//红色是ff所在的那些位
				gt += (float) ((pixel & 0x0000ff00) >> 8) / mBlurWidth;
				bt += (float) ((pixel & 0x000000ff) >> 0) / mBlurWidth;
			}


			// Reassemble destination pixel.
			int dpixel = (0xff000000) | (((int) rt) << 16) | (((int) gt) << 8) | (((int) bt) << 0);
			mDestination[index] = dpixel;
		}
	}


	protected static int sThreshold = 100000;

protected void compute() {

//不是显示调用,是java虚拟机自动调用
        if (mLength < sThreshold) {            
		computeDirectly();            
		return;        
		}        
		int split = mLength / 2;        
		invokeAll(new ForkBlur(mSource, mStart, split, mDestination),                
		new ForkBlur(mSource, mStart + split, mLength - split, mDestination));//是一个递归调用
}// Plumbing follows.
public static void main(String[] args) throws Exception {
       String srcName = "red-tulips.jpg";
        File srcFile = new File(srcName);
       BufferedImage image = ImageIO.read(srcFile);
     System.out.println("Source image: " + srcName);
     BufferedImage blurredImage = blur(image);
    String dstName = "blurred-tulips.jpg";
    File dstFile = new File(dstName);
    ImageIO.write(blurredImage, "jpg", dstFile);
    System.out.println("Output image: " + dstName);
}
public static BufferedImage blur(BufferedImage srcImage) {
int w = srcImage.getWidth();
int h = srcImage.getHeight();
int[] src = srcImage.getRGB(0, 0, w, h, null, 0, w);
int[] dst = new int[src.length];
System.out.println("Array size is " + src.length);
System.out.println("Threshold is " + sThreshold);
int processors = Runtime.getRuntime().availableProcessors();
System.out.println(Integer.toString(processors) + " processor" + (processors != 1 ? "s are " : " is ") + "available");
ForkBlur fb = new ForkBlur(src, 0, src.length, dst);
ForkJoinPool pool = new ForkJoinPool();
long startTime = System.currentTimeMillis();
pool.invoke(fb);
long endTime = System.currentTimeMillis();
System.out.println("Image blur took " + (endTime - startTime) + " milliseconds.");
BufferedImage dstImage = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
dstImage.setRGB(0, 0, w, h, dst, 0, w);return dstImage;
}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值