您的位置:首页 > 编程语言 > Java开发

Java图片截图缩放工具

2014-12-21 17:26 127 查看
最近在做一个图像的软件,为了让用户体验更加舒畅,需要对图像进行截取,对于高分辨率的图像,有缩放功能是最好的了。可惜本人技术水平不高,只能去网上到处找源码啊。倒是给我找到了一个图像截取的,嘛,时间太久了,忘了从哪里找到的了,但是可惜它没有图像缩放的功能,就自己摸索着加上去了,写的比较挫,但是使用起来还算可以了。

import java.awt.Color;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Toolkit;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.event.MouseWheelEvent;
import java.awt.event.MouseWheelListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;

import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;

public class ImageCutAndZoomFrame extends JFrame {

/**
*
*/
private static final long serialVersionUID = 1L;

public static void main(String[] args) {
new ImageCutAndZoomFrame("test.jpg", System.getProperty("user.dir"));
}

public ImageCutAndZoomFrame(String imagePath, String targetPath) {
super("图像缩放截取窗口 by 皮皮king1");
BufferedImage bi = null;
try {
bi = ImageIO.read(new File(imagePath));
} catch (IOException e) {
JOptionPane.showMessageDialog(null, "IOException:未能获取图片", "错误",
JOptionPane.ERROR_MESSAGE);
System.exit(0);
}
ImageSnapPanel imageSnapPanel = new ImageSnapPanel(bi, targetPath);
this.add(imageSnapPanel);

// 设置显示大小
Dimension screenDimension = Toolkit.getDefaultToolkit().getScreenSize();
int width = (int) (screenDimension.getWidth() * 0.7 > bi.getWidth() ? bi
.getWidth() : screenDimension.getWidth() * 0.7);
int height = (int) (screenDimension.getHeight() * 0.7 > bi.getHeight() ? bi
.getHeight() : screenDimension.getHeight() * 0.7);
double rate = (double) bi.getHeight() / (double) bi.getWidth();
if (screenDimension.getHeight() < screenDimension.getWidth())
width = (int) ((double) height / rate);
else
height = (int) ((double) width * rate);
this.setSize(width, height);
this.setLocation(
(int) ((screenDimension.getWidth() - this.getWidth()) / 2),
(int) ((screenDimension.getHeight() - this.getHeight()) / 2));

this.setVisible(true);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}

}

/**
* 真正用于图像裁剪的类
*
*/
class ImageSnapPanel extends JPanel implements MouseListener,
MouseMotionListener, MouseWheelListener {

/**
*
*/
private static final long serialVersionUID = 1L;
private BufferedImage srcBi;
private BufferedImage bi;
private int startX, startY, endX, endY, tempX, tempY;
private Rectangle select = new Rectangle(0, 0, 0, 0);// 表示选中的区域
private Cursor cs = new Cursor(Cursor.CROSSHAIR_CURSOR);// 表示一般情况下的鼠标状态(十字线)
private States current = States.DEFAULT;// 表示当前的编辑状态
private Rectangle[] rec;// 表示八个编辑点的区域
// 下面四个常量,分别表示谁是被选中的那条线上的端点
public static final int START_X = 1;
public static final int START_Y = 2;
public static final int END_X = 3;
public static final int END_Y = 4;
private int currentX, currentY;// 当前被选中的X和Y,只有这两个需要改变
private Point p = new Point();// 当前鼠标移的地点
private boolean showTip = true;// 是否显示提示.如果鼠标左键一按,则提示就不再显示了
private BufferedImage get;
// private ImageSnapDialog imageSnapDialog;
private String targetPath;

private int times;// 放大或缩小倍数
int xL = 0;// 坐标点左侧距离
int xR = 0;// 坐标点右侧距离
int yB = 0;// 坐标点下方距离
int yA = 0;// 坐标点上方距离
int x, y, w, h;

/**
* 构造函数
*
* @param bi
* 传入的图片BufferedImage
* @param targetPath
* 截图存储目录
*/
public ImageSnapPanel(BufferedImage bi, String targetPath) {
// this.imageSnapDialog = (ImageSnapDialog) imageSnapDialog;

this.srcBi = bi;
this.bi = bi;
this.targetPath = targetPath;
this.addMouseListener(this);
this.addMouseMotionListener(this);
this.addMouseWheelListener(this);
initRecs();
}

private void initRecs() {
rec = new Rectangle[8];
for (int i = 0; i < rec.length; i++) {
rec[i] = new Rectangle();
}
}

public void paintComponent(Graphics g) {
g.drawImage(bi, 0, 0, this.getWidth(), this.getHeight(), this);
g.setColor(Color.RED);
g.drawLine(startX, startY, endX, startY);
g.drawLine(startX, endY, endX, endY);
g.drawLine(startX, startY, startX, endY);
g.drawLine(endX, startY, endX, endY);
int x = startX < endX ? startX : endX;
int y = startY < endY ? startY : endY;
select = new Rectangle(x, y, Math.abs(endX - startX), Math.abs(endY
- startY));
int x1 = (startX + endX) / 2;
int y1 = (startY + endY) / 2;
g.fillRect(x1 - 2, startY - 2, 5, 5);
g.fillRect(x1 - 2, endY - 2, 5, 5);
g.fillRect(startX - 2, y1 - 2, 5, 5);
g.fillRect(endX - 2, y1 - 2, 5, 5);
g.fillRect(startX - 2, startY - 2, 5, 5);
g.fillRect(startX - 2, endY - 2, 5, 5);
g.fillRect(endX - 2, startY - 2, 5, 5);
g.fillRect(endX - 2, endY - 2, 5, 5);
rec[0] = new Rectangle(x - 5, y - 5, 10, 10);
rec[1] = new Rectangle(x1 - 5, y - 5, 10, 10);
rec[2] = new Rectangle((startX > endX ? startX : endX) - 5, y - 5, 10,
10);
rec[3] = new Rectangle((startX > endX ? startX : endX) - 5, y1 - 5, 10,
10);
rec[4] = new Rectangle((startX > endX ? startX : endX) - 5,
(startY > endY ? startY : endY) - 5, 10, 10);
rec[5] = new Rectangle(x1 - 5, (startY > endY ? startY : endY) - 5, 10,
10);
rec[6] = new Rectangle(x - 5, (startY > endY ? startY : endY) - 5, 10,
10);
rec[7] = new Rectangle(x - 5, y1 - 5, 10, 10);
if (showTip) {
g.setColor(Color.CYAN);
g.fillRect(p.x, p.y, 350, 20);
g.setColor(Color.RED);
g.drawRect(p.x, p.y, 350, 20);
g.setColor(Color.BLACK);
g.drawString("左键选择,右键取消,双击截图,滚轮缩放", p.x, p.y + 15);
}
}

// 根据东南西北等八个方向决定选中的要修改的X和Y的座标
private void initSelect(States state) {
switch (state) {
case DEFAULT:
currentX = 0;
currentY = 0;
break;
case EAST:
currentX = (endX > startX ? END_X : START_X);
currentY = 0;
break;
case WEST:
currentX = (endX > startX ? START_X : END_X);
currentY = 0;
break;
case NORTH:
currentX = 0;
currentY = (startY > endY ? END_Y : START_Y);
break;
case SOUTH:
currentX = 0;
currentY = (startY > endY ? START_Y : END_Y);
break;
case NORTH_EAST:
currentY = (startY > endY ? END_Y : START_Y);
currentX = (endX > startX ? END_X : START_X);
break;
case NORTH_WEST:
currentY = (startY > endY ? END_Y : START_Y);
currentX = (endX > startX ? START_X : END_X);
break;
case SOUTH_EAST:
currentY = (startY > endY ? START_Y : END_Y);
currentX = (endX > startX ? END_X : START_X);
break;
case SOUTH_WEST:
currentY = (startY > endY ? START_Y : END_Y);
currentX = (endX > startX ? START_X : END_X);
break;
default:
currentX = 0;
currentY = 0;
break;
}
}

public void mouseMoved(MouseEvent me) {
doMouseMoved(me);
initSelect(current); // current:当前状态(state)
if (showTip) {
p = me.getPoint();
repaint();
}
}

// 特意定义一个方法处理鼠标移动,是为了每次都能初始化一下所要选择的区域
private void doMouseMoved(MouseEvent me) {
if (select.contains(me.getPoint())) {
this.setCursor(new Cursor(Cursor.MOVE_CURSOR));
current = States.MOVE;
} else {
States[] st = States.values();
for (int i = 0; i < rec.length; i++) {
if (rec[i].contains(me.getPoint())) {
current = st[i];
this.setCursor(st[i].getCursor());
return;
}
}
this.setCursor(cs);
current = States.DEFAULT;
}
}

public void mouseExited(MouseEvent me) {
}

public void mouseEntered(MouseEvent me) {
}

public void mouseDragged(MouseEvent me) {
int x = me.getX();
int y = me.getY();
// 分别处理一系列的(光标)状态(枚举值)
if (current == States.MOVE) {
startX += (x - tempX);
startY += (y - tempY);
endX += (x - tempX);
endY += (y - tempY);
tempX = x;
tempY = y;
} else if (current == States.EAST || current == States.WEST) {
if (currentX == START_X) {
startX += (x - tempX);
tempX = x;
} else {
endX += (x - tempX);
tempX = x;
}
} else if (current == States.NORTH || current == States.SOUTH) {
if (currentY == START_Y) {
startY += (
a7b4
y - tempY);
tempY = y;
} else {
endY += (y - tempY);
tempY = y;
}
} else if (current == States.NORTH_EAST || current == States.NORTH_WEST
|| current == States.SOUTH_EAST || current == States.SOUTH_WEST) {
if (currentY == START_Y) {
startY += (y - tempY);
tempY = y;
} else {
endY += (y - tempY);
tempY = y;
}
if (currentX == START_X) {
startX += (x - tempX);
tempX = x;
} else {
endX += (x - tempX);
tempX = x;
}
} else {
startX = tempX;
startY = tempY;
endX = me.getX();
endY = me.getY();
}
this.repaint();
}

public void mousePressed(MouseEvent me) {
showTip = false;
tempX = me.getX();
tempY = me.getY();
}

public void mouseReleased(MouseEvent me) {
if (me.isPopupTrigger()) { // 右键
showTip = true;
p = me.getPoint();
startX = 0;
startY = 0;
endX = 0;
endY = 0;
repaint();
}
}

public void mouseClicked(MouseEvent me) {
int x = (int) ((double) me.getX() / (double) this.getWidth() * (double) srcBi
.getWidth());
int y = (int) ((double) me.getY() / (double) this.getHeight() * (double) srcBi
.getHeight());
System.out.println("鼠标点击坐标:" + me.getX() + "," + me.getY()
+ " 在源图中的实际坐标为:" + x + "," + y + " 窗口大小为:" + this.getWidth()
+ "," + this.getHeight());
System.out.println();
if (me.getClickCount() == 2) {
// Rectangle rec=new
// Rectangle(startX,startY,Math.abs(endX-startX),Math.abs(endY-startY));
Point p = me.getPoint();
if (select.contains(p)) {

int startx = (int) ((double) select.x
/ (double) this.getWidth() * (double) bi.getWidth());
int starty = (int) ((double) select.y
/ (double) this.getHeight() * (double) bi.getHeight());

int width = (int) ((double) select.width
/ (double) this.getWidth() * (double) bi.getWidth());
int height = (int) ((double) select.height
/ (double) this.getHeight() * (double) bi.getHeight());
if (startx < 0) {
width += startx;
startx = 0;

} else if (startx > bi.getWidth())
startx = bi.getWidth();
if (starty < 0) {
height += starty;
starty = 0;
} else if (starty > bi.getHeight())
starty = bi.getHeight();

if (select.x + select.width > this.getWidth()
|| select.y + select.height > this.getHeight()) {
if (select.x + select.width >= this.getWidth()) {
width = bi.getWidth() - startx;
}
if (select.y + select.height >= this.getHeight()) {
height = bi.getHeight() - starty;
}
}

System.out.println(startx + " " + starty + " " + width + " "
+ height);
get = bi.getSubimage(startx, starty, width, height);

System.out.println("截图区域为:从(" + startx + "," + starty
+ ") 开始长宽为(" + width + "," + height + ") 的区域");

// 以时间为名称,保存到文件
String format = "jpg";
File file = new File(
targetPath
+ File.separator
+ new SimpleDateFormat("yyyyMMddHHmmss")
.format(new Date()) + "." + format);
try {
ImageIO.write(get, format, file);
JOptionPane.showMessageDialog(null,
"成功截图,文件存放在:" + file.getCanonicalPath());
} catch (IOException e) {
e.printStackTrace();
}
}
}
}

public BufferedImage getGet() {
return get;
}

public void setGet(BufferedImage get) {
this.get = get;
}

public void mouseWheelMoved(MouseWheelEvent e) {
int wheelRotation = e.getWheelRotation();// 鼠标滚轮向前转-1,向后转+1
times += wheelRotation;
times = times > 0 ? 0 : times;
times = times < -9 ? -9 : times;

if (times < 0) {// 负数表示当前为放大
int tempTimes = Math.abs(times);
// 获得缩放中心点在srcBi中的实际距离
xL = (int) ((double) e.getX() * (double) srcBi.getWidth() / (double) this
.getWidth());
yA = (int) ((double) e.getY() * (double) srcBi.getHeight() / (double) this
.getHeight());

if (w != 0) {
xL = (int) ((double) e.getX() / (double) this.getWidth() * w + x);
yA = (int) ((double) e.getY() / (double) this.getHeight() * h + y);
}
xR = srcBi.getWidth() - xL;
yB = srcBi.getHeight() - yA;
System.out.println("初始点位(xL、yA、xR、yB):" + xL + " " + yA + " " + xR
+ " " + yB);
x = xL * tempTimes / 10;
y = yA * tempTimes / 10;
w = srcBi.getWidth() - x - xR * tempTimes / 10;
h = srcBi.getHeight() - y - yB * tempTimes / 10;
System.out.println("放大倍数:" + times + "截图区域x,y,w,h:" + x + " " + y
+ " " + w + " " + h);
bi = srcBi.getSubimage(x, y, w, h);
} else {
bi = srcBi;
}
this.repaint();
}

}

enum States {
NORTH_WEST(new Cursor(Cursor.NW_RESIZE_CURSOR)), NORTH(new Cursor(
Cursor.N_RESIZE_CURSOR)), NORTH_EAST(new Cursor(
Cursor.NE_RESIZE_CURSOR)), EAST(new Cursor(Cursor.E_RESIZE_CURSOR)), SOUTH_EAST(
new Cursor(Cursor.SE_RESIZE_CURSOR)), SOUTH(new Cursor(
Cursor.S_RESIZE_CURSOR)), SOUTH_WEST(new Cursor(
Cursor.SW_RESIZE_CURSOR)), WEST(new Cursor(Cursor.W_RESIZE_CURSOR)), MOVE(
new Cursor(Cursor.MOVE_CURSOR)), DEFAULT(new Cursor(
Cursor.DEFAULT_CURSOR));

private Cursor cs;

States(Cursor cs) {
this.cs = cs;
}

public Cursor getCursor() {
return cs;
}
}


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  java 图片 截图 缩放