一个简单的图片编辑器
背景:一个同学问我怎样将一个图片显示在窗体上面,我解决之后,于是想为什么不加上一些其他的功能呢?
功能:截图、逆时针旋转、顺时针旋转、水平旋转、垂直旋转、放大、缩小。
代码:
这包括三个类-----1、图形编辑类。2、界面类。3、改变图形类
public class Imagedit {
private static JFrame frame;
public static void main(String[] args) {
frame = new TransformFrame();
frame.setVisible(true);
// frame.add(new DivideImage(new File("D://p_head_KKKV_61160000061f2d0f.jpg")));
}
public static JFrame getFrame(){
return frame;
}
}
class TransformFrame extends JFrame implements ActionListener {
JButton open = new JButton("打开");
JButton save = new JButton("保存");
JButton rote1 = new JButton("逆时针");
JButton rote = new JButton("顺时针");
JButton flipX = new JButton("水平翻转");
JButton flipY = new JButton("垂直翻转");
JButton zoomIn = new JButton("放大");
JButton zoomOut = new JButton("缩小");
public TransformFrame() {
setTitle("Java图片处理");
setSize(400, 400);
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
Container contentPane = getContentPane();
canvas = new TransPanel();
contentPane.add(canvas, "Center");
JPanel buttonPanel = new JPanel();
buttonPanel.add(open);
open.addActionListener(this);
buttonPanel.add(save);
save.addActionListener(this);
buttonPanel.add(rote1);
rote1.addActionListener(this);
buttonPanel.add(rote);
rote.addActionListener(this);
buttonPanel.add(flipX);
flipX.addActionListener(this);
buttonPanel.add(flipY);
flipY.addActionListener(this);
buttonPanel.add(zoomIn);
zoomIn.addActionListener(this);
buttonPanel.add(zoomOut);
zoomOut.addActionListener(this);
contentPane.add(buttonPanel, "North");
}
public void actionPerformed(ActionEvent event) {
Object source = event.getSource();
if (source == rote1) {
canvas.setRotate1();
}
if (source == rote) {
canvas.setRotate();
} else if (source == flipX) {
canvas.flipX();
} else if (source == flipY) {
canvas.flipY();
} else if (source == zoomIn) {
canvas.zoomIn();
} else if (source == zoomOut) {
canvas.zoomOut();
} else if (source == save) {
canvas.save();
}
else if(source==open){
canvas.open();
}
}
private TransPanel canvas;
}
class TransPanel extends JPanel {
JTextPane jTextPane1 = new JTextPane();
//水平翻转比例的标志。-1表示需要进行水平翻转
int m_nFlipXScale = 1;
//垂直翻转比例的标志。-1表示需要进行垂直翻转
int m_nFlipYScale = 1;
//旋转的角度。因为工程需要,代码中直接写成了90,可以根据具体需要动态修改,以符合实际情况
int roteAngle = 0;
//缩放比例。默认的比例0表示没有翻转,具体的翻转大小通过一个方法:getZoomSize()获取
int zoomLevel = 0;
public TransPanel() {
img = new ImageIcon("").getImage();
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(img, 0, 0, this);
drawTransImage(g, img.getWidth(this), img.getHeight(this), zoomLevel);
}
public void drawTransImage(Graphics g, int drawx, int drawy, int zoom) {
int x = 0;
int y = 0;
int w = img.getWidth(this);
int h = img.getHeight(this);
int zoomw = getZoomSize(w, zoom);
int zoomh = getZoomSize(h, zoom);
int xPos = 0;
int yPos = 0;
if (m_nFlipXScale == -1) {
xPos = -zoomw;
}
if (m_nFlipYScale == -1) {
yPos = -zoomh;
}
Graphics2D g2 = (Graphics2D) g;
//转换坐标原点。这步不要也成,但是将当前位置转换为坐标原点后,可以节省好多计算步骤,非常好用。
//不过记得用完了以后,一定要把原点转换回来,要不然其他地方就乱了
g2.translate(drawx, drawy);
if (roteAngle != 0) {
g2.rotate(Math.toRadians(m_nFlipXScale * m_nFlipYScale * roteAngle), zoomw >> 1, zoomh >> 1);
}
//上面的m_nFlipXScale * m_nFlipYScale需要特殊说明一下:因为实际使用中,可能遇到各种组合的情况,比如
//先flipX或者flipY以后然后再旋转,这时候,图片的旋转方向就会出现错误,加上这段代码可以保证无论使用哪种组合
//操作方式,都保证在旋转图片的时候是按照顺时针的方向进行旋转。
if (m_nFlipXScale == -1) {
g2.scale(-1, 1);//第一个值表示水平,-1表示等宽水平翻转,Math.abs(m_nFlipXScale)的值越大,出来的图片就越宽
}
if (m_nFlipYScale == -1) {
g2.scale(1, -1);//第二个值表示垂直,-1表示等高垂直翻转,Math.abs(m_nFlipYScale)的值越大,出来的图片就越高
} //显示图片
g2.drawImage(img, xPos, yPos, xPos + zoomw, yPos + zoomh, x, y, w, h, null);
g2.translate(-drawx, -drawy);
}
//实现逆时针的方法
public void setRotate1() {
roteAngle -= 90;
roteAngle %= 360;
repaint();
}
//实现顺时针的方法
public void setRotate() {
roteAngle += 90;
roteAngle %= 360;
repaint();
}
//实现水平移动的方法
public void flipX() {
m_nFlipXScale = -m_nFlipXScale;
repaint();
}
public void flipY() {
m_nFlipYScale = -m_nFlipYScale;
repaint();
}
//放大的方法
public void zoomIn() {
zoomLevel++;
repaint();
}
//缩小的方法
public void zoomOut() {
zoomLevel--;
repaint();
}
public void open(){//
JFileChooser chooser=new JFileChooser();
// chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
int result=chooser.showOpenDialog(null);
if(result==JFileChooser.APPROVE_OPTION){
String filePath=chooser.getSelectedFile().getPath();
JFrame frame = Imagedit.getFrame();
frame.add(new DivideImage(new File(filePath)));
img = new ImageIcon(filePath).getImage();
// System.out.println(frame);
frame.setVisible(true);
System.out.println(filePath);
}
}
/**
* 保存图片的方法
*/
public void save() {
JFileChooser fc = new JFileChooser();
int returnVal = fc.showSaveDialog(this);
if (returnVal == JFileChooser.APPROVE_OPTION) {
String savefile = fc.getSelectedFile().getPath();
if (savefile == null) {
return;
} else {
String docToSave = jTextPane1.getText();
if (docToSave != null) {
ObjectOutputStream fstrm = null;
BufferedOutputStream ostrm = null;
try {
fstrm = new ObjectOutputStream(new FileOutputStream(savefile));
ostrm = new BufferedOutputStream(fstrm);
byte[] bytes = null;
try {
bytes = docToSave.getBytes();
} catch (Exception e1) {
e1.printStackTrace();
}
ostrm.write(bytes);
} catch (IOException io) {
System.err.println("IOException: " +
io.getMessage());
} finally {
try {
ostrm.flush();
fstrm.close();
ostrm.close();
} catch (IOException ioe) {
System.err.println("IOException: " +
ioe.getMessage());
}
}
}
}
}
return;
}
public static final int getZoomSize(int sourceSize, int zoomLevel) {
if (zoomLevel == 0) {
return sourceSize;
} else if (zoomLevel < 0) {
return sourceSize / (Math.abs(zoomLevel) + 1);
} else {
return sourceSize * (zoomLevel + 1);
}
}
private Image img;
}
下面是截取图片类
//截取图片类
public class DivideImage extends JPanel {
BufferedImage image = null;
int x1, y1, x2, y2;
public DivideImage(File file) {
super();
this.addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent e) {
x1 = e.getX();
y1 = e.getY();
}
public void mouseReleased(MouseEvent e) {
x2 = e.getX();
y2 = e.getY();
int x = x1 < x2 ? x1 : x2;
int y = y1 < y2 ? y1 : y2;
int w = (x1 > x2 ? x1 : x2) - x;
int h = (y1 > y2 ? y1 : y2) - y;
Image image = DivideImage.this.getImageByClip(x, y, w, h);
setClipboardImage2(image);
x1 = y1 = x2 = y2 = 0;
JOptionPane.showMessageDialog(DivideImage.this, "图片已保存到系统粘贴板!", "图片已保存", JOptionPane.INFORMATION_MESSAGE);
DivideImage.this.repaint();
}
});
this.addMouseMotionListener(new MouseMotionAdapter() {
public void mouseDragged(MouseEvent e) {
x2 = e.getX();
y2 = e.getY();
DivideImage.this.repaint();
}
});
try {
image = ImageIO.read(file);
} catch (IOException e) {
System.out.println("请输入一个图片文件!");
}
}
public Image getImage() {
return image;
}
public Image getImageByClip(int x, int y, int w, int h) {
int rgbs[] = new int[w * h];
rgbs = image.getRGB(x, y, w, h, rgbs, 0, w);
BufferedImage tmpImage = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
tmpImage.setRGB(0, 0, w, h, rgbs, 0, w);
return tmpImage;
}
public void paint(Graphics g) {
super.paint(g);
g.drawImage(image, 0, 0, this);
System.out.println("(" + x1 + "," + y1 + ")(" + x2 + "," + y2 + ")");
if (x1 == 0 && y1 == 0 && x2 == 0 && y2 == 0) {
return;
}
System.out.println("rect");
int x = x1 < x2 ? x1 : x2;
int y = y1 < y2 ? y1 : y2;
int w = (x1 > x2 ? x1 : x2) - x;
int h = (y1 > y2 ? y1 : y2) - y;
g.setColor(Color.blue);
g.drawRect(x, y, w, h);
}
protected static void setClipboardImage2(final Image image) {
Transferable trans = new Transferable() {
public DataFlavor[] getTransferDataFlavors() {
return new DataFlavor[]{DataFlavor.imageFlavor};
}
public boolean isDataFlavorSupported(DataFlavor flavor) {
return DataFlavor.imageFlavor.equals(flavor);
}
public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException {
if (isDataFlavorSupported(flavor)) {
return image;
}
throw new UnsupportedFlavorException(flavor);
}
};
Toolkit.getDefaultToolkit().getSystemClipboard().setContents(trans, null);
}
}
分享到:
相关推荐
在IT领域,图片编辑软件是常见的工具,它们用于对图像进行各种操作,以达到美化、修改或分析的目的。本文将详细介绍基于C++开发的一款简单图片编辑软件,它具备了多种功能,包括放大、缩小、旋转、噪声处理、...
帮助开发者快速构建图片编辑器应用 它是一款基于Fabric + Vue3开发的一款开源Web图片编辑器,二次开发简单、扩展便捷,可帮助开发者快速构建一个面向非专业设计人员的图形编辑器。 项目以Fabric.js 为底层,使用Vue...
【标题】:基于canvas的移动端图片编辑插件 在移动互联网时代,图片编辑已经成为许多应用程序不可或缺的功能,尤其在移动端H5页面和微信小程序中。基于canvas的图片编辑插件为开发者提供了一种轻量级、高效且灵活的...
在现代Web应用中,前端开发领域的一个重要工具是图片编辑器。本文将深入探讨一个纯前端JavaScript实现的图片编辑器,它可以提供丰富的功能,如图片剪切、合成、变色等,极大地增强了用户在浏览器端对图像进行处理的...
在本文中,我们将深入探讨如何使用Qt 4.7库实现一个简单的图片编辑器,重点关注C++中的继承概念。Qt是一个强大的跨平台应用程序开发框架,特别适合创建图形用户界面(GUI)应用,如图片编辑器。 首先,让我们理解...
在本文中,我们将深入探讨基于C#的Winform图片编辑应用程序。这个程序提供了一个用户友好的界面,允许用户进行基本的图像编辑操作,如使用画笔、画板和颜色选择,以及撤销和保存功能。以下是关于这些核心概念的详细...
【资源介绍】基于vue和fabric.js的图片编辑器网页源码+项目说明(含demo演示地址).zip基于vue和fabric.js的图片编辑器网页源码+项目说明(含demo演示地址).zip基于vue和fabric.js的图片编辑器网页源码+项目说明(含demo...
例如,`<canvas>`元素允许在网页上进行动态图形绘制,这对于图片编辑功能至关重要,可以实现实时的图像操作,如裁剪、旋转、滤镜效果等。另外,`<video>`和`<audio>`元素则简化了多媒体内容的集成,使得用户可以直接...
这款编辑器允许用户无需上传文件即可对图片进行高效处理,提高了图片编辑的效率和用户体验。 首先,我们要了解PHP作为服务器端脚本语言,在Web开发中的核心作用。PHP(Hypertext Preprocessor)是一种开源的、跨...
【基于canvas的前端图片编辑器】是一种利用HTML5的Canvas元素构建的轻量级、高度交互的图片编辑工具。Canvas是HTML5中的一个重要特性,它允许开发者在网页上进行动态图形绘制,为创建复杂的图像编辑功能提供了可能。...
在本文中,我们将深入探讨如何使用C# WinForm开发一个简单的图片编辑器,该编辑器具备本地图片加载、缩放以及按比例缩放的功能。在C#编程环境中,WinForm是一个常用的用户界面库,用于创建桌面应用程序。我们将讨论...
其中,微信的图片编辑功能尤其受到用户喜爱,特别是涂鸦、马赛克和裁剪等工具,使得用户可以方便地对图片进行个性化处理。下面将详细探讨这些功能的实现原理和相关知识点。 1. 图片编辑基础 在图像处理领域,编辑...
【图片编辑核心代码】在Android开发中,图片编辑是一个常见的需求,可以实现一系列图像处理功能,如缩放、旋转、裁剪以及调整亮度和饱和度等。以下将详细讲解图片编辑的核心代码及其工作原理。 首先,为了从SDCard...
标题中的“搞笑图片编辑器 可用多张图片编辑成幻灯片”指的是一个软件工具,主要用于将多张静态图片组合并编辑成动态效果,如幻灯片展示或GIF动画。这种编辑器通常包含一系列功能,使得用户可以轻松地进行图片的拼接...
在Android平台上,图片编辑功能是许多应用程序不可或缺的一部分,如社交应用、相册应用等。本教程将探讨如何在Android中实现图片的旋转、放大缩小、剪裁以及添加网格等常见编辑功能,通过内存缓存机制确保操作的高效...
标题中的“Flash图片编辑器”指的是一个基于Adobe Flash平台的图像处理工具,它允许用户对图像进行各种编辑操作。在Web开发中,Flash曾广泛用于创建动态内容和交互式应用程序,包括图片编辑器这种功能丰富的工具。这...
在IT行业中,图片编辑器是不可或缺的工具,尤其在设计、开发、营销等领域。这个名为“一个简洁的图片编辑器”的应用,正如其标题所言,旨在提供简单易用但功能丰富的图片处理体验,适用于各种项目需求。描述中提到的...
【资源说明】 1、该资源包括项目的全部源码,下载可以直接使用! ...高仿微信的图片编辑器源码+项目说明(画笔(paint),贴图(sticker),添加文字(add text),马赛克(mosaic),截图(crop)功能).zip
《使用Delphi构建图片编辑器》 在编程领域,Delphi是一种强大的面向对象的编程环境,以其高效、直观和丰富的组件库而闻名。本项目利用Delphi开发了一款简易的图片编辑器,虽然功能相对简单,但对于初学者来说,它是...
微软在不同版本的操作系统中都提供了内置的图片编辑工具,从早期的Windows XP到后来的Windows 7,画图程序经历了不断的演变和功能增强。近期,一种号称“仿win7”的图片编辑软件出现在市场上,以其简单易用性和丰富...