我没有在java中处理图像的经验。我的目标是结合几个图像。更详细一点,我有一个模板图像和一些其他图像。我想将这些图像放在特定位置的模板图像中。 例如:
模板图片:
特定图片:
所以,我想把狗的图像放到猫的图像位置并存储创建的图像。
请告诉我最简单的方法是做什么的?
答案 0 :(得分:5)
正如法比安指出的那样,识别模式可能无法给出预期的结果,所以我的建议将是另一种选择
如果您控制模板并将其作为选项提供给用户,则可以自己实现这些模板并在占位符节点中填充图像。合并后的图像来自整体快照
我已经包含了一个简单的示例,但请注意它的未完全实现(布局等),因此请将其视为概念验证。它仍然可以在下面构建,同时显示不同的图像,文本装饰,星星等,以更接近地表示您提供的示例图像
这可能不是最简单的方法,但它可能是一种愉快的学习体验。这也可能是一个可行的选择,因为您没有Java的图像处理经验
public class ImageTemplateNode extends Region{
private SimpleObjectProperty<Image> displayedImageProperty;
private ObservableList<Node> children = FXCollections.observableArrayList();
private Random random = new Random();
private int rows, columns;
private final int maximumRotation = 15;
public ImageTemplateNode(int rows, int cols, Image imageToDisplay){
this.rows = rows;
this.columns = cols;
this.displayedImageProperty = new SimpleObjectProperty<>(imageToDisplay);
createDisplayNodes();
setPadding(new Insets(10));
Bindings.bindContentBidirectional(getChildren(), children);
}
public ImageTemplateNode(int rows, int cols, Image imageToDisplay, Image backgroundImage){
this(rows, cols, imageToDisplay);
setBackgroundImage(backgroundImage);
}
private void createDisplayNodes(){
for(int count = 0; count < (rows * columns); count++){
StackPane container = new StackPane();
container.setRotate(getRandomRotationValue());
container.setBackground(
new Background(new BackgroundFill(getRandomColour(), new CornerRadii(5), new Insets(5))));
container.maxWidthProperty().bind(displayedImageProperty.get().widthProperty().add(25));
container.maxHeightProperty().bind(displayedImageProperty.get().heightProperty().add(25));
ImageView displayNode = new ImageView();
displayNode.imageProperty().bind(displayedImageProperty);
displayNode.fitWidthProperty().bind(container.widthProperty().subtract(25));
displayNode.fitHeightProperty().bind(container.heightProperty().subtract(25));
container.getChildren().setAll(displayNode);
children.add(container);
}
}
private int getRandomRotationValue(){
int randomValue = random.nextInt(maximumRotation);
//Rotate clockwise if even, anti-clockwise if odd
return randomValue % 2 == 0 ? randomValue : 360 - randomValue;
}
private Color getRandomColour(){
int red = random.nextInt(256);
int green = random.nextInt(256);
int blue = random.nextInt(256);
return Color.rgb(red, green, blue);
}
@Override
protected void layoutChildren() {
//Calculate the dimensions for the children so that they do not breach the padding and allow for rotation
double cellWidth = (widthProperty().doubleValue()
- getPadding().getLeft() - getPadding().getRight() - maximumRotation) / columns;
double cellHeight = (heightProperty().doubleValue()
- getPadding().getTop() - getPadding().getBottom() - maximumRotation) / rows;
for (int i = 0; i < (rows); i++) {
for (int j = 0; j < (columns); j++) {
if (children.size() <= ((i * (columns)) + j)) {
break;
}
Node childNode = children.get((i * (columns)) + j);
layoutInArea(childNode,
(j * cellWidth) + getPadding().getLeft(),
(i * cellHeight) + getPadding().getTop(), cellWidth, cellHeight,
0.0d, HPos.CENTER, VPos.CENTER);
}
}
}
public void setBackgroundImage(Image backgroundImage){
setBackground(new Background(
new BackgroundImage(backgroundImage,
BackgroundRepeat.REPEAT, BackgroundRepeat.REPEAT, BackgroundPosition.CENTER,
BackgroundSize.DEFAULT)));
}
public void changeDisplayImage(Image newImageToDisplay){
displayedImageProperty.set(newImageToDisplay);
}
public void captureAndSaveDisplay(){
FileChooser fileChooser = new FileChooser();
//Set extension filter
fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("png files (*.png)", "*.png"));
//Prompt user to select a file
File file = fileChooser.showSaveDialog(null);
if(file != null){
try {
//Pad the capture area
WritableImage writableImage = new WritableImage((int)getWidth() + 20,
(int)getHeight() + 20);
snapshot(null, writableImage);
RenderedImage renderedImage = SwingFXUtils.fromFXImage(writableImage, null);
//Write the snapshot to the chosen file
ImageIO.write(renderedImage, "png", file);
} catch (IOException ex) { ex.printStackTrace(); }
}
}
}
截屏:
保存快照: