一个简单的图片编辑器
背景:一个同学问我怎样将一个图片显示在窗体上面,我解决之后,于是想为什么不加上一些其他的功能呢?
功能:截图、逆时针旋转、顺时针旋转、水平旋转、垂直旋转、放大、缩小。
代码:
这包括三个类-----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);
}
}
分享到:
相关推荐
帮助开发者快速构建图片编辑器应用 它是一款基于Fabric + Vue3开发的一款开源Web图片编辑器,二次开发简单、扩展便捷,可帮助开发者快速构建一个面向非专业设计人员的图形编辑器。 项目以Fabric.js 为底层,使用Vue...
基于C++的简单图片编辑软件,包含放大,缩小,旋转,噪声,拉普拉斯变换,边缘提取等等功能。
C# winform 图片编辑器 实现本地载入 缩放 按比例缩放功能 C# winform 图片编辑器 实现本地载入 缩放 按比例缩放功能
纯前端js图片编辑器、可实现图片剪切、合成、变色等等各种功能
该插件是一款脱离jq的移动端图片编辑器。可以应用在移动端H5页面或者微信小程序中。
图片编辑HTML5网页模板
Google图片编辑工具
基于canvas的纯前端的图片编辑器,支持方形,圆形,箭头,缩放,拖拽,鹰眼,马赛克,涂鸦,线条,导出png,剪切等
c#c#图片编辑软件 有简单的图片编辑功能图片编辑软件 有简单的图片编辑功能
一个简洁的图片编辑器,放大器, 图片水印(图片水印、文字水印) 适用大部分项目
图片编辑的核心代码,主要是为了赚取积分下载东西
仿微信图片编辑涂鸦、马赛克、裁剪
使用Pure MVC开发的flex 图片编辑器
工具类网站源码,多功能在线图片编辑器源码 加水印加文字修剪等 无需上传文件的多功能图片批量处理程序
android 图片编辑软件,实现图片的旋转,放大缩小,剪裁,网格等,用内存缓存实现,操作起来很强大稳定,具有很好的参考价值。代码中有少量的c++文件,需要编译成so文件。
C#简易图片编辑器 vs2010
qt4.7 实现图片编辑 包括打开图片,在图片上画线条,线条颜色,宽度改变!保存编辑的图片!内容很简单 一看就懂 主要知识点就是c++中的继承知识!
三国志11威力加强版事件图片编辑器 支持大宇的大富翁8、天使帝国3、阿猫阿狗2 支持光谱的三国立志传3 打开轩辕剑5的IMD文件时将直接读取TBL中的索引,不再需要预扫文件 修正上一版本不能读取光谱的富甲天下3&4...
另外,对于编程人员,您可以把Phocasa嵌入到您的程序中,给软件增加图片编辑功能,只需要去官方申请许可,即可 Phocasa 使用说明 下载解压后,运行 phocasa.exe,即可打开程序,然后打开一张图片 选择
一款自定义多选相册、单张图片编辑、旋转、裁剪功能