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 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162
|
import ij.plugin.*;
import java.awt.*;
import java.awt.datatransfer.*;
import java.awt.image.*;
import java.io.*;
import java.lang.reflect.*;
import ij.*;
import ij.process.*;
/** This plugin uses QuickTime for Java to open PICT images on the Mac system
clipboard. Only needed on Macs running 32-bit Java and OS X 10.5 and earlier. */
public class MacClipboard extends ImagePlus implements PlugIn {
static java.awt.datatransfer.Clipboard clipboard;
public void run(String arg) {
Image img = showSystemClipboard();
if (img!=null) setImage(img);
}
Image showSystemClipboard() {
Image img = null;
if (clipboard==null)
clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
try {
Transferable transferable = clipboard.getContents(null);
img = displayMacImage(transferable);
} catch (Throwable e) {
IJ.handleException(e);
}
return img;
}
Image displayMacImage(Transferable t) {
Image img = getMacImage(t);
if (img!=null) {
WindowManager.checkForDuplicateName = true;
new ImagePlus("Clipboard", img).show();
}
return img;
}
// Mac OS X's data transfer handling is horribly broken. We sometimes
// need to use the "image/x-pict" MIME type and then Quicktime
// for Java in order to get the image data.
Image getMacImage(Transferable t) {
if (!isQTJavaInstalled())
return null;
Image img = null;
DataFlavor[] d = t.getTransferDataFlavors();
if (d==null || d.length==0)
return null;
try {
Object is = t.getTransferData(d[0]);
if (is==null || !(is instanceof InputStream))
return null;
img = getImageFromPictStream((InputStream)is);
} catch (Exception e) {}
return img;
}
// Converts a PICT to an AWT image using QuickTime for Java.
// This code was contributed by Gord Peters.
Image getImageFromPictStream(InputStream is) {
try {
ByteArrayOutputStream baos= new ByteArrayOutputStream();
// We need to strip the header from the data because a PICT file
// has a 512 byte header and then the data, but in our case we only
// need the data. --GP
byte[] header= new byte[512];
byte[] buf= new byte[4096];
int retval= 0, size= 0;
baos.write(header, 0, 512);
while ( (retval= is.read(buf, 0, 4096)) > 0)
baos.write(buf, 0, retval);
baos.close();
size = baos.size();
//IJ.log("size: "+size); IJ.wait(2000);
if (size<=0)
return null;
byte[] imgBytes= baos.toByteArray();
// Again with the uglyness. Here we need to use the Quicktime
// for Java code in order to create an Image object from
// the PICT data we received on the clipboard. However, in
// order to get this to compile on other platforms, we use
// the Java reflection API.
//
// For reference, here is the equivalent code without
// reflection:
//
//
// if (QTSession.isInitialized() == false) {
// QTSession.open();
// }
// QTHandle handle= new QTHandle(imgBytes);
// GraphicsImporter gi=
// new GraphicsImporter(QTUtils.toOSType("PICT"));
// gi.setDataHandle(handle);
// QDRect qdRect= gi.getNaturalBounds();
// GraphicsImporterDrawer gid= new GraphicsImporterDrawer(gi);
// QTImageProducer qip= new QTImageProducer(gid,
// new Dimension(qdRect.getWidth(),
// qdRect.getHeight()));
// return(Toolkit.getDefaultToolkit().createImage(qip));
//
// --GP
//IJ.log("quicktime.QTSession");
Class c = Class.forName("quicktime.QTSession");
Method m = c.getMethod("isInitialized", null);
Boolean b= (Boolean)m.invoke(null, null);
if (b.booleanValue() == false) {
m= c.getMethod("open", null);
m.invoke(null, null);
}
c= Class.forName("quicktime.util.QTHandle");
Constructor con = c.getConstructor(new Class[] {imgBytes.getClass() });
Object handle= con.newInstance(new Object[] { imgBytes });
String s= new String("PICT");
c = Class.forName("quicktime.util.QTUtils");
m = c.getMethod("toOSType", new Class[] { s.getClass() });
Integer type= (Integer)m.invoke(null, new Object[] { s });
c = Class.forName("quicktime.std.image.GraphicsImporter");
con = c.getConstructor(new Class[] { type.TYPE });
Object importer= con.newInstance(new Object[] { type });
m = c.getMethod("setDataHandle",
new Class[] { Class.forName("quicktime.util." + "QTHandleRef") });
m.invoke(importer, new Object[] { handle });
m = c.getMethod("getNaturalBounds", null);
Object rect= m.invoke(importer, null);
c = Class.forName("quicktime.app.view.GraphicsImporterDrawer");
con = c.getConstructor(new Class[] { importer.getClass() });
Object iDrawer = con.newInstance(new Object[] { importer });
m = rect.getClass().getMethod("getWidth", null);
Integer width= (Integer)m.invoke(rect, null);
m = rect.getClass().getMethod("getHeight", null);
Integer height= (Integer)m.invoke(rect, null);
Dimension d= new Dimension(width.intValue(), height.intValue());
c = Class.forName("quicktime.app.view.QTImageProducer");
con = c.getConstructor(new Class[] { iDrawer.getClass(), d.getClass() });
Object producer= con.newInstance(new Object[] { iDrawer, d });
if (producer instanceof ImageProducer)
return(Toolkit.getDefaultToolkit().createImage((ImageProducer)producer));
} catch (Exception e) {
IJ.showStatus(""+e);
}
return null;
}
// Retuns true if QuickTime for Java is installed.
// This code was contributed by Gord Peters.
boolean isQTJavaInstalled() {
boolean isInstalled = false;
try {
Class c= Class.forName("quicktime.QTSession");
isInstalled = true;
} catch (Exception e) {}
return isInstalled;
}
}
|