2015-09-02 5 views
1

Есть ли способ в SWT экспортировать композит в изображение, которое всегда имеет одинаковый размер/разрешение? Проблема в том, что у нас есть панель инструментов, которая всегда выглядит разной при открытии на экранах с различным размером и разрешением дисплея. Теперь я могу экспортировать Dashboard на изображение с фиксированным размером и всегда выглядит одинаково независимо от того, какой размер/разрешение экрана он был создан?Экспортировать композит в изображение независимо от разрешения экрана

В настоящее время мы делаем это так, но, как сказал, что это зависит от того, на дисплее оно было создано на:

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(); 

Есть, например, какой-нибудь способ, чтобы создать виртуальный экран с определенным разрешением, который фактически не отображается и используется только для экспорта Dashboard? Любая помощь или указатели будут оценены.

ответ

1

В одном из моих приложений я создавал графики и диаграммы в 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(); 
    } 
} 

Для вашего случая желание всегда экспортировать в определенном размере, просто замените аргументы ширины и высоты с соответствующими константами.

Edit 1

Я хотел бы добавить, что int imageType аргумент соответствующий SWT модификатор (например: SWT.IMAGE_PNG, SWT.IMAGE_JPEG, SWT.IMAGE_BMP, и т.д ...).

Edit 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 + ")"); 
    } 

} 

В случае этого примера я создаю простой композит, который когда-то добавленный к оболочке будет выглядеть что-то вроде этого: Composite to Write

Когда я нажимаю кнопку, она изменяет размер композита на 500 x 500 и записывает измененный композит в файл. В результате эта картина: Image of resized composite

я должен отметить, что я заметил композитное мерцание, когда кнопка нажата, так что это не может происходить полностью в фоновом режиме или «выкл экране», как я первоначально предложил.

+0

Спасибо за ответ, но можете ли вы более подробно описать, как вы создали экранный экран? Я еще не нашел решение для этого ... И после установки размера композита он автоматически изменяется или мне нужно вызвать какой-то метод для этого? – tom1991te

+0

Итак, в этом случае «compositeToDraw» будет вашей панелью инструментов, в первой строке мы создадим новое изображение с требуемой шириной и высотой, а затем создадим новый графический компонент для этого изображения, затем мы изменим размер исходного композита, а затем скажем его пишите себе в новый графический компонент для изображения. Наконец, мы вернем исходный композитный исходный размер, а затем напишем новое измененное изображение в файл.Изменение размера оригинального композита никогда не реализуется «на экране», поскольку родитель исходного композита не обновляется, поэтому комментарий «за пределами экрана». – Automaton

+0

ok Я вижу, что вы имеете в виду сейчас с частью «вне экрана», но это все еще не работает для меня. После изменения размера композита и его печати на изображение изображение имеет нужный размер, но композит по-прежнему находится в исходном размере ... Это означает, что на изображении сейчас много свободного места. Любые идеи, что я делаю неправильно? – tom1991te

Смежные вопросы