如何使用 processing/java 将 SVG 文件保存到剪贴板?
How do I save an SVG file to clipboard using processing/java?
我正在使用 processing(java) 创建一个程序,该程序输出一个 SVG 文件供我将其添加到 PowerPoint 和其他程序中。
我认为程序直接将生成的文件复制到我的系统剪贴板会更方便,而不必从输出目录复制文件。
问题是我找不到将剪贴板的内容设置为 SVG 文件的方法。我找到了处理图像的方法,但不是 SVG。澄清一下,我希望粘贴的文件也是 SVG,因为之后我想在 PowerPoint 中编辑形状和线条。
我也对 java可能在网络上工作的脚本解决方案持开放态度。目标是能够将可编辑的形状、线条和文本集合粘贴到 PowerPoint 中。
感谢所有帮助,提前致谢!
编辑:这是适用于图像的代码:
import java.awt.image.*;
import java.awt.*;
import java.awt.datatransfer.*;
import javax.imageio.*;
void setup() {
size(200, 200);
background(0);
Image img=null;
try {
img = ImageIO.read(new File("path/to/file.jpg"));//path to image file
}
catch (IOException e) {
print(e);
}
ImageSelection imageSelection = new ImageSelection(img);
Toolkit toolkit = Toolkit.getDefaultToolkit();
toolkit.getSystemClipboard().setContents(imageSelection, null);
}
void draw() {
}
public class ImageSelection implements Transferable {
private Image image;
public ImageSelection(Image image) {
this.image = image;//added on
}
public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException {
if (flavor.equals(DataFlavor.imageFlavor) == false) {
throw new UnsupportedFlavorException(flavor);//usually with transferable
}
return image;
}
public boolean isDataFlavorSupported(DataFlavor flavor) {
return flavor.equals(DataFlavor.imageFlavor);//usually with transferable
}
public DataFlavor[] getTransferDataFlavors() {
return new DataFlavor[] {
DataFlavor.imageFlavor//usually with transferable
};
}
}
您发布的代码有点混乱:到目前为止,出于某种原因,您似乎想要加载图像并将其复制到剪贴板,而不是 SVG。
如果要将 SVG 复制到 PowerPoint 的剪贴板,需要跳过几个步骤:
- 使用PShapeSVG source code理解获取SVG标记
- 使用正确的MIME type: I simply tried
放在一起:
import processing.svg.*;
import java.awt.Toolkit;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.SystemFlavorMap;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.Writer;
import java.nio.charset.StandardCharsets;
import org.apache.batik.svggen.SVGGraphics2D;
import org.apache.batik.svggen.SVGGraphics2DIOException;
void setup(){
PGraphicsSVG svg = (PGraphicsSVG)createGraphics(300,300,SVG);
svg.beginDraw();
svg.background(#4db748);
svg.noFill();
svg.strokeWeight(27);
int a = 80;
int b = 220;
svg.line(a,a,b,b);
svg.line(a,b,b,a);
svg.line(a,a,b,a);
svg.line(a,b,b,b);
svg.ellipse(150, 150, 250, 250);
copyToClipboard(svg);
// normally you would call endDraw, but this will obviously throw an error if you didn't specify a filename in createGraphics()
//svg.endDraw();
println("svg copied to clipboard");
exit();
}
String getSVGString(PGraphicsSVG svg){
// make a binary output stream
ByteArrayOutputStream output = new ByteArrayOutputStream();
// make a writer for it
Writer writer = PApplet.createWriter(output);
// same way the library writes to disk we write to the byte array stream
try{
((SVGGraphics2D) svg.g2).stream(writer, false);
} catch (SVGGraphics2DIOException e) {
e.printStackTrace();
}
// convert bytes to an UTF-8 encoded string
return new String( output.toByteArray(), StandardCharsets.UTF_8 );
}
void copyToClipboard(PGraphicsSVG svg){
// get the SVG markup as a string
String svgString = getSVGString(svg);
println(svgString);
// access the system clipboard
Clipboard clip = Toolkit.getDefaultToolkit().getSystemClipboard();
// get an binary clipboard with the correct SVG MIME type
SvgClip strSVG = new SvgClip(svgString);
// commit the clipboard encoded SVG to clipboard
clip.setContents(strSVG, null);
}
// blatant copy/adapation of
class SvgClip implements Transferable{
String svgString;
DataFlavor svgFlavor = new DataFlavor("image/svg+xml; class=java.io.InputStream","Scalable Vector Graphic");
DataFlavor [] supportedFlavors = {svgFlavor};
SvgClip(String svgString){
this.svgString = svgString;
SystemFlavorMap systemFlavorMap = (SystemFlavorMap) SystemFlavorMap.getDefaultFlavorMap();
systemFlavorMap.addUnencodedNativeForFlavor(svgFlavor, "image/svg+xml");
}
@Override public DataFlavor[] getTransferDataFlavors(){
return this.supportedFlavors;
}
@Override public boolean isDataFlavorSupported(DataFlavor flavor){
return true;
}
@Override public Object getTransferData(DataFlavor flavor)
throws UnsupportedFlavorException, IOException{
return new ByteArrayInputStream(svgString.getBytes(StandardCharsets.UTF_8));
}
}
注意在你最后一个绘图命令之后,但在PGraphicsSVG
的endDraw()
调用之前调用copyToClipboard(svg)
(否则它会return 一个空的 SVG 文档)
PowerPoint 中的结果:
我正在使用 processing(java) 创建一个程序,该程序输出一个 SVG 文件供我将其添加到 PowerPoint 和其他程序中。
我认为程序直接将生成的文件复制到我的系统剪贴板会更方便,而不必从输出目录复制文件。
问题是我找不到将剪贴板的内容设置为 SVG 文件的方法。我找到了处理图像的方法,但不是 SVG。澄清一下,我希望粘贴的文件也是 SVG,因为之后我想在 PowerPoint 中编辑形状和线条。
我也对 java可能在网络上工作的脚本解决方案持开放态度。目标是能够将可编辑的形状、线条和文本集合粘贴到 PowerPoint 中。
感谢所有帮助,提前致谢!
编辑:这是适用于图像的代码:
import java.awt.image.*;
import java.awt.*;
import java.awt.datatransfer.*;
import javax.imageio.*;
void setup() {
size(200, 200);
background(0);
Image img=null;
try {
img = ImageIO.read(new File("path/to/file.jpg"));//path to image file
}
catch (IOException e) {
print(e);
}
ImageSelection imageSelection = new ImageSelection(img);
Toolkit toolkit = Toolkit.getDefaultToolkit();
toolkit.getSystemClipboard().setContents(imageSelection, null);
}
void draw() {
}
public class ImageSelection implements Transferable {
private Image image;
public ImageSelection(Image image) {
this.image = image;//added on
}
public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException {
if (flavor.equals(DataFlavor.imageFlavor) == false) {
throw new UnsupportedFlavorException(flavor);//usually with transferable
}
return image;
}
public boolean isDataFlavorSupported(DataFlavor flavor) {
return flavor.equals(DataFlavor.imageFlavor);//usually with transferable
}
public DataFlavor[] getTransferDataFlavors() {
return new DataFlavor[] {
DataFlavor.imageFlavor//usually with transferable
};
}
}
您发布的代码有点混乱:到目前为止,出于某种原因,您似乎想要加载图像并将其复制到剪贴板,而不是 SVG。
如果要将 SVG 复制到 PowerPoint 的剪贴板,需要跳过几个步骤:
- 使用PShapeSVG source code理解获取SVG标记
- 使用正确的MIME type: I simply tried
放在一起:
import processing.svg.*;
import java.awt.Toolkit;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.SystemFlavorMap;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.Writer;
import java.nio.charset.StandardCharsets;
import org.apache.batik.svggen.SVGGraphics2D;
import org.apache.batik.svggen.SVGGraphics2DIOException;
void setup(){
PGraphicsSVG svg = (PGraphicsSVG)createGraphics(300,300,SVG);
svg.beginDraw();
svg.background(#4db748);
svg.noFill();
svg.strokeWeight(27);
int a = 80;
int b = 220;
svg.line(a,a,b,b);
svg.line(a,b,b,a);
svg.line(a,a,b,a);
svg.line(a,b,b,b);
svg.ellipse(150, 150, 250, 250);
copyToClipboard(svg);
// normally you would call endDraw, but this will obviously throw an error if you didn't specify a filename in createGraphics()
//svg.endDraw();
println("svg copied to clipboard");
exit();
}
String getSVGString(PGraphicsSVG svg){
// make a binary output stream
ByteArrayOutputStream output = new ByteArrayOutputStream();
// make a writer for it
Writer writer = PApplet.createWriter(output);
// same way the library writes to disk we write to the byte array stream
try{
((SVGGraphics2D) svg.g2).stream(writer, false);
} catch (SVGGraphics2DIOException e) {
e.printStackTrace();
}
// convert bytes to an UTF-8 encoded string
return new String( output.toByteArray(), StandardCharsets.UTF_8 );
}
void copyToClipboard(PGraphicsSVG svg){
// get the SVG markup as a string
String svgString = getSVGString(svg);
println(svgString);
// access the system clipboard
Clipboard clip = Toolkit.getDefaultToolkit().getSystemClipboard();
// get an binary clipboard with the correct SVG MIME type
SvgClip strSVG = new SvgClip(svgString);
// commit the clipboard encoded SVG to clipboard
clip.setContents(strSVG, null);
}
// blatant copy/adapation of
class SvgClip implements Transferable{
String svgString;
DataFlavor svgFlavor = new DataFlavor("image/svg+xml; class=java.io.InputStream","Scalable Vector Graphic");
DataFlavor [] supportedFlavors = {svgFlavor};
SvgClip(String svgString){
this.svgString = svgString;
SystemFlavorMap systemFlavorMap = (SystemFlavorMap) SystemFlavorMap.getDefaultFlavorMap();
systemFlavorMap.addUnencodedNativeForFlavor(svgFlavor, "image/svg+xml");
}
@Override public DataFlavor[] getTransferDataFlavors(){
return this.supportedFlavors;
}
@Override public boolean isDataFlavorSupported(DataFlavor flavor){
return true;
}
@Override public Object getTransferData(DataFlavor flavor)
throws UnsupportedFlavorException, IOException{
return new ByteArrayInputStream(svgString.getBytes(StandardCharsets.UTF_8));
}
}
注意在你最后一个绘图命令之后,但在PGraphicsSVG
的endDraw()
调用之前调用copyToClipboard(svg)
(否则它会return 一个空的 SVG 文档)
PowerPoint 中的结果: