Issue #235 Ability to screen capture or print multiple frames at once.
Change-Id: I58176883e701fbe0d9e0bcc0e43b60bd5c0053a7 Former-commit-id: 9062fe4b8fdb62840b21aba7c648f48fa691986a
This commit is contained in:
parent
e79aa3bfa1
commit
c74dae631e
5 changed files with 253 additions and 43 deletions
|
@ -112,6 +112,37 @@
|
|||
commandId="com.raytheon.viz.ui.loadSerialized"
|
||||
label="Load Displays..."
|
||||
style="push">
|
||||
</command>
|
||||
<separator
|
||||
name="afterSerialized"
|
||||
visible="true">
|
||||
</separator>
|
||||
<command
|
||||
commandId="com.raytheon.viz.ui.actions.printScreenAction"
|
||||
label="Print Screen"
|
||||
style="push">
|
||||
<parameter
|
||||
name="frameSelection"
|
||||
value="current">
|
||||
</parameter>
|
||||
</command>
|
||||
<command
|
||||
commandId="com.raytheon.viz.ui.actions.saveScreen"
|
||||
label="Capture Current Frame"
|
||||
style="push">
|
||||
<parameter
|
||||
name="frameSelection"
|
||||
value="current">
|
||||
</parameter>
|
||||
</command>
|
||||
<command
|
||||
commandId="com.raytheon.viz.ui.actions.saveScreen"
|
||||
label="Capture All Frames"
|
||||
style="push">
|
||||
<parameter
|
||||
name="frameSelection"
|
||||
value="all">
|
||||
</parameter>
|
||||
</command>
|
||||
</menu>
|
||||
<separator
|
||||
|
|
|
@ -207,6 +207,11 @@
|
|||
categoryId="com.raytheon.uf.viz.core.commandCategory"
|
||||
description="Print the currently active editor"
|
||||
name="Print Screen">
|
||||
<commandParameter
|
||||
id="frameSelection"
|
||||
name="Frame Selection"
|
||||
optional="true">
|
||||
</commandParameter>
|
||||
</command>
|
||||
<command
|
||||
id="com.raytheon.viz.ui.newPage"
|
||||
|
@ -217,7 +222,12 @@
|
|||
categoryId="com.raytheon.uf.viz.core.commandCategory"
|
||||
description="Save the current screen"
|
||||
name="Save Screen">
|
||||
</command>
|
||||
<commandParameter
|
||||
id="frameSelection"
|
||||
name="Frame Selection"
|
||||
optional="true">
|
||||
</commandParameter>
|
||||
</command>
|
||||
<command
|
||||
id="com.raytheon.viz.ui.actions.notImplemented"
|
||||
name="Not Implemented">
|
||||
|
|
|
@ -0,0 +1,100 @@
|
|||
package com.raytheon.viz.ui.actions;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.core.commands.AbstractHandler;
|
||||
import org.eclipse.swt.graphics.Rectangle;
|
||||
|
||||
import com.raytheon.uf.viz.core.IDisplayPane;
|
||||
import com.raytheon.uf.viz.core.IDisplayPaneContainer;
|
||||
import com.raytheon.uf.viz.core.IGraphicsTarget;
|
||||
import com.raytheon.uf.viz.core.IView;
|
||||
import com.raytheon.uf.viz.core.datastructure.LoopProperties;
|
||||
import com.raytheon.uf.viz.core.drawables.IDescriptor;
|
||||
import com.raytheon.uf.viz.core.drawables.IDescriptor.FramesInfo;
|
||||
import com.raytheon.uf.viz.core.drawables.IRenderableDisplay;
|
||||
import com.raytheon.uf.viz.core.drawables.PaintProperties;
|
||||
import com.raytheon.uf.viz.core.exception.VizException;
|
||||
import com.raytheon.viz.ui.EditorUtil;
|
||||
import com.raytheon.viz.ui.editor.AbstractEditor;
|
||||
|
||||
public abstract class AbstractScreenCaptureAction extends AbstractHandler {
|
||||
|
||||
protected BufferedImage captureCurrentFrames(AbstractEditor editor) {
|
||||
return editor.screenshot();
|
||||
}
|
||||
|
||||
protected List<BufferedImage> captureAllFrames(AbstractEditor editor)
|
||||
throws VizException {
|
||||
int startIndex = 0;
|
||||
int endIndex = editor.getActiveDisplayPane().getDescriptor()
|
||||
.getFramesInfo().getFrameCount();
|
||||
return captureFrames(editor, startIndex, endIndex);
|
||||
}
|
||||
|
||||
protected List<BufferedImage> captureFrames(AbstractEditor editor,
|
||||
int startIndex, int endIndex) throws VizException {
|
||||
if (startIndex < 0) {
|
||||
startIndex = 0;
|
||||
}
|
||||
List<BufferedImage> images = new ArrayList<BufferedImage>(endIndex
|
||||
- startIndex);
|
||||
int origIndex = editor.getActiveDisplayPane().getDescriptor()
|
||||
.getFramesInfo().getFrameIndex();
|
||||
for (int i = startIndex; i < endIndex; i++) {
|
||||
for (IDisplayPane pane : editor.getDisplayPanes()) {
|
||||
setFrameIndex(pane.getDescriptor(), i);
|
||||
pane.refresh();
|
||||
renderPane(pane, editor.getLoopProperties());
|
||||
}
|
||||
images.add(editor.screenshot());
|
||||
}
|
||||
for (IDisplayPane pane : editor.getDisplayPanes()) {
|
||||
setFrameIndex(pane.getDescriptor(), origIndex);
|
||||
pane.refresh();
|
||||
}
|
||||
return images;
|
||||
}
|
||||
|
||||
private void setFrameIndex(IDescriptor desc, int index) {
|
||||
FramesInfo fi = desc.getFramesInfo();
|
||||
fi = new FramesInfo(fi.getFrameTimes(), index, fi.getTimeMap());
|
||||
desc.setFramesInfo(fi);
|
||||
}
|
||||
|
||||
private void renderPane(IDisplayPane pane, LoopProperties loopProperties)
|
||||
throws VizException {
|
||||
IGraphicsTarget target = pane.getTarget();
|
||||
IRenderableDisplay display = pane.getRenderableDisplay();
|
||||
|
||||
float alpha = 1.0f;
|
||||
float zoomLevel = (float) pane.getZoomLevel();
|
||||
IView view = display.getView();
|
||||
Rectangle canvasBounds = pane.getBounds();
|
||||
boolean isZooming = false;
|
||||
FramesInfo framesInfo = pane.getDescriptor().getFramesInfo();
|
||||
PaintProperties paintProps = new PaintProperties(alpha, zoomLevel,
|
||||
view, canvasBounds, isZooming, framesInfo);
|
||||
paintProps.setLoopProperties(loopProperties);
|
||||
|
||||
// paint in a loop until any async tasks are done
|
||||
while (target.isNeedsRefresh()) {
|
||||
target.beginFrame(display, true);
|
||||
display.paint(target, paintProps);
|
||||
target.endFrame();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setEnabled(Object obj) {
|
||||
IDisplayPaneContainer container = EditorUtil.getActiveVizContainer();
|
||||
if (container == null) {
|
||||
setBaseEnabled(false);
|
||||
} else {
|
||||
setBaseEnabled(true);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -27,7 +27,6 @@ import java.awt.image.ComponentColorModel;
|
|||
import java.awt.image.IndexColorModel;
|
||||
import java.awt.image.WritableRaster;
|
||||
|
||||
import org.eclipse.core.commands.AbstractHandler;
|
||||
import org.eclipse.core.commands.ExecutionEvent;
|
||||
import org.eclipse.core.commands.ExecutionException;
|
||||
import org.eclipse.swt.graphics.GC;
|
||||
|
@ -46,6 +45,8 @@ import org.eclipse.swt.widgets.Shell;
|
|||
import org.eclipse.ui.IEditorPart;
|
||||
import org.eclipse.ui.PlatformUI;
|
||||
|
||||
import com.raytheon.uf.viz.core.drawables.IDescriptor;
|
||||
import com.raytheon.uf.viz.core.exception.VizException;
|
||||
import com.raytheon.viz.ui.EditorUtil;
|
||||
import com.raytheon.viz.ui.editor.AbstractEditor;
|
||||
|
||||
|
@ -65,7 +66,7 @@ import com.raytheon.viz.ui.editor.AbstractEditor;
|
|||
* @author chammack
|
||||
* @version 1
|
||||
*/
|
||||
public class PrintScreenAction extends AbstractHandler {
|
||||
public class PrintScreenAction extends AbstractScreenCaptureAction {
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
|
@ -88,17 +89,68 @@ public class PrintScreenAction extends AbstractHandler {
|
|||
Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow()
|
||||
.getShell();
|
||||
|
||||
IDescriptor desc = editor.getActiveDisplayPane().getDescriptor();
|
||||
|
||||
// display the printer dialog to get print options
|
||||
PrintDialog pd = new PrintDialog(shell);
|
||||
String frameMode = event.getParameter("frameSelection");
|
||||
if (frameMode == null || frameMode.equalsIgnoreCase("current")) {
|
||||
// selection doesn't seem to work.
|
||||
pd.setScope(PrinterData.PAGE_RANGE);
|
||||
pd.setStartPage(desc.getFramesInfo().getFrameIndex() + 1);
|
||||
pd.setEndPage(desc.getFramesInfo().getFrameIndex() + 1);
|
||||
} else if (frameMode.equalsIgnoreCase("all")) {
|
||||
pd.setScope(PrinterData.ALL_PAGES);
|
||||
} else {
|
||||
throw new ExecutionException("Invalid frameMode: " + frameMode);
|
||||
}
|
||||
PrinterData printerData = pd.open();
|
||||
if (printerData == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
BufferedImage bi = editor.screenshot();
|
||||
|
||||
Display display = editor.getActiveDisplayPane().getDisplay();
|
||||
Printer printer = new Printer(printerData);
|
||||
if (printer.startJob("CAVE")) {
|
||||
switch (pd.getScope()) {
|
||||
case PrinterData.ALL_PAGES: {
|
||||
try {
|
||||
for (BufferedImage bi : captureAllFrames(editor)) {
|
||||
printImage(printer, display, bi);
|
||||
}
|
||||
} catch (VizException e) {
|
||||
throw new ExecutionException(
|
||||
"Error occurred while writing image", e);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PrinterData.PAGE_RANGE: {
|
||||
try {
|
||||
for (BufferedImage bi : captureFrames(editor,
|
||||
pd.getStartPage() - 1, pd.getEndPage())) {
|
||||
printImage(printer, display, bi);
|
||||
}
|
||||
} catch (VizException e) {
|
||||
throw new ExecutionException(
|
||||
"Error occurred while writing image", e);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PrinterData.SELECTION: {
|
||||
BufferedImage bi = editor.screenshot();
|
||||
printImage(printer, display, bi);
|
||||
break;
|
||||
}
|
||||
}
|
||||
printer.endJob();
|
||||
|
||||
}
|
||||
printer.dispose();
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private void printImage(Printer printer, Display display, BufferedImage bi) {
|
||||
Point screenDPI = display.getDPI();
|
||||
Point printerDPI = printer.getDPI();
|
||||
|
||||
|
@ -152,27 +204,20 @@ public class PrintScreenAction extends AbstractHandler {
|
|||
offset.x += printArea.width - (imageBounds.width) * scaleX;
|
||||
}
|
||||
|
||||
if (printer.startJob("CAVE")) {
|
||||
if (printer.startPage()) {
|
||||
GC gc = new GC(printer);
|
||||
Transform transform = new Transform(gc.getDevice());
|
||||
transform.translate(offset.x, offset.y);
|
||||
transform.scale(scaleX, scaleY);
|
||||
gc.setTransform(transform);
|
||||
if (printer.startPage()) {
|
||||
GC gc = new GC(printer);
|
||||
Transform transform = new Transform(gc.getDevice());
|
||||
transform.translate(offset.x, offset.y);
|
||||
transform.scale(scaleX, scaleY);
|
||||
gc.setTransform(transform);
|
||||
|
||||
gc.drawImage(image, 0, 0);
|
||||
gc.drawImage(image, 0, 0);
|
||||
|
||||
transform.dispose();
|
||||
gc.dispose();
|
||||
printer.endPage();
|
||||
printer.endJob();
|
||||
}
|
||||
transform.dispose();
|
||||
gc.dispose();
|
||||
printer.endPage();
|
||||
}
|
||||
|
||||
image.dispose();
|
||||
printer.dispose();
|
||||
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
|
@ -228,15 +273,4 @@ public class PrintScreenAction extends AbstractHandler {
|
|||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.eclipse.ui.IWorkbenchWindowActionDelegate#dispose()
|
||||
*/
|
||||
@Override
|
||||
public void dispose() {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -26,12 +26,12 @@ import java.io.IOException;
|
|||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.imageio.ImageWriter;
|
||||
import javax.imageio.stream.FileImageOutputStream;
|
||||
|
||||
import org.eclipse.core.commands.AbstractHandler;
|
||||
import org.eclipse.core.commands.ExecutionEvent;
|
||||
import org.eclipse.core.commands.ExecutionException;
|
||||
import org.eclipse.swt.SWT;
|
||||
|
@ -43,6 +43,7 @@ import org.eclipse.ui.PlatformUI;
|
|||
import com.raytheon.uf.common.status.IUFStatusHandler;
|
||||
import com.raytheon.uf.common.status.UFStatus;
|
||||
import com.raytheon.uf.common.status.UFStatus.Priority;
|
||||
import com.raytheon.uf.viz.core.exception.VizException;
|
||||
import com.raytheon.viz.ui.EditorUtil;
|
||||
import com.raytheon.viz.ui.editor.AbstractEditor;
|
||||
|
||||
|
@ -60,7 +61,7 @@ import com.raytheon.viz.ui.editor.AbstractEditor;
|
|||
* @author chammack
|
||||
* @version 1
|
||||
*/
|
||||
public class SaveScreenAction extends AbstractHandler {
|
||||
public class SaveScreenAction extends AbstractScreenCaptureAction {
|
||||
private static final transient IUFStatusHandler statusHandler = UFStatus
|
||||
.getHandler(SaveScreenAction.class);
|
||||
|
||||
|
@ -116,6 +117,7 @@ public class SaveScreenAction extends AbstractHandler {
|
|||
}
|
||||
|
||||
String suffix = path.substring(path.lastIndexOf('.') + 1);
|
||||
String basePath = path.substring(0, path.lastIndexOf('.'));
|
||||
Iterator<ImageWriter> iter = ImageIO.getImageWritersBySuffix(suffix);
|
||||
if (!iter.hasNext()) {
|
||||
String reason = "Unsupported filetype: \"" + suffix + "\"";
|
||||
|
@ -125,15 +127,48 @@ public class SaveScreenAction extends AbstractHandler {
|
|||
}
|
||||
ImageWriter writer = iter.next();
|
||||
|
||||
BufferedImage bi = editor.screenshot();
|
||||
String frameMode = arg0.getParameter("frameSelection");
|
||||
|
||||
try {
|
||||
writer.setOutput(new FileImageOutputStream(new File(path)));
|
||||
writer.write(bi);
|
||||
} catch (IOException e) {
|
||||
String reason = "Error occurred while writing image";
|
||||
statusHandler.handle(Priority.PROBLEM, reason, e);
|
||||
throw new ExecutionException(reason, e);
|
||||
if (frameMode == null || frameMode.equalsIgnoreCase("current")) {
|
||||
BufferedImage bi = editor.screenshot();
|
||||
|
||||
try {
|
||||
writer.setOutput(new FileImageOutputStream(new File(path)));
|
||||
writer.write(bi);
|
||||
} catch (IOException e) {
|
||||
String reason = "Error occurred while writing image";
|
||||
statusHandler.handle(Priority.PROBLEM, reason, e);
|
||||
throw new ExecutionException(reason, e);
|
||||
}
|
||||
} else if (frameMode.equalsIgnoreCase("all")) {
|
||||
List<BufferedImage> images = null;
|
||||
try {
|
||||
images = captureAllFrames(editor);
|
||||
} catch (VizException e) {
|
||||
String reason = "Error occurred while writing image";
|
||||
statusHandler.handle(Priority.PROBLEM, reason, e);
|
||||
throw new ExecutionException(reason, e);
|
||||
}
|
||||
|
||||
for (int i = 0; i < images.size(); i++) {
|
||||
|
||||
BufferedImage bi = images.get(i);
|
||||
|
||||
path = basePath + "-" + (i + 1) + "." + suffix;
|
||||
|
||||
try {
|
||||
writer.setOutput(new FileImageOutputStream(new File(path)));
|
||||
writer.write(bi);
|
||||
} catch (IOException e) {
|
||||
String reason = "Error occurred while writing image";
|
||||
statusHandler.handle(Priority.PROBLEM, reason, e);
|
||||
throw new ExecutionException(reason, e);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
String reason = "Invalid frameMode: " + frameMode;
|
||||
statusHandler.handle(Priority.PROBLEM, reason);
|
||||
throw new ExecutionException(reason);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue