java swing中简单图片编辑器(图片缩放、透明化、旋转)

java swing中简单图片编辑器(图片缩放、半透明化、旋转)

本文介绍了一个简单的图片编辑器,可以实现图片的固定长宽显示、放大一倍显示、缩小一半显示,以及半透明化存储到本地。本文写给我的朋友,助她初入java。

程序界面展示

在这里插入图片描述
按钮说明

  1. 点击左上角文件之后有四个选项,点击打开图片按钮,弹出文件选择器,选择一张图片就会显示在当前界面;
  2. 保存图片会将已经打开的图片保存到指定目录,在保存的时候需要填写完整的图片名称,包括扩展名;
  3. 图片放大一倍会将当前显示图片放大一倍显示;
  4. 图片缩小一倍会将当前显示图片缩小一倍显示;
  5. 固定缩放需要填写左面的长度和宽度,需是正整数,程序代码中可自定义长宽的临界值;
  6. 图片透明需要在左面透明度填写0~255之间的数值,填写完数值之后点击图片透明会保存在指定盘中;
  7. 图片旋转需要在左面旋转角度填写一个数值,填写完数值之后点击图片旋转会将旋转过的图片保存在指定盘中,并将旋转过后的图片再次显示在界面;

代码结构

  • src
    • java_picture
      • DialogDemo.java --主界面
      • TranslucentImage.java --图片透明处理
      • RotaingImage.java --图片旋转处理

界面代码

代码参考了: 霜沐林的博客
在源代码上做了一些修改,先建一个DialogDemo 类:

package java_picture;

import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;

import javax.swing.*;
import java.io.*;
import java.util.UUID;

import javax.imageio.ImageIO;
import javax.swing.GroupLayout.Alignment;
import javax.swing.LayoutStyle.ComponentPlacement;

public class DialogDemo implements ActionListener {
	JFrame frame;
	private Panel panel,panelButton,panelText;
	private JLabel labelHight,labelWidth,labelPellucidity;
	
	private JTextField textHight;
	private JTextField textWidth;
	private JTextField textPellucidity;
	static JTextArea textArea;
	
	private JButton buttonReduce,buttonEnlarge,buttonZoom,buttonPellucidity;
	
	private JMenuItem itemSave,itemOpen,itemAbout,itemExit;
	
	private FileDialog dialogOpen;
	private FileDialog dialogSave;
	
	private BufferedImage bufferedImage;
	
