在我的一个应用程序中,我在 SWT 中创建图形和图表。用户能够将这些导出为他们指定的大小和格式的图像。我的解决方案是获取图表组合的 GC 并将其重新绘制到屏幕外的新组合,然后导出新绘制的组合。
这是我完成此任务的课程:
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.Composite;
/**
* The class used for writing an {@link Composite} to an image file
*
* @author David L. Moffett
*
*/
public class CompositeImageWriter
{
/**
* Redraws the composite to the desired size off-screen and then writes that
* composite as an image to the desired location and in the desired format
*
* @param absolutePath
* the absolute path to the desired output file
* @param compositeToDraw
* the composite to be written to file as an image
* @param width
* the desired width in pixels that the composite should be redrawn
* to
* @param height
* the desired height in pixels that the composite should be redrawn
* to
* @param imageType
* an int representing the type of image that should be written
*/
public static void drawComposite(String absolutePath, Composite compositeToDraw, int width,
int height, int imageType)
{
Image image = new Image(compositeToDraw.getDisplay(), width, height);
GC gc = new GC(image);
int originalWidth = compositeToDraw.getBounds().width;
int originalHeight = compositeToDraw.getBounds().height;
compositeToDraw.setSize(width, height);
compositeToDraw.print(gc);
compositeToDraw.setSize(originalWidth, originalHeight);
ImageLoader loader = new ImageLoader();
loader.data = new ImageData[] { image.getImageData() };
loader.save(absolutePath, imageType);
image.dispose();
gc.dispose();
}
}
如果您希望始终以特定大小导出,只需将宽度和高度参数替换为适当的常量即可。
编辑 1
我应该补充一点,int imageType 参数是对应的 SWT 修饰符(例如:SWT.IMAGE_PNG、SWT.IMAGE_JPEG、SWT.IMAGE_BMP 等...)。
编辑 2
我更新了静态引用以动态地从compositeToDraw 中获取显示。此外,这是我放在一起的一个示例,它使用CompositeImageWriter,您可以使用它来调试您的问题:
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
public class CompositeToWrite extends Composite
{
private int width, height;
private Label l;
public CompositeToWrite(Composite parent, int style)
{
super(parent, style);
this.setLayout(new GridLayout(1, true));
this.addListener(SWT.Resize, new Listener()
{
@Override
public void handleEvent(Event event)
{
updateText();
}
});
Button b = new Button(this, SWT.NONE);
b.setText("Export as image (500, 500)");
b.addListener(SWT.Selection, new Listener()
{
@Override
public void handleEvent(Event event)
{
CompositeImageWriter.drawComposite("./img/output.png", CompositeToWrite.this, 500, 500,
SWT.IMAGE_PNG);
}
});
l = new Label(this, SWT.CENTER);
GridData gd = new GridData(SWT.FILL, SWT.FILL, true, true);
gd.verticalAlignment = SWT.CENTER;
l.setLayoutData(gd);
updateText();
}
protected void updateText()
{
width = this.getBounds().width;
height = this.getBounds().height;
l.setText("My label is centered in composite (" + width + ", " + height + ")");
}
}
在这个例子中,我创建了一个简单的组合,一旦添加到外壳中,它看起来像这样:
当我单击按钮时,它会将合成的大小调整为 500 x 500,并将调整大小的合成写入文件。结果是这张图:
我应该注意到,单击按钮时我确实注意到复合闪烁,因此这可能不会像我最初建议的那样完全在后台或“屏幕外”发生。