JAVA 数字图像处理----非白即黑的灰,2B青年的自画像

昨天晚上在科学松鼠会上看到一篇题为“计算机原来要晃一晃才好用”的文章,里面提到了一种计算机处理数字信号时常用的抖动技术,觉得蛮有意思的所以今天就用万恶的JAVA写了生成二直图像的小程序。

截图:

JAVA 数字图像处理----非白即黑的灰,2B青年的自画像_第1张图片


程序中使用的acm jtf包在http://jtf.acm.org/可以下到,推荐刚开始学java的同学去看Eric S. Roberts的《the art and Science of Java》(影印版),很好的入门教材,还可以顺便提高英语阅读能力。

主程序代码:

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import acm.program.*;
import acm.graphics.*;

import javax.imageio.ImageIO;
import javax.swing.*;

public class test_filter extends GraphicsProgram{
	public void init()
	{
		setBackground(Color.gray);
		slider = new JSlider(0,100,50);
		add(new JButton("Open Image"),SOUTH);
		add(new JButton("Process"),SOUTH);
		add(new JLabel("Dark "),SOUTH);
		add(slider,SOUTH);
		add(new JLabel("Bright"),SOUTH);
		add(new JButton("Save"),SOUTH);
		
		addActionListeners();
	}
	
	public void actionPerformed(ActionEvent e)
	{
		String cmd = e.getActionCommand();
		if(cmd.equals("Open Image")) openTarget();
		if(cmd.equals("Process")) process();
		if(cmd.equals("Save")) save();
	}
	
	private void openTarget()
	{
		JFileChooser chooser = new JFileChooser();
		
		int fid = chooser.showOpenDialog(this);
		if(fid == chooser.APPROVE_OPTION)
		{
			File file = chooser.getSelectedFile();
			if(file.getName().endsWith(".jpg") || file.getName().endsWith(".JPG"))
			{
				target = null;
				target = new GImage(file.getPath());
				setScale(target);
				is_target_ready = true;
				target_thumbnail = thumbnail(target);
				pic_width = target_thumbnail.getWidth();
				pic_height = target_thumbnail.getHeight();
				removeAll();
				add(target_thumbnail,0,0);
			}
		}
	}
	
	private void process()
	{
		if(!is_target_ready) return ;
		double factor = slider.getValue()/50.0;
		result = dsp.actBwFilter(target,factor);
		GImage result_thumbnail = thumbnail(result);
		add(result_thumbnail,pic_width,0);
		is_result_ready = true;
	}
	
	private void save()
	{
		if(!is_result_ready) return ;
		try {
			JFileChooser chooser = new JFileChooser();
			
			int fid = chooser.showSaveDialog(this);
			if(fid==JFileChooser.APPROVE_OPTION)
			{
				File file = chooser.getSelectedFile();
				ImageIO.write(toBufferedImage(result), "jpg", file);
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	private BufferedImage toBufferedImage(GImage image)
	{
		int[][] array = image.getPixelArray();
		int width = array[0].length;
		int height = array.length;
		BufferedImage bimg = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
		for(int i=0;i<height;i++)
		{
			for(int j=0;j<width;j++) bimg.setRGB(j, i, array[i][j]);
		}
		return bimg;
	}
	
	private GImage thumbnail(GImage image)
	{
		GImage thumbnail = dsp.imageSampleAve(image, scale);
		return thumbnail;
	}
	
	private void setScale(GImage image)
	{
		if(image.getWidth()>image.getHeight())
		{
			scale = (int)(calcuScale(image,1,2)+0.5);
		}
		else scale = (int)(calcuScale(image,2,1)+0.5);
	}
	
	private double calcuScale(GImage image,int row,int column)
	{
		int width = getWidth()/column;
		int height = getHeight()/row;
		double ws = image.getWidth()/width;
		double hs = image.getHeight()/height;
		if(ws>hs) return ws;
		return hs;
	}
	
	public static void main(String args[])
	{
		new test_filter().start(args);
	}
	
	public static final int APPLICATION_WIDTH = 600;
	public static final int APPLICATION_HEIGHT = 300;
	
	private int scale;
	private GImage target;
	private GImage result;
	private GImage target_thumbnail;
	private double pic_width;
	private double pic_height;
	private JSlider slider;
	
	private boolean is_target_ready;
	private boolean is_result_ready;
}

二值图生成函数:

public static GImage actBwFilter(GImage image)
	{
		return actBwFilter(image,1);
	}
	
	public static GImage actBwFilter(GImage image,double factor)
	{
		image = bwFilter(image);
		int[][] array = image.getPixelArray();
		RandomGenerator rgen = RandomGenerator.getInstance();
		int width = array[0].length;
		int height = array.length;
		for(int i=0;i<height;i++)
		{
			for(int j=0;j<width;j++)
			{
				int color=array[i][j]&0xFF;
				double p = (double)color/0xFF;
				if(rgen.nextBoolean(p*factor)) color=0xFF;
				else color=0x00;
				array[i][j]=(0xFF<<24)|(color<<16)|(color<<8)|color;
			}
		}
		GImage img = new GImage(array);
		return img;
	}


你可能感兴趣的:(java,image,File,application,import,图像处理)