最近时而忙一阵,也在看些书,几篇文章都没写完.一晃8月最后一天,昝发篇简洁的,努力写些文章. *概述 ---这篇文章说明了如下问题: 如何把gef的内容导出为图片,本质是如何把figure绘制到需要...
最近时而忙一阵,也在看些书,几篇文章都没写完.一晃8月最后一天,昝发篇简洁的,努力写些文章.
*概述
---这篇文章说明了如下问题:
如何把gef的内容导出为图片,本质是如何把figure绘制到需要的地方,而不是默认的FigureCanvas.
---实现代码
实现分成了2部分
1)导出的action,即代码主体
2)提炼的工具方法
*工具方法ImageUtil
ImageUtil源码/*******************************************************************************
* Copyright(C) 2011 Arzan Corporation. All rights reserved.
*
* Contributors:
* Arzan Corporation - initial API and implementation
*******************************************************************************/
package galaxy.gef.extension.utils;
import org.eclipse.draw2d.Graphics;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.SWTGraphics;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.ImageData;
import org.eclipse.swt.graphics.ImageLoader;
import org.eclipse.swt.widgets.Display;
/**
* @author dzh
* @date 2011-8-31 上午10:11:31
*/
public class ImageUtil {
/**
* 返回figure的图片
* @param figure
* @param width
* @param height
* @return
*/
public static final Image getFigureImage(IFigure figure, int width, int height) {
Image rootImage = new Image(Display.getDefault(), width, height);
GC gc = new GC(rootImage);
Graphics graphics = new SWTGraphics(gc);
figure.paint(graphics); //通过过给figure传入自定义GC,这个GC将figure绘制到rootImage
gc.dispose();
return rootImage;
}
/**
* 保存ImageData到指定的文件中
* @param image
* @param savePath
* @param format IMAGE_PNG,IMAGE_BMP and so on.
*/
public static final void saveImage(Image image,String savePath,int format){
ImageLoader loader = new ImageLoader();
ImageData data = image.getImageData();
loader.data = new ImageData[] {data};
loader.save(savePath, format);
}
}
注意IMAGE_GIF由于色深8位,高位到低位的保存会失败.如何保存为GIF格式,可以研究下.
*导出action
Action源码/*******************************************************************************
* Copyright(C) 2011 Arzan Corporation. All rights reserved.
*
* Contributors:
* Arzan Corporation - initial API and implementation
*******************************************************************************/
package galaxy.gef.extension.action;
import galaxy.gef.extension.utils.ImageUtil;
import org.eclipse.draw2d.IFigure;
import org.eclipse.gef.GraphicalViewer;
import org.eclipse.gef.LayerConstants;
import org.eclipse.gef.editparts.LayerManager;
import org.eclipse.gef.ui.actions.SelectionAction;
import org.eclipse.gef.ui.parts.GraphicalEditor;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.ui.IWorkbenchPart;
/**
* @author dzh
* @date 2011-8-31 上午10:06:44
*/
public class ExportImageAction extends SelectionAction {
public static final String ID = "galaxy.mars.ide.flow.node.action.ExportImageAction";
private static final String[] EXTENSIONS = new String[] { "*.bmp", "*.jpg",
"*.png" };
private static final int[] TYPES = new int[] { SWT.IMAGE_BMP,
SWT.IMAGE_JPEG, SWT.IMAGE_PNG };
public ExportImageAction(IWorkbenchPart part) {
super(part);
}
/*
* (non-Javadoc)
*
* @see org.eclipse.gef.ui.actions.WorkbenchPartAction#calculateEnabled()
*/
@Override
protected boolean calculateEnabled() {
if (getWorkbenchPart() instanceof GraphicalEditor) {
return true;
}
return false;
}
protected void init() {
super.init();
setText("导出为图片");
setId(ID);
}
public void run() {
FileDialog dialog = new FileDialog(getWorkbenchPart().getSite()
.getShell(), SWT.SAVE);
dialog.setFilterExtensions(EXTENSIONS);
dialog.setText(getText());
dialog.setOverwrite(true);
String savePath = null;
try {
savePath = dialog.open(); //获取保存路径
} catch (Exception e) {
MessageDialog.openError(getWorkbenchPart().getSite().getShell(),
getText(), "图片保存失败!");
return;
}
if (savePath != null) {
int type = dialog.getFilterIndex();
GraphicalViewer viewer = (GraphicalViewer) getWorkbenchPart()
.getAdapter(GraphicalViewer.class);
LayerManager lm = (LayerManager) viewer.getEditPartRegistry().get(
LayerManager.ID); //获取继承LayerManager的RootEditPart,当然也有不继承LayerManager的,故需要判断一下
if (lm == null)
return;
IFigure f = lm.getLayer(LayerConstants.PRINTABLE_LAYERS); //获取需要导出为图片的figure,这里获取RootEditPart的内容层figure
if (f == null)
return;
Image rootImage = ImageUtil.getFigureImage(f, f.getBounds().width,
f.getBounds().height);
ImageUtil.saveImage(rootImage, savePath, TYPES[type]); //调用ImageUtil
rootImage.dispose(); //释放资源
}
}
}
说明,
1)很多RootEditPart,如FreeformGraphicalRootEditPart,在注册时使用LayerManager.ID为key.
2)GEF中Figure分层的原理,简单说,就是把不同的图形如连线,移动时的阴影图形等等放在不同的层上,这些层也是Figure,注册在RootEditPart中.
所以看看RootEditPart的几个实现类源码,就会明白了.
*总结
---把GraphicalViewer编辑器导出到图片的原理,就是定义一个Image的GC,并传给Figure的paint()方法.
---上面例子还需要优化,如导出图片时把图片内容绘制在合适的大小,就是说可能编辑器的边界会大于图形的边界
---org.eclipse.gef.ui.actions.PrintAction,对于绘制可以参考下它的实现.