问题描述
在 SWT 中有没有办法将合成导出为始终具有相同大小/分辨率的图像?问题是我们有一个仪表板,当在具有不同显示尺寸/分辨率的屏幕上打开时,它看起来总是不同的.现在的问题是,我能否将仪表板导出为具有固定大小的图像,并且无论创建的屏幕尺寸/分辨率如何,它始终看起来相同?
Is there a way in SWT to export a composite to an image which always has the same size/resolution? The problem is that we have a Dashboard which looks always different when opening on screens with different display size/resolution. The question is now can I export the Dashboard to an image wich has a fixed size and always looks the same no matter on which screen size/resolution it has been created?
目前我们是这样做的,但如前所述,这取决于创建它的显示器:
For the time being we do it like that but as said it depends on the display it has been created on:
Image image = new Image(Display.getCurrent(), this.content.getBounds().width, this.content.getBounds().height);
ImageLoader loader = new ImageLoader();
FileOutputStream fileOutputStream = new FileOutputStream(file);
GC gc = new GC(image);
this.content.print(gc);
gc.dispose();
loader.data = new ImageData[] { image.getImageData() };
loader.save(fileOutputStream, imageFormat);
fileOutputStream.close();
例如,是否有某种方法可以创建具有特定分辨率的虚拟屏幕,但该屏幕实际上并未显示而仅用于导出仪表板?任何帮助或指示将不胜感激.
Is there for example some way to create a virtual screen with a certain resolution, which isn't actually displayed and only used for exporting the Dashboard?Any help or pointers would be appreciated.
推荐答案
在我的一个应用程序中,我使用 SWT 创建图形和图表.用户能够将这些导出为他们指定的大小和格式的图像.我的解决方案是获取图表合成的 GC 并将其重新绘制到屏幕外的新合成,然后导出新绘制的合成.
In one of my applications I was creating graphs and charts in SWT. The user was able to export these to an image of a size and format that they specified. My solution was to take the GC of the chart composite and redraw it to a new composite off screen, then export the newly drawn composite.
这是我完成的课程:
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();
}
}
对于希望始终以特定尺寸导出的情况,只需将宽度和高度参数替换为适当的常量即可.
For your case of wanting to always export at a specific size, just replace the width and height arguments with appropriate constants.
编辑 1
我应该补充一点,int imageType
参数是相应的 SWT 修饰符(例如:SWT.IMAGE_PNG
、SWT.IMAGE_JPEG
、SWT.IMAGE_BMP 等...).
I should add that the int imageType
argument is the corresponding SWT modifier (for example: SWT.IMAGE_PNG
, SWT.IMAGE_JPEG
, SWT.IMAGE_BMP
, etc...).
编辑 2
我更新了静态引用,以便从 CompositeToDraw 动态获取显示.此外,这是我放在一起的一个示例,它使用 CompositeImageWriter
您可以用来调试您的问题:
I updated the static reference to dynamically get the display from the compositeToDraw. Further, here's an example I put together which uses the CompositeImageWriter
which you may be able to use to debug your issue:
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 + ")");
}
}
在这个例子中,我创建了一个简单的组合,一旦添加到 shell 中,它看起来像这样:
In the case of this example I create a simple composite that once added to a shell will look something like this:
当我单击按钮时,它会将合成大小调整为 500 x 500,并将调整后的合成大小写入文件.结果是这张图:
When I click the button it resizes the composite to 500 x 500 and writes the resized composite to a file. The result is this picture:
我应该注意到,当单击按钮时,我确实注意到复合闪烁,因此这可能不会完全发生在我最初建议的背景或屏幕外"中.
I should note that I did notice the composite flicker when the button is clicked, so this may not be happening completely in the background or "off screen" as I initially suggested.
这篇关于将合成导出为独立于屏幕分辨率的图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!