如何使用 processing/java 将 SVG 文件保存到剪贴板?

How do I save an SVG file to clipboard using processing/java?

我正在使用 processing(java) 创建一个程序,它输出一个 SVG 文件供我将其添加到 PowerPoint 和其他程序中。

我认为程序直接将生成的文件复制到我的系统剪贴板会更方便,而不必从输出目录复制文件。

问题是我找不到将剪贴板的内容设置为 SVG 文件的方法。我找到了处理图像的方法,但不是 SVG。澄清一下,我希望粘贴的文件也是 SVG,因为我想之后在 PowerPoint 中编辑形状和线条。

我也对可能在网络上运行的 javascript 解决方案持开放态度。目标是能够将可编辑的形状、线条和文本集合粘贴到 PowerPoint 中。

感谢所有帮助,在此先感谢!

编辑:这是适用于图像的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
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源码理解获取SVG标记
  • 使用正确的 MIME 类型:我只是尝试了这个解决方案
  • 把它放在一起:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    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 https://stackoverflow.com/questions/33726321/how-to-transfer-svg-image-to-other-programs-with-dragndrop-in-java
    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));
        }

    }

    注意在上一个绘图命令之后调用 copyToClipboard(svg),但在 PGraphicsSVGendDraw() 调用之前(否则它将返回一个空的 SVG 文档)

    PowerPoint 中的结果:

    XR