同事之前的软件到期了,又不想续费,还不知道怎么破解,所以我就帮他做了一个切图工具,想要的私我,因为是有空做的,主要就是为了实现最基本的切图,所以会有一些测不到的bug,也就没有放到github上面,如果用了,遇到一些想让我改的bug,可以和我说,我有空就改一下。
距做完这个都过几个月了,一直拖着没发。
接下来我放一些最主要的代码,java bean那些简单的就不放了,知道就好,我也会适当注释一下,我也会说一下怎么把jar转为exe
之前是那个啥,用的是SelectFile 弹出选择文件对话框,后来又改成了用文件拖拽控件DropTarget拖动,其实没差
PicDivTool.java
package sc.pro.tool;
//不删,任性
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.HeadlessException;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.Toolkit;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.dnd.DnDConstants;
import java.awt.dnd.DropTarget;
import java.awt.dnd.DropTargetAdapter;
import java.awt.dnd.DropTargetDropEvent;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import javax.imageio.ImageIO;
import javax.imageio.ImageReadParam;
import javax.imageio.ImageReader;
import javax.imageio.stream.ImageInputStream;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.border.Border;
import javax.swing.border.LineBorder;
//用的这个库解析json,而且生成exe也要引进去,想要也私我
import org.json.JSONObject;
import sc.pro.bean.JsonContent;
import sc.pro.bean.JsonInfo;
import sc.pro.bean.PicInfo;
import sc.pro.bean.SavePathInfo;
public class PicDivTool extends JFrame {
public static String SELECTPIC = "选择图片:";
public static String SELECTJSON = "选择Json自动匹配Pic:";
public static String SETPATH = "选择保存路径:";
public static String SAVEPIC = "确认切图";
public static String PNG = ".png";
private JTextArea jta1;
private JTextArea jta2;
private JTextArea jta3;
private Border border = BorderFactory.createEmptyBorder(5, 5, 5, 5);
Map<String, JsonContent> map = new HashMap<>();
private JsonInfo jInfo;
private PicInfo pInfo;
private SavePathInfo sInfo;
private ActionListener listener = new ActionListener() {
public void actionPerformed(ActionEvent e) {
JButton b = (JButton) e.getSource();
String label = b.getText();
if (label.equals(SAVEPIC)) {
//根据那个按钮text绑定动作,之前是三个,现在是拖动就剩一个了
b.addActionListener(new SavePic());
}
}
};
//获取json和图片的,其实图片就是改个后缀,因为文件名是一样的
private DropTargetAdapter adapter2 = new DropTargetAdapter() {
public void drop(DropTargetDropEvent d) {
try {
Transferable tf = d.getTransferable();
if (tf.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) {
d.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
List lt = (List) tf.getTransferData(DataFlavor.javaFileListFlavor);
Iterator itor = lt.iterator();
if (itor.hasNext()) {
File f = (File) itor.next();
jInfo = new JsonInfo("", f.getAbsolutePath());
String jsonContent = getContent(f.getAbsolutePath());
operateJson(jsonContent);
String jsonPathTemp = f.getAbsolutePath();
String picPathName = jsonPathTemp.substring(0, jsonPathTemp.lastIndexOf(".")) + ".png";
pInfo = new PicInfo("", picPathName);
jta2.setText(f.getAbsolutePath() + "\n" + picPathName);
}
d.dropComplete(true);
} else {
d.rejectDrop();
}
} catch (Exception e) {
}
}
};
//获取保存路径的
private DropTargetAdapter adapter3 = new DropTargetAdapter() {
public void drop(DropTargetDropEvent d) {
try {
Transferable tf = d.getTransferable();
if (tf.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) {
d.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
List lt = (List) tf.getTransferData(DataFlavor.javaFileListFlavor);
Iterator itor = lt.iterator();
if (itor.hasNext()) {
File f = (File) itor.next();
jta3.setText("\n" + f.getAbsolutePath());
sInfo = new SavePathInfo(f.getAbsolutePath());
}
d.dropComplete(true);
} else {
d.rejectDrop();
}
} catch (Exception e) {
}
}
};
public PicDivTool() {
super();
}
public PicDivTool(String title) throws HeadlessException {
super(title);
initFrame();
initPB();
}
// 总窗体
private void initFrame() {
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
this.setLocation(500, 300);
this.setSize(450, 480);
this.setResizable(false);
}
// 内面板
private void initPB() {
initPanel();
}
private void initPanel() {
JPanel panel = new JPanel();
panel.setBorder(border);
panel.setLayout(new GridLayout(6, 1));
createDragPanel(panel);
this.add(panel, BorderLayout.CENTER);
}
//生成里面的那些界面什么的
private void createDragPanel(JPanel panel) {
// JLabel jl1 = new JLabel(SELECTPIC);
JLabel jl2 = new JLabel(SELECTJSON);
JLabel jl3 = new JLabel(SETPATH);
//因为同事连图片都不想拖,所以把这个去掉了,上面的adapter删掉了,然后加个改后缀的
// jta1 = new JTextArea();
// jta1.setEditable(false);
// jta1.setBackground(new java.awt.Color(166, 235, 220));
// jta1.setBorder(new LineBorder(new java.awt.Color(121, 232, 208), 3));
//拖json的区域
jta2 = new JTextArea();
jta2.setEditable(false);
jta2.setBackground(new java.awt.Color(243, 201, 201));
jta2.setBorder(new LineBorder(new java.awt.Color(255, 184, 184), 3));
//拖保存路径的区域
jta3 = new JTextArea();
jta3.setEditable(false);
jta3.setBackground(new java.awt.Color(192, 242, 170));
jta3.setBorder(new LineBorder(new java.awt.Color(134, 230, 90), 3));
// panel.add(jl1);
// panel.add(jta1);
// new DropTarget(jta1, DnDConstants.ACTION_COPY_OR_MOVE, adapter1);
panel.add(jl2);
panel.add(jta2);
new DropTarget(jta2, DnDConstants.ACTION_COPY_OR_MOVE, adapter2);
panel.add(jl3);
panel.add(jta3);
new DropTarget(jta3, DnDConstants.ACTION_COPY_OR_MOVE, adapter3);
panel.add(new JLabel());
JPanel p2 = new JPanel();
p2.setBackground(new java.awt.Color(125, 223, 190));
p2.setBorder(new LineBorder(new java.awt.Color(36, 209, 151), 3));
p2.setLayout(new FlowLayout(FlowLayout.CENTER, 98, 21));
JButton jb1 = new JButton(savePic);
jb1.setFont(new Font("宋体", Font.PLAIN, 17));
jb1.addActionListener(listener);
p2.add(jb1);
panel.add(p2);
}
//之前有个按钮去掉了,这个用不着
class ClearAll implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
jta1.setText("");
jta2.setText("");
jta3.setText("");
}
}
//点击保存切图,就是开切的实现方法
class SavePic implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
// ImgCutUtil.cutImg(894, 401, 22, 43, "E:\\qsbattle01.png",
// "E:\\qsbattlewd020_1_png.png");
// System.out.println(sInfo.getSavePath() + " " + pInfo.getPicPath()
// + " " + jInfo.getJsonPath());
for (Map.Entry<String, JsonContent> enItem : map.entrySet()) {
String key = enItem.getKey();
JsonContent jc = enItem.getValue();
String picPath = (pInfo.getPicPath()).replaceAll("\\\\", "/");
String newPicPath = (sInfo.getSavePath()).replaceAll("\\\\", "/");
String newPicPathName = newPicPath + "/" + key + PNG;
// System.out.println(
// enItem.getKey() + " " + jc.getX() + " " + picPath + " " +
// newPicPathName + " " + newPicPath);
//这个是最主要的,老铁
ImgCutUtil.cutAndDrawImg(jc.getX(), jc.getY(), jc.getW(), jc.getH(), jc.getOffX(), jc.getOffY(),jc.getSourceW(), jc.getSourceH(), picPath, newPicPathName);
}
}
}
//就是json里面的各图片的坐标
private String getContent(String fileName) {
String encoding = "UTF-8";
File file = new File(fileName);
Long filelength = file.length();
byte[] filecontent = new byte[filelength.intValue()];
try {
FileInputStream in = new FileInputStream(file);
in.read(filecontent);
in.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
try {
return new String(filecontent, encoding);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
return null;
}
}
//获取json,然后放在map里面
private void operateJson(String jsonContent) {
JSONObject obj;
try {
obj = new JSONObject(jsonContent);
if (obj != null) {
JSONObject frameObj = obj.getJSONObject("frames");
Iterator theFrame = frameObj.keys();
JsonContent js;
for (Iterator<Map.Entry<String, JsonContent>> it = map.entrySet().iterator(); it.hasNext();) {
Entry<String, JsonContent> item = it.next();
it.remove();
}
while (theFrame.hasNext()) {
String curItemId = (String) theFrame.next();
String newItemId = curItemId.substring(0, curItemId.length() - 4);
JSONObject curItemObj = frameObj.getJSONObject(curItemId);
int picX = curItemObj.getInt("x");
int picY = curItemObj.getInt("y");
int picH = curItemObj.getInt("h");
int picW = curItemObj.getInt("w");
int picOffX = curItemObj.getInt("offX");
int picOffY = curItemObj.getInt("offY");
int picSourW = curItemObj.getInt("sourceW");
int picSourH = curItemObj.getInt("sourceH");
js = new JsonContent(picX, picY, picW, picH, picOffX, picOffY, picSourW, picSourH);
map.put(newItemId, js);
// System.out.println(newItemId + " " + picX + " " + picY +
// " " + picH);
}
}
} catch (Exception e) {
System.out.println("错了");
}
}
}
// 图片剪切类,这个是最主要的,其他都是界面、获取内容什么的
class ImgCutUtil {
public static void cutAndDrawImg(int x, int y, int width, int height, int offsetX, int offsetY, int sourceW, int sourceH, String sourPath, String descPath) {
FileInputStream is = null;
ImageInputStream iis = null;
File file = null;
try {
is = new FileInputStream(sourPath);
String fileSuffix = sourPath.substring(sourPath.lastIndexOf(".") + 1);
Iterator<ImageReader> it = ImageIO.getImageReadersByFormatName(fileSuffix);
ImageReader reader = it.next();
iis = ImageIO.createImageInputStream(is);
reader.setInput(iis, true);
ImageReadParam param = reader.getDefaultReadParam();
Rectangle rect = new Rectangle(x, y, width, height);
param.setSourceRegion(rect);
BufferedImage bi = reader.read(0, param);
ImageIO.write(bi, fileSuffix, new File(descPath));
// 之前做了一个,是按json里面的长宽进行切,然后生成,但同事后来让改成长和宽要加偏移,就是下面这个方法
file = new File(descPath);
BufferedImage src = javax.imageio.ImageIO.read(file);
int theWidth = src.getWidth();
int theHeight = src.getHeight();
int temp = src.getRGB(3, 3);
BufferedImage img = new BufferedImage(sourceW, sourceH, BufferedImage.TYPE_4BYTE_ABGR);
for (int i = 0; i < sourceW; ++i)// 把原图片的内容复制到新的图片,同时把背景设为透明
{
for (int j = 0; j < sourceH; ++j) {
if (i < theWidth && j < theHeight) {
if (src.getRGB(i, j) == temp)
img.setRGB(i, j, temp & 0x00ffffff);// 这里把背景设为透明
} else {
if (img.getRGB(i, j) == temp)
img.setRGB(i, j, temp & 0x00ffffff);// 这里把背景设为透明
else
img.setRGB(i, j, img.getRGB(i, j));
}
}
}
//下面这两句很重要,而且不用引入那些快要被淘汰不用的类,可以说很方便了
img.getGraphics().drawImage(src, offsetX, offsetY, theWidth, theHeight, null);
ImageIO.write(img, fileSuffix, new File(descPath));
} catch (Exception ex) {
ex.printStackTrace();
} finally {
if (is != null) {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
is = null;
}
if (iis != null) {
try {
iis.close();
} catch (IOException e) {
e.printStackTrace();
}
iis = null;
}
}
}
}
PicDivMain.java 就是主类呗
package sc.pro.main;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import sc.pro.tool.PicDivTool;
public class PicDivMain {
public static void main(String[] args) throws ClassNotFoundException, InstantiationException,
IllegalAccessException, UnsupportedLookAndFeelException {
//这个是改一下UI,就是好看一点,默认的主题丑
String lookAndFeel = "com.sun.java.swing.plaf.windows.WindowsLookAndFeel";
UIManager.setLookAndFeel(lookAndFeel);
PicDivTool myDivTool = new PicDivTool("迦苇切图工具");
myDivTool.setVisible(true);
}
}
MANIFEST.MF,因为有引入包
//有用到解析json,所以得弄这个,lib要和src同级,知道?
Manifest-Version: 1.0
Main-Class: sc.pro.main.PicDivMain
Class-Path: lib/org.json.jar
上面就是最主要的所有,需要的可以拿去学习。
然后我上面说了教你怎么把jar弄成exe,所以看这篇《将jar弄成exe(口述)》,分开写贱贱的?