用 java 开发一个 clipboard-image 的功能、手动 jar 打包
因为nodejs里一个不好实现的需求,发现这个问题用 java 很好解决
背景
自己在实现 xpic 这个项目的时候,核心功能就是读取
clipboard
里的image buffer
或者filepath
,用了几种办法实现都不理想。
nodejs
里并没有合适,或者说是优雅的解决方案,唯一找到的一个,还是用c语言
实现的,然后包了一层nodejs
的壳,不过,看过源码,也基本打开了思路。
代码
文件名 ClipboardImage.java
import java.awt.*;
import java.awt.datatransfer.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
public class ClipboardImage {
public static void main(String[] args) {
Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
Transferable contents = clipboard.getContents(null);
if (contents != null) {
// 来源截图软件
Boolean isFromClipboard = contents.isDataFlavorSupported(DataFlavor.imageFlavor);
// 来源于复制系统文件
Boolean isFromFile = contents.isDataFlavorSupported(DataFlavor.javaFileListFlavor);
if (isFromClipboard) {
try {
Image image = (Image) contents.getTransferData(DataFlavor.imageFlavor);
String imagePath = saveImageToFile(convertToBufferedImage(image));
System.out.print(imagePath);
} catch (UnsupportedFlavorException | IOException e) {
e.printStackTrace();
}
}
if (isFromFile) {
try {
@SuppressWarnings("unchecked")
java.util.List<File> files = (java.util.List<File>) contents
.getTransferData(DataFlavor.javaFileListFlavor);
if (!files.isEmpty()) {
File file = files.get(0); // Assuming the first file
String filePath = file.getAbsolutePath();
System.out.print(filePath);
}
} catch (UnsupportedFlavorException | IOException e) {
e.printStackTrace();
}
}
}
}
private static String saveImageToFile(BufferedImage image) throws IOException {
File tempFile = File.createTempFile("clipboard_image", ".png");
ImageIO.write(image, "png", tempFile);
return tempFile.getAbsolutePath();
}
private static BufferedImage convertToBufferedImage(Image image) {
BufferedImage newImage = new BufferedImage(
image.getWidth(null), image.getHeight(null),
BufferedImage.TYPE_INT_ARGB);
Graphics2D g = newImage.createGraphics();
g.drawImage(image, 0, 0, null);
g.dispose();
return newImage;
}
}
编译
编译字节码,生成
jar
包的过程。
javac ClipboardImage.java
jar cvfe ClipboardImage.jar ClipboardImage ClipboardImage.class
执行
$ java -jar ClipboardImage.jar
/var/folders/kk/45b76t8x6157sc2895ffdw3c0000gn/T/clipboard_image10270512188937717754.png
结论
- 这个方法只是开拓一种思路,缺点如下:
- 有java的应用程序框弹出,使用并不方便
- 这个依赖于
java
环境,不方便推广使用 - 打出来的包,会比较大(虽然实际情况是只有4k左右)
- 后续:
go
应该会是一个不错的解决方案
关于 headless
检查是否在无头模式下运行
import java.awt.GraphicsEnvironment;
public class Test {
public static void main(String[] args) {
// 检查是否在无头模式下运行
if (GraphicsEnvironment.isHeadless()) {
System.out.println("Running in headless mode");
// 执行你的逻辑
} else {
System.out.println("Running in graphical mode");
// 弹出图形界面
// ...
}
}
}
// java -Djava.awt.headless=true -jar ClipboardImage.jar