Как сделать динамическое изображение во время выполнения? - PullRequest
0 голосов
/ 11 октября 2011

Я работаю над карточной игрой на платформе NetBeans и изо всех сил пытаюсь разобраться с динамическими изображениями.Почему динамический?Что ж, я хочу, чтобы карточки корректировались во время выполнения в соответствии с изменениями на странице (например, имя, текст, стоимость и т. Д.).

Моим первым взломом было создание компонента (JPanel) с предварительно размещенными метками, гдеЯ загрузил текст / изображение на основе значений карты.Кажется, это работает нормально, но потом стало неприятно, когда я подумал о том, что некоторые страницы выглядят по-другому в более поздних выпусках (то есть не все будет на одном месте).

Так что я пытаюсь понятьо способах сделать это на основе какого-то шаблона.

Есть идеи?

Есть дополнительный вопрос по адресу: Список карточек?

1 Ответ

0 голосов
/ 23 ноября 2011

Наконец-то у меня появилось время вернуться к этому, и я смог найти способ, используя Java 2D-учебник .

Изображения не соответствуют тому, что я буду использовать в своем приложениино служит подтверждением концепции.

пакет javaapplication3;

import java.awt. *;import java.awt.font.FontRenderContext;import java.awt.font.LineBreakMeasurer;import java.awt.font.TextAttribute;import java.awt.font.TextLayout;import java.awt.image.BufferedImage;импорт java.io.File;импорт java.io.IOException;import java.net.MalformedURLException;импорт java.net.URL;import java.text.AttributedCharacterIterator;import java.text.AttributedString;import java.util.ArrayList;import java.util.HashMap;import java.util.logging.Level;import java.util.logging.Logger;import javax.imageio.ImageIO;

/ ** * * @author Javier A. Ortiz Bultrón * / public class DefaultImageManager {

/**
 * @param args the command line arguments
 */
public static void main(String[] args) {
    try {
        // TODO code application logic here
        DefaultImageManager manager = new DefaultImageManager();
        URL url = DefaultImageManager.class.getResource("weather-rain.png");
        manager.getLayers().add(ImageIO.read(url));
        url = DefaultImageManager.class.getResource("weather-sun.png");
        manager.getLayers().add(ImageIO.read(url));
        manager.addText(new Font("Arial", Font.PLAIN, 10), "Many people believe that Vincent van Gogh painted his best works "
                + "during the two-year period he spent in Provence. Here is where he "
                + "painted The Starry Night--which some consider to be his greatest "
                + "work of all. However, as his artistic brilliance reached new "
                + "heights in Provence, his physical and mental health plummeted. ",
                200, 150, new Point(0, 0));
        manager.generate();
    } catch (MalformedURLException ex) {
        Logger.getLogger(DefaultImageManager.class.getName()).log(Level.SEVERE,

null, ex);} catch (IOException ex) {Logger.getLogger (DefaultImageManager.class.getName ()). log (Level.SEVERE, null, ex);}} / ** * Слои, используемые для создания окончательного изображения * / private ArrayList layer = new ArrayList ();private ArrayList textLayers = new ArrayList ();

/**
 * @return the layers
 */
public ArrayList<BufferedImage> getLayers() {
    return layers;
}

private Dimension getMaxSize() {
    int width = 0, height = 0;
    for (BufferedImage img : getLayers()) {
        if (img.getWidth() > width) {
            width = img.getWidth();
        }
        if (img.getHeight() > height) {
            height = img.getHeight();
        }
    }
    return new Dimension(width, height);
}

public void addText(Font font, String text, int height, int width, Point location) {
    BufferedImage textImage = new BufferedImage(width, height,
            BufferedImage.TYPE_INT_ARGB);
    HashMap<TextAttribute, Object> map =
            new HashMap<TextAttribute, Object>();
    map.put(TextAttribute.FAMILY, font.getFamily());
    map.put(TextAttribute.SIZE, font.getSize());
    map.put(TextAttribute.FOREGROUND, Color.BLACK);
    AttributedString aString = new AttributedString(text, map);
    AttributedCharacterIterator paragraph = aString.getIterator();
    // index of the first character in the paragraph.
    int paragraphStart = paragraph.getBeginIndex();
    // index of the first character after the end of the paragraph.
    int paragraphEnd = paragraph.getEndIndex();
    Graphics2D graphics = textImage.createGraphics();
    FontRenderContext frc = graphics.getFontRenderContext();
    // The LineBreakMeasurer used to line-break the paragraph.
    LineBreakMeasurer lineMeasurer = new LineBreakMeasurer(paragraph, frc);
    // Set break width to width of Component.
    float breakWidth = width;
    float drawPosY = 0;
    // Set position to the index of the first character in the paragraph.
    lineMeasurer.setPosition(paragraphStart);

    // Get lines until the entire paragraph has been displayed.
    while (lineMeasurer.getPosition() < paragraphEnd) {
        // Retrieve next layout. A cleverer program would also cache
        // these layouts until the component is re-sized.
        TextLayout layout = lineMeasurer.nextLayout(breakWidth);

        // Compute pen x position. If the paragraph is right-to-left we
        // will align the TextLayouts to the right edge of the panel.
        // Note: this won't occur for the English text in this sample.
        // Note: drawPosX is always where the LEFT of the text is placed.
        float drawPosX = layout.isLeftToRight()
                ? 0 : breakWidth - layout.getAdvance();

        // Move y-coordinate by the ascent of the layout.
        drawPosY += layout.getAscent();

        // Draw the TextLayout at (drawPosX, drawPosY).
        layout.draw(graphics, drawPosX, drawPosY);

        // Move y-coordinate in preparation for next layout.
        drawPosY += layout.getDescent() + layout.getLeading();
    }
    getTextLayers().add(textImage);
}

public void generate() throws IOException {
    Dimension size = getMaxSize();
    BufferedImage finalImage = new BufferedImage(size.width, size.height,
            BufferedImage.TYPE_INT_ARGB);
    for (BufferedImage img : getLayers()) {
        finalImage.createGraphics().drawImage(img,
                0, 0, size.width, size.height,
                0, 0, img.getWidth(null),
                img.getHeight(null),
                null);
    }
    for(BufferedImage text: getTextLayers()){
        finalImage.createGraphics().drawImage(text,
                0, 0, text.getWidth(), text.getHeight(),
                0, 0, text.getWidth(null),
                text.getHeight(null),
                null);
    }
    File outputfile = new File("saved.png");
    ImageIO.write(finalImage, "png", outputfile);
}

/**
 * @return the textLayers
 */
public ArrayList<BufferedImage> getTextLayers() {
    return textLayers;
}

/**
 * @param textLayers the textLayers to set
 */
public void setTextLayers(ArrayList<BufferedImage> textLayers) {
    this.textLayers = textLayers;
} }

Это все еще требует некоторого уточнения, особенно при размещении текста, но это работает.Я думаю, что я могу реализовать формат XML для хранения всей этой информации, так что легко настраивается.В приведенном ниже примере солнце нарисовано поверх дождя, а текст поверх всего этого.Для моего приложения каждый слой будет создавать вместе нужную мне страницу.

Вот изображения, которые я использовал: enter image description here enter image description here

И конечный результат:

enter image description here

...