最近时而忙一阵,也在看些书,几篇文章都没写完.一晃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,对于绘制可以参考下它的实现.