Image 如何在运行时生成动态图像?
我正在开发一款基于NetBeans平台的纸牌游戏,我正努力让自己的头脑去思考动态图像。为什么是动态的?我希望卡片在运行时根据页面的变化进行调整,例如名称、文本、成本等 我对它的第一个攻击是创建一个组件JPanel,在其中预先放置标签,然后根据卡片值加载文本/图像。这似乎很好,但当我想到一些页面在以后的版本中有不同的外观,这意味着并非所有内容都在同一个位置时,这就变得很麻烦了 因此,我试图在某种模板的基础上了解实现这一点的方法 有什么想法吗Image 如何在运行时生成动态图像?,image,dynamic,netbeans-platform,Image,Dynamic,Netbeans Platform,我正在开发一款基于NetBeans平台的纸牌游戏,我正努力让自己的头脑去思考动态图像。为什么是动态的?我希望卡片在运行时根据页面的变化进行调整,例如名称、文本、成本等 我对它的第一个攻击是创建一个组件JPanel,在其中预先放置标签,然后根据卡片值加载文本/图像。这似乎很好,但当我想到一些页面在以后的版本中有不同的外观,这意味着并非所有内容都在同一个位置时,这就变得很麻烦了 因此,我试图在某种模板的基础上了解实现这一点的方法 有什么想法吗 还有一个后续问题:最后,我有时间回到这个话题,并且能够找
还有一个后续问题:最后,我有时间回到这个话题,并且能够找到一种使用的方法 这些图片与我将在应用程序中使用的不太接近,但可以作为概念证明 包javaapplication3 导入java.awt.*;导入java.awt.font.FontRenderContext;进口 java.awt.font.LineBreakMeasurer;导入java.awt.font.texttribute; 导入java.awt.font.TextLayout;导入java.awt.image.buffereImage; 导入java.io.File;导入java.io.IOException;进口 java.net.MalformedURLException;导入java.net.URL;进口 java.text.AttributedCharacterator;进口 java.text.AttributeString;导入java.util.ArrayList;进口 java.util.HashMap;导入java.util.logging.Level;进口 java.util.logging.Logger;导入javax.imageio.imageio /*****作者Javier A.Ortiz Bultron */公共类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,
无效,例如;
}捕捉异常{
Logger.getLoggerDefaultImageManager.class.getName.logLevel.SEVERE,
无效,例如;
}
}
/**
*用于创建最终图像的层
*/
私有ArrayList层=新建ArrayList;
私有ArrayList textLayers=新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格式来存储所有这些信息,因此很容易配置。在下面的例子中,太阳被画在雨的上面,而文本位于所有这些之上。对于我的应用程序,每一层将一起构建我想要的页面
以下是我使用的图像:
最后的结果是:
你可以发布一些图片来澄清吗?没有那么清楚:我现在无法从工作中获取这些图片,但是你可以到这里的参考资料中获取一个想法:!我的游戏就是基于这一点。链接不起作用…你可以画一个草图,你的确切意思是什么…或者试着提出一个详细的问题,请…出于某种原因,感叹号没有作为链接的一部分。我现在正在处理它。。。