java swing中简单图片编辑器(图片缩放、半透明化、旋转)
本文介绍了一个简单的图片编辑器,可以实现图片的固定长宽显示、放大一倍显示、缩小一半显示,以及半透明化存储到本地。本文写给我的朋友,助她初入java。
程序界面展示
按钮说明
- 点击左上角文件之后有四个选项,点击打开图片按钮,弹出文件选择器,选择一张图片就会显示在当前界面;
- 保存图片会将已经打开的图片保存到指定目录,在保存的时候需要填写完整的图片名称,包括扩展名;
- 图片放大一倍会将当前显示图片放大一倍显示;
- 图片缩小一倍会将当前显示图片缩小一倍显示;
- 固定缩放需要填写左面的长度和宽度,需是正整数,程序代码中可自定义长宽的临界值;
- 图片透明需要在左面透明度填写0~255之间的数值,填写完数值之后点击图片透明会保存在指定盘中;
- 图片旋转需要在左面旋转角度填写一个数值,填写完数值之后点击图片旋转会将旋转过的图片保存在指定盘中,并将旋转过后的图片再次显示在界面;
代码结构
- src
- java_picture
- DialogDemo.java --主界面
- TranslucentImage.java --图片透明处理
- RotaingImage.java --图片旋转处理
- java_picture
界面代码
代码参考了: 霜沐林的博客
在源代码上做了一些修改,先建一个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));
}
}