	private imageCanvas canvas;
	private Image image;
	private Graphics graphics;
	private Panel panel_1;
	private int imageHeight=0;
	private int imageWidth=0;
	private JPanel panel_2;
	private JLabel label;
	private JTextField textRataing;
	private JButton buttonRataing;
	public static void main(String[] args) {
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					DialogDemo window=new DialogDemo();
					window.frame.setVisible(true);
				}catch(Exception e) {
					e.printStackTrace();
				}
			}
		});
	}
	
	class imageCanvas extends Canvas{
		private static final long serialVersionUID = 1L;

		public void paint(Graphics g) {
			g.drawImage(bufferedImage,0,0,null);
		}
	}
	public DialogDemo() {
		frame=new JFrame();
		frame.setBounds(100,100,1081,900);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		
		frame.getContentPane().setLayout(new BorderLayout(0,0));
		canvas=new imageCanvas();
		canvas.setPreferredSize(new Dimension(800,600));
		frame.getContentPane().add(canvas,BorderLayout.CENTER);
		panel=new Panel();
		frame.getContentPane().add(panel,BorderLayout.SOUTH);
		panel.setLayout(new GridLayout(1,0,0,0));
		
		textArea=new JTextArea();
		textArea.setEditable(false);
		
		textArea.setText("提示\r\n");
		panel.add(textArea);
		panelButton=new Panel();
		panel.add(panelButton);
		panelButton.setLayout(new GridLayout(5,1,0,0));
		buttonReduce=new JButton("图片缩小一倍");
		 //按钮触发事件
		buttonReduce.addActionListener(new ActionListener(){

            public void actionPerformed(ActionEvent e) {
                // TODO Auto-generated method stub
            	reduceImage();
            }
            
        });
		buttonEnlarge=new JButton("图片放大一倍");
		 //按钮触发事件
		buttonEnlarge.addActionListener(new ActionListener(){

	            public void actionPerformed(ActionEvent e) {
	                // TODO Auto-generated method stub
	            	enlargeImage();
	            }       
	     });
		panelButton.add(buttonEnlarge);
		panelButton.add(buttonReduce);
		buttonEnlarge=new JButton("ceshi");
		buttonEnlarge.addActionListener(this);
		
		panelText=new Panel();
		panelButton.add(panelText);
		//长度
		labelHight=new JLabel("长度(px)");
		textHight=new JTextField();
		textHight.setColumns(10);
		//宽度
		labelWidth=new JLabel("宽度(px)");
		textWidth=new JTextField();
		textWidth.setColumns(10);
		
		buttonZoom=new JButton("固定缩放");
		GroupLayout gl_panelText = new GroupLayout(panelText);
		gl_panelText.setHorizontalGroup(
			gl_panelText.createParallelGroup(Alignment.LEADING)
				.addGroup(gl_panelText.createSequentialGroup()
					.addComponent(labelHight, GroupLayout.PREFERRED_SIZE, 65, GroupLayout.PREFERRED_SIZE)
					.addPreferredGap(ComponentPlacement.RELATED)
					.addComponent(textHight, GroupLayout.PREFERRED_SIZE, 53, GroupLayout.PREFERRED_SIZE)
					.addPreferredGap(ComponentPlacement.RELATED, 64, Short.MAX_VALUE)
					.addComponent(labelWidth, GroupLayout.PREFERRED_SIZE, 53, GroupLayout.PREFERRED_SIZE)
					.addPreferredGap(ComponentPlacement.RELATED)
					.addComponent(textWidth, GroupLayout.PREFERRED_SIZE, 53, GroupLayout.PREFERRED_SIZE)
					.addGap(59)
					.addComponent(buttonZoom, GroupLayout.PREFERRED_SIZE, 177, GroupLayout.PREFERRED_SIZE))
		);
		gl_panelText.setVerticalGroup(
			gl_panelText.createParallelGroup(Alignment.LEADING)
				.addGroup(gl_panelText.createParallelGroup(Alignment.BASELINE)
					.addComponent(labelHight, GroupLayout.PREFERRED_SIZE, 23, GroupLayout.PREFERRED_SIZE)
					.addComponent(textHight, GroupLayout.PREFERRED_SIZE, 23, GroupLayout.PREFERRED_SIZE))
				.addGroup(gl_panelText.createParallelGroup(Alignment.BASELINE)
					.addComponent(buttonZoom)
					.addComponent(labelWidth, GroupLayout.PREFERRED_SIZE, 23, GroupLayout.PREFERRED_SIZE)
					.addComponent(textWidth, GroupLayout.PREFERRED_SIZE, 23, GroupLayout.PREFERRED_SIZE))
		);
		panelText.setLayout(gl_panelText);
		
		panel_1 = new Panel();
		panelButton.add(panel_1);
		panel_1.setLayout(new GridLayout(1, 0, 0, 0));
		
		//透明度
		labelPellucidity=new JLabel("透明度(0-255)");
		panel_1.add(labelPellucidity);
		textPellucidity=new JTextField();
		panel_1.add(textPellucidity);
		textPellucidity.setColumns(10);
		//透明度按钮
		buttonPellucidity=new JButton("图片透明");
		panel_1.add(buttonPellucidity);
		
		panel_2 = new JPanel();
		panelButton.add(panel_2);
		panel_2.setLayout(new GridLayout(1, 2, 0, 0));
		
		label = new JLabel("旋转角度");
		panel_2.add(label);
		
		textRataing = new JTextField();
		textRataing.setColumns(10);
		panel_2.add(textRataing);
		
		buttonRataing = new JButton("图片旋转");
		buttonRataing.addActionListener(this);
		panel_2.add(buttonRataing);
		buttonPellucidity.addActionListener(this);
		
		buttonZoom.addActionListener(this);
		JMenuBar menuBar=new JMenuBar();
		frame.setJMenuBar(menuBar);
		
		JMenu newMenu=new JMenu("文件\r\n");
		menuBar.add(newMenu);
		//打开图片
		itemOpen = new JMenuItem("打开图片\r\n");
		newMenu.add(itemOpen);
		itemOpen.addActionListener(this);
		
		//保存图片
		itemSave=new JMenuItem("保存图片\r\n");
		newMenu.add(itemSave);
		itemSave.addActionListener(this);
		
		//关于程序
		itemAbout=new JMenuItem("关于程序");
		newMenu.add(itemAbout);
		itemAbout.addActionListener(this);
		
		JSeparator separator=new JSeparator();
		newMenu.add(separator);
		
		itemExit=new JMenuItem("退出程序\r\n");
		newMenu.add(itemExit);
		itemExit.addActionListener(this);
		
		dialogOpen=new FileDialog(frame,"请选择图片",FileDialog.LOAD);
		dialogSave=new FileDialog(frame,"‪图片路径",FileDialog.SAVE);
	}

	/**
	 * 点击事件监听
	 */
	public void actionPerformed(ActionEvent e) {
		if (e.getSource()==itemSave) {
			//保存图片
			saveImage();
		}else if(e.getSource()==itemOpen) {
			//打开图片
			openImage();
		}else if(e.getSource()==itemExit) {
			//推出程序
			System.exit(0);
		}else if(e.getSource()==itemAbout) {
			JOptionPane.showMessageDialog(null,"图片缩放程序:PhotoZoomer 1.0","版本",
					JOptionPane.INFORMATION_MESSAGE);
		}else if(e.getSource()==buttonEnlarge) {
			//放大图片事件
			enlargeImage();
		}else if(e.getSource()==buttonReduce) {
			//缩小图片事件
			reduceImage();
		}else if(e.getSource()==buttonZoom) {
			//固定缩放图片事件
			zoomImage();
		}else if(e.getSource()==buttonPellucidity){
		    //半透明化事件
			Pellucidity();
			
		}else if(e.getSource()==buttonRataing){
			//旋转图片
			try {
				RotaingImage();
			} catch (IOException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
		}
	}
	/**
	 * 打开图片按钮
	 */
	private void openImage() {
		try {
			bufferedImage=new BufferedImage(1920,890,BufferedImage.TYPE_INT_RGB);
			bufferedImage.flush();
			graphics=bufferedImage.getGraphics();
			dialogOpen.setVisible(true);
			image=ImageIO.read(new File(dialogOpen.getDirectory()+dialogOpen.getFile()));
			if(image!=null) {
				graphics.drawImage(image,0,0,null);
				canvas.repaint();
			}
			imageHeight=image.getHeight(null);
			imageWidth=image.getWidth(null);
			textArea.append("打开图片成功!\n图片路径:"+dialogOpen.getDirectory()+"\n"
					+"图片名称:"+dialogOpen.getFile()+"\n");
		}catch(IOException e) {
			e.printStackTrace();
			System.out.println("打开图片发生错误!");
		}
	}
	/**
	 * 保存图片
	 */
	private void saveImage() {
		try {
			dialogSave.setVisible(true);
			ImageIO.write(bufferedImage,"jpeg",new File(dialogSave.getDirectory()+
					dialogSave.getFile()));
			textArea.append("添加图片成功!\n保存目录:"+dialogSave.getDirectory()+"\n");
		}catch(IOException e) {
			e.printStackTrace();
			System.out.println("保存图片发生错误!");
		}
	}
	/**
	 * 固定缩放图片
	 */
	private void zoomImage() {
		if((textHight.getText().equals("")||textHight.getText().length()<0)&&(textWidth.getText().equals("")||textWidth.getText().length()<0)){
			textArea.append("\n请输入正确的图片宽度和长度!");
		}
		int height=Integer.parseInt(textHight.getText().replace(" ", ""));
		int width=Integer.parseInt(textWidth.getText().replace(" ", ""));
		if(height>0 && width>0 && height<=890 && width<=1920) {
			bufferedImage=new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
			graphics=bufferedImage.getGraphics();
			graphics.drawImage(image,0,0,width,height,null);
			canvas.repaint();
			textArea.append("\n图片缩放为高:"+height+"px,宽:"+width+"px\n");
			textHight.setText(" ");
			textWidth.setText(" ");
			}else {
				textArea.append("\n请输入正确的图片宽度和长度!");
				textHight.setText(" ");
				textWidth.setText(" ");
			}
	}
	/**
	 * 放大图片
	 */
	private void enlargeImage() {
		int height=imageHeight*2;
		int width=imageWidth*2;
		if(height>0 && width>0 && height<=8900 && width<=19200) {
			bufferedImage=new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
			graphics=bufferedImage.getGraphics();
			graphics.drawImage(image,0,0,width,height,null);
			canvas.repaint();
			textArea.setText("");
			textArea.append("\n图片缩放为高:"+height+"px,宽:"+width+"px\n");
			textHight.setText(" ");
			textWidth.setText(" ");
		}else {
			textArea.setText("");
			textArea.append("\n不能再进放大了!");
			textHight.setText(" ");
			textWidth.setText(" ");
		}
		imageWidth=imageWidth*2;
		imageHeight=imageHeight*2;
	}
	/**
	 * 缩小图片
	 */
	private void reduceImage() {
		int height=imageHeight/2;
		int width=imageWidth/2;
		if(height>0 && width>0 && height<=8900 && width<=19200) {
			bufferedImage=new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
			graphics=bufferedImage.getGraphics();
			graphics.drawImage(image,0,0,width,height,null);
			canvas.repaint();
			textArea.setText("");
			textArea.append("\n图片缩放为高:"+height+"px,宽:"+width+"px\n");
			textHight.setText(" ");
			textWidth.setText(" ");
		}else {
			textArea.setText("");
			textArea.append("\n不能再进行缩小了!");
			textHight.setText(" ");
			textWidth.setText(" ");
		}
		imageWidth=imageWidth/2;
		imageHeight=imageHeight/2;	
	}
	/**
	 * 设置图片透明度
	 */
	private void Pellucidity(){
	    //检查输入的正确性
		try{
			int alpha = Integer.parseInt(textPellucidity.getText());
			if(alpha<0||alpha>255){
				textArea.append("\n请输入0-255之间的数值!");
			}
			//生成一个随机数
			String uuid = UUID.randomUUID().toString();
			//转化半透明图片
			boolean result =TranslucentImage.Translucent(new File(dialogOpen.getDirectory()+dialogOpen.getFile()) ,
					new File("f:\\"+uuid+".png") , alpha);
			if(result){
				//若半透明转化成功则重新加载图片
				image=ImageIO.read(new File("f:\\"+uuid+".png"));
				if(image!=null) {
					graphics.drawImage(image,0,0,null);
					canvas.repaint();
				}
			}else{
				textArea.setText("");
				textArea.append("\n半透明化失败!");
			}	
		}catch(Exception e){
			textArea.append("\n请输入0-255之间的数值!");
		}	
	}
	
	/**
	 * 旋转图片
	 * @throws IOException 
	 */
	private void RotaingImage() throws IOException{
		//接收用户输入的角度
		double angle = Double.parseDouble(textRataing.getText().toString());
		Image imageSrc = ImageIO.read(new File(dialogOpen.getDirectory()+dialogOpen.getFile()));
		BufferedImage save = RotaingImage.Rotate(imageSrc,angle);
		String uuid = UUID.randomUUID().toString();
		ImageIO.write(save, "jpg", new File("f:\\"+uuid+".jpg"));
		image=ImageIO.read(new File("f:\\"+uuid+".jpg"));
		if(image!=null) {
			graphics.drawImage(image,0,0,null);
			canvas.repaint();
		}
	}
}


图片半透明参考:百度经验
原文写的流程是很清晰的,为了更方便学习我在这里做重新排版,思路如下:

1.打开一张图片

BufferedImage imageOpen = ImageIO.read(new File("图像路径"));

2.获取图像每一个点的颜色值

int rgb = imageOpen.getRGB(x, y);

3.为每一个颜色值加上一个alpha值(控制透明度的值)

int rgb = imageOpen.getRGB(x, y);

Color color = new Color(rgb);    Color color = new Color(color.getRed(), color.getGreen(),color.getBlue(), alpha);

4.在一张空白的图像上涂上每一个颜色值

BufferedImage imageSave = new BufferedImage(width, height,BufferedImage.TYPE_INT_ARGB);

imageSave.setRGB(x, y, color.getRGB());

5.保存涂上颜色的图像

ImageIO.write(imageSave, "PNG", new File("保存到的文件的路径"));

其中半透明化代码分离出来,用另一个TranslucentImage类来写:

package java_picture;

import java.awt.Color;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;

public class TranslucentImage {

	/**
	 * 半透明一张图片
	 * @param image 需要半透明的图片所在文件
	 * @param save  半透明之后保存的文件
	 * @param alpha 透明度(0~255)
	 * @return
	 */
	public static boolean Translucent(File image,File save,int alpha){
		//原始图像
		BufferedImage imageOpen = null; 
		//保存图像
		BufferedImage imageSave = null; 
		//图片宽度,高度,临时存放像素点的元素值
		int width,height,rgb;
		//用于计算值的Color对象
		Color color ;
		try {
			imageOpen = ImageIO.read(image);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return false;
		}
		//获取图像宽度
		width = imageOpen.getWidth(); 
		//获取图像高度
		height = imageOpen.getHeight();
		imageSave = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
		//新建空白图像
		for(int x=0 ; x<width ; x++){
			for(int y=0 ; y<height; y++){
				//获取颜色值
				rgb = imageOpen.getRGB(x, y);
				//构建color对象
				color = new Color(rgb);
				//重新构建一次Color对象(有透明值的)
				color = new Color(color.getRed(),color.getGreen(),color.getBlue(),alpha);
				//设置颜色值
				imageSave.setRGB(x, y, color.getRGB());
			}
		}
		//保存图片
		try {
			ImageIO.write(imageSave, "PNG", save);
			
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return false;
		}
		return true;
	}
}

注意事项
1.在创建一张空白图像时.BufferedImage构建函数中第3个参数是创建的图像的颜色模式.因为我们生成的图像是有半透明的,所以这个参数就必须是支持ARGB颜色模式的类型,否则将无法正常生成半透明图像
所以本例中使用了BufferedImage.TYPE_INT_ARGB类型
2.保存图像时,ImageIO.write()方法的第2个参数应该用"PNG",而不应该使用"JPG",因为PNG文件格式是支持Alpha的,而JPG不支持,这样才能保证生成的图像有半透明效果

图片旋转参考:Java实现图片任意角度旋转
旋转代码,用另一个RotaingImage类来写,修改为符合本程序的代码如下:

package java_picture;

import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.image.BufferedImage;


public class RotaingImage {
	    /**
	     * 图像旋转
	     * @param src
	     * @param angel
	     * @return
	     */
	    public static BufferedImage Rotate(Image src, double angel) {
	        int src_width = src.getWidth(null);
	        int src_height = src.getHeight(null);
	        // calculate the new image size
	        Rectangle rect_des = CalcRotatedSize(new Rectangle(new Dimension(
	                src_width, src_height)), angel);
	 
	        BufferedImage res = null;
	        res = new BufferedImage(rect_des.width, rect_des.height,
	                BufferedImage.TYPE_3BYTE_BGR);
	        Graphics2D g2 = res.createGraphics();
	        // transform
	        g2.translate((rect_des.width - src_width) / 2,
	                (rect_des.height - src_height) / 2);
	        g2.rotate(Math.toRadians(angel), src_width / 2, src_height / 2);
	 
	        g2.drawImage(src, null, null);
	        g2.dispose();
	        return res;
	    }
	 
	    public static Rectangle CalcRotatedSize(Rectangle src, double angel) {
	        // if angel is greater than 90 degree, we need to do some conversion
	        if (angel >= 90) {
	            if(angel / 90 % 2 == 1){
	                int temp = src.height;
	                src.height = src.width;
	                src.width = temp;
	            }
	            angel = angel % 90;
	        }
	 
	        double r = Math.sqrt(src.height * src.height + src.width * src.width) / 2;
	        double len = 2 * Math.sin(Math.toRadians(angel) / 2) * r;
	        double angel_alpha = (Math.PI - Math.toRadians(angel)) / 2;
	        double angel_dalta_width = Math.atan((double) src.height / src.width);
	        double angel_dalta_height = Math.atan((double) src.width / src.height);
	 
	        int len_dalta_width = (int) (len * Math.cos(Math.PI - angel_alpha
	                - angel_dalta_width));
	        len_dalta_width=len_dalta_width>0?len_dalta_width:-len_dalta_width;
	 
	        int len_dalta_height = (int) (len * Math.cos(Math.PI - angel_alpha
	                - angel_dalta_height));
	        len_dalta_height=len_dalta_height>0?len_dalta_height:-len_dalta_height;
	 
	        int des_width = src.width + len_dalta_width * 2;
	        int des_height = src.height + len_dalta_height * 2;
	        des_width=des_width>0?des_width:-des_width;
	        des_height=des_height>0?des_height:-des_height;
	        return new java.awt.Rectangle(new Dimension(des_width, des_height));
	    }
}
  • 1
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值