如何在运行时制作动态图像?

时间:2011-10-11 18:15:00

标签: image dynamic netbeans-platform

我正在开发基于NetBeans平台的纸牌游戏,我正在努力让我的头脑围绕动态图像。为什么动态?好吧,我希望卡片在运行时调整到页面的更改(即名称,文本,成本等)。

我的第一个黑客是创建一个组件(JPanel),其中预先放置了标签,我根据卡片值加载了文本/图像。这似乎工作正常,但当我想到一些页面在后期版本中具有不同的外观(意味着并非所有内容都在同一个地方)时,它变得很麻烦。

所以我试图根据某种模板来了解如何做到这一点。

有什么想法吗?

有一个跟进问题:JList of cards?

1 个答案:

答案 0 :(得分:0)

最后,我有时间回到这一点,并且能够找到使用Java 2D tutorial的方法。

图片并不接近我在申请中使用的图片,但作为概念证明。

  

package javaapplication3;

     

import java.awt。*; import java.awt.font.FontRenderContext;进口   java.awt.font.LineBreakMeasurer; import java.awt.font.TextAttribute;   import java.awt.font.TextLayout; import java.awt.image.BufferedImage;   import java.io.File; import java.io.IOException;进口   java.net.MalformedURLException; import java.net.URL;进口   java.text.AttributedCharacterIterator;进口   java.text.AttributedString; import java.util.ArrayList;进口   的java.util.HashMap; import java.util.logging.Level;进口   java.util.logging.Logger中; import javax.imageio.ImageIO;

     

/ ** * * @author Javier A.OrtizBultró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())。日志(Level.SEVERE,   null,ex);           }       }       / **        *用于创建最终图像的图层        * /       private ArrayList layers = 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