Как сохранить файл SVG в буфер обмена с помощью обработки / java? - PullRequest
1 голос
/ 17 апреля 2020

Я создаю программу с использованием обработки (java), которая выводит файл SVG для меня, чтобы добавить его в PowerPoint и другие программы.

Я подумал, что для программы было бы гораздо удобнее напрямую скопировать сгенерированный файл в системный буфер обмена вместо необходимости копировать файл из выходного каталога.

Проблема в том, что что я не могу найти способ установить содержимое буфера обмена в файл SVG. Я нашел способы работы с изображениями, но не SVG. Чтобы уточнить, я хочу, чтобы вставленный файл также был SVG, потому что я хочу редактировать формы и линии в PowerPoint позже.

Я также открыт для javascript решений, которые могут работать в Интернете. Цель состоит в том, чтобы иметь возможность вставлять редактируемую коллекцию форм, линий и текстов в 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
    };
  }
}


1 Ответ

0 голосов
/ 17 апреля 2020

Существует некоторая путаница с кодом, который вы разместили: до сих пор похоже, что по какой-то причине вы хотите загрузить изображение и скопировать его в буфер обмена, а не в SVG.

Если вы хотите Скопируйте SVG в буфер обмена для PowerPoint, и вам нужно прыгнуть через несколько обручей:

  1. Используйте исходный код PShapeSVG , чтобы понять, как получить разметку SVG
  2. Используйте правильный MIME тип : я просто попытался это решение

Соединяя его вместе:

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) после последней команды рисования, но до PGraphicsSVG endDraw() вызова (в противном случае будет возвращен пустой документ SVG)

Результат в PowerPoint:

XR logo approximation pasted from Processing generated SVG as PowerPoint Clipboard

...