简体   繁体   English

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

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

I am creating a program using processing(java) that outputs an SVG file for me to add it to PowerPoint and other programs.我正在使用 processing(java) 创建一个程序,该程序输出 SVG 文件供我将其添加到 PowerPoint 和其他程序中。

I figured it would be a lot more convenient for the program to directly copy the generated file to my system clipboard, instead of having to copy the file from the output directory.我认为程序直接将生成的文件复制到我的系统剪贴板会更方便,而不必从 output 目录中复制文件。

The trouble is that I can't find a way to set the contents of the clipboard to an SVG file.问题是我找不到将剪贴板内容设置为 SVG 文件的方法。 I've found ways that work with images, but not SVG.我找到了处理图像的方法,但不是 SVG。 To clarify, I want the pasted file to be an SVG too because I want to edit the shapes and lines in PowerPoint afterward.澄清一下,我希望粘贴的文件也是 SVG 因为我想在 PowerPoint 中编辑形状和线条。

I am also open to javascript solutions which may work on the web.我也对可能适用于 web 的 javascript 解决方案持开放态度。 The goal is to be able to paste an editable collection of shapes, lines, and texts into PowerPoint.目标是能够将可编辑的形状、线条和文本集合粘贴到 PowerPoint 中。

All help is appreciated, thanks in advance!感谢所有帮助,在此先感谢!

Edit: Here is the code that works for images:编辑:这是适用于图像的代码:

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
    };
  }
}


There is a bit of confusion with the code you posted: so far it looks like for some reason you want to load an image and copy that to the clipboard, not an SVG.您发布的代码有点混乱:到目前为止,您似乎出于某种原因想要加载图像并将其复制到剪贴板,而不是 SVG。

If you want to copy an SVG to the clipboard for PowerPoint there are a few hoops to jump through:如果要将 SVG 复制到 PowerPoint 的剪贴板,则需要跳过一些步骤:

  1. Use the PShapeSVG source code to understand to get the SVG markup使用PShapeSVG源码理解获取SVG标记
  2. Use the rightMIME type : I simply tried this solution使用正确的MIME 类型:我只是尝试了这个解决方案

Putting it together:把它放在一起:

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));
    }

}

Note Call copyToClipboard(svg) after your last drawing command, but before PGraphicsSVG 's endDraw() call (otherwise it will return an empty SVG document)注意在最后一个绘图命令之后调用copyToClipboard(svg) ,但在PGraphicsSVGendDraw()调用之前(否则它将返回一个空的 SVG 文档)

The result in PowerPoint: PowerPoint 中的结果:

从处理生成的 SVG 作为 PowerPoint 剪贴板粘贴的 XR 徽标近似

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM