This is the case:
I have a Mesh and PointLight added to the pane and I want to take snapshot from pane and show the result in the image view. But it only works when I add the pane to the scene.
Is there any way to take snapshot from a node which has been not added to the scene?
Accoring to documentation of Node.snapshot
NOTE: In order for CSS and layout to function correctly, the node must be part of a Scene (the Scene may be attached to a Stage, but need not be).
You can create new Scene without attaching it to Stage and even without displaying it:
WritableImage writableImage = new WritableImage(1000, 600);
// here is your node such as PointLight
new Circle(200, 200, 50).snapshot(null, writableImage);
new Scene(chartVH, 1000, 600);
chartVH.snapshot(null, writableImage);
File outFile = new File("/tmp/aa.png");
System.out.println(outFile);
try {
ImageIO.write(SwingFXUtils.fromFXImage(writableImage, null), "png", outFile);
} catch (IOException e) {
e.printStackTrace();
}
Related
I am making a game where the data to be displayed in the Main Menu is fetched from the API. I store the data in a class and loop through the data to map the data in the Menu.
foreach(var dt in mainMenuDto.data)
{
GameObject _catogeryPrefabTemp = Instantiate(catogeryPrefab);
Vector3 originalSize = _catogeryPrefabTemp.transform.localPosition;
_tabGroup.objectsToSwap.Add(_catogeryPrefabTemp);
_catogeryPrefabTemp.transform.SetParent(catogeryParent.transform);
_catogeryPrefabTemp.transform.localPosition = originalSize;
_catogeryPrefabTemp.transform.localScale = new Vector3(1, 1, 1);
foreach (var item in dt.games)
{
Texture2D image = await (GetRemoteTexture(item.thumbnail));
tex.Add(image);
await _catogeryPrefabTemp.GetComponent<CatogeryInitialise>().InstantiateGame(gameButtonPrefab, item.slug,image);
}
}
Now , this works fine but when I change the scene and come back to The main Menu, the whole mapping process takes place again. How do I change the main menu to be saved even during scene changes.
Use DontDestroyOnLoad
This method will tell unity to keep your menu between scenes. You will be able to see it under separate DontDestroyOnLoad label in your scene hierarchy.
In my (full-screen) program I have several items displayed in a layout. What I would like to do is that when I tap or click on a item is to show a full screen editor. The idea is to have transition from the item shown to the editor.
When the editor is shown I first display a semi-transparent view on top of the stackpane, underneath the other items are still visible. The selected item should 'move' to the upper layer, and then start to transform to its editor shape. Closing the editor should of course be a reverse course of actions.
The first attempt was to move the from its container to the upper layer, but JavaFX complained about the bound properties. I rather not have to code a whole bunch of bind/unbinds, so I assumed this was not the route.
My next attempt was something like this:
private volatile FullScreenService fullscreenService;
private void showFullPhoto(MouseEvent e) {
FullScreenService service = fullscreenService;
if (service != null) {
try {
Node node = (Node) e.getSource();
ImageView photoView = (ImageView)node.lookup("#image");
Image image = photoView.getImage();
Pane pane = new Pane();
pane.setPrefSize(1920d, 1080d);
ImageView copy = new ImageView(image);
copy.setRotate(node.getRotate());
node.setVisible(false);
Bounds bounds = photoView.localToScene(photoView.getBoundsInLocal());
copy.setLayoutX(bounds.getMinX());
copy.setLayoutY(bounds.getMinY());
pane.getChildren().add(copy);
service.requestFullScreen(pane);
} catch (InUseException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
}
The idea is to hide the original view and 'clone' the part that should be shown (and then transitioned). In this case I extract the image part out of a photo (that also has a border and caption), and make a copy on the editor screen.
However the location of the image does not match the original location exactly, it is off by a couple of pixels, making the image 'jump'.
I've created the pane to be exact the size of the screen, so I thought I could assume scene coordinates are the same as the new node's coordinates.
Abstracting my question: given two overlapping panes, how to make sure a node is exactly on top of another node?
Is there a way to make a snapshot of entire Stage (or Window in general) with decoration (titlebar, border, etc.) in JavaFX? I know that I can make a snapshot of a Scene, but it would not contain window decotation.
[EDIT]
I need to take a snapshot of stage even if it is not visible (is hidden behind another window). So using java.awt.Robot.createScreenCapture(..) is not suitable.
You could use the Robot createScreenCapture class to do it als Scene.snapshot only captures the scene itself.
Rectangle screenRect = new Rectangle(Toolkit.getDefaultToolkit().getScreenSize());
BufferedImage capture = new Robot().createScreenCapture(screenRect);
ImageIO.write(capture, "bmp", new File(args[0]));
It's a bit of code, you have to make a BufferedImage and then convert it to a WriteableImage. There may be an easier way to do this, but to get the window, this is the way I do it:
NOTE: To get the stage, use the following code (you can use any fx:id you have defined; doesn't have to be the AnchorPane).
#FXML private AnchorPane ap;
Stage stage = (Stage) ap.getScene().getWindow();
File file = new File("snapshot.png");
try {
Rectangle rectangle = new Rectangle((int)stage.getX(), (int)stage.getY(),
(int)stage.getWidth(), (int)stage.getHeight());
BufferedImage bufferedImage = new Robot().createScreenCapture(rectangle);
ImageIO.write(bufferedImage, "png", file);
} catch (IOException ex) {
//IOException
} catch (AWTException ex) {
//AWTException
}
Also, be sure to be using the java.awt.Rectangle and not the javafx one.
Hi does anyone know a good way to take a screenshot of a simulation, in such way that you can specify the resolution and get a higher quality image?
the only way i can think of is zooming in and stitch multiple image together, but it takes a long time...
update:
I've managed to successfully export the whole area, the magic parameter is the: .setAnimationParameterEnabled(Panel.ANIM_BOUNDS_CLIPPING_XJAL, false)
it will force Anylogic to draw the whole area, and not just the visible area.
But it doesn't always work. I have to run the code, move around the area, zoom in/out and try again. At some point it gets really glitchy, probably because it starts to draw every thing, and then the code works. The problem is that i can't figure out exactly what to do to make it work...
java.awt.Component alPanel = getExperiment().getPresentation().getPanel();
getExperiment().getPresentation().getPanel().setAnimationParameterEnabled(Panel.ANIM_BOUNDS_CLIPPING_XJAL, false);
getExperiment().getPresentation().setMaximized(false);
getExperiment().getPresentation().setPanelSize(5000, 5000);
java.awt.image.BufferedImage imageExperiment = new java.awt.image.BufferedImage(
alPanel.getWidth(),
alPanel.getHeight(),
java.awt.image.BufferedImage.TYPE_INT_RGB
);
getExperiment().drawPresentation(getExperiment().getPresentation().getPanel(), imageExperiment.createGraphics(), false);
java.awt.Component component = getExperiment().getPresentation().getPanel();
// call the Component's paint method, using
// the Graphics object of the image.
component.paintAll( imageExperiment.getGraphics() ); // alternately use .printAll(..)
try {
// write the image as a PNG
javax.imageio.ImageIO.write(
imageExperiment,
"png",
new File("screenshotAnylogic.png"));
} catch(Exception e) {
e.printStackTrace();
}
Okay... so after a lot of experimentation, i found that the "magic parameter" wasn't as magic as i thought.
but this piece of code should be able to create a screenshot that extends the visible area:
public void capturePanel (ShapeGroup p, String fileName) {
Panel argPanel = p.getPresentable().getPresentation().getPanel();
BufferedImage capture = new BufferedImage(4000, 4000, BufferedImage.TYPE_INT_ARGB);
Graphics2D g = capture.createGraphics();
g.setClip( -200, -200, 4000, 4000 );
p.draw( argPanel, g, null, true );
g.dispose();
try {
ImageIO.write(capture, "png", new File(fileName));
} catch (IOException ioe) {
System.out.println(ioe);
}
}
Well, afaik there is no built in method in Anylogic for that.You could try to use Java to realize that though. It is possible to get the Panel that contains the simulation via getExperiment().getPresentation().getPanel() and you can create an image from that. This is explained here for example and the code would look like this:
public static BufferedImage getScreenShot(Component component)
{
BufferedImage image = new BufferedImage(
component.getWidth(),
component.getHeight(),
BufferedImage.TYPE_INT_RGB
);
// call the Component's paint method, using
// the Graphics object of the image.
component.paint( image.getGraphics() ); // alternately use .printAll(..)
return image;
}
public static void saveComponentScreenshot(Component component)
{
try {
// write the image as a PNG
ImageIO.write(
getScreenShot(component),
"png",
new File("screenshot.png"));
} catch(Exception e) {
e.printStackTrace();
}
}
Unfortunately this does not give you the bigger viewport you probably want to have. Maybe the method public final void drawPresentation(Panel panel, java.awt.Graphics2D g, boolean publicOnly) that is available from the Experiment object returned from getExperiment() could help you to draw the simulation on a custom Panel with the wanted dimensions. Pretty hacky but it's all that I can come up with ^^
I'm trying to use the new UI objects in Unity 4.6 to create a ranking screen where I download information about the users and show them. Among those informations I have an URL pointing to their picture.
Before the UI tools I was doing it with GUITexture and using the www.LoadImageIntoTexture method, but there doesn't seem to be a similar solution for UI Images. Using a GUITexture with a Rect Transform doesn't seem to work.
Should I just manually download the image and load it into the image or is there a similiar solution as with using WWW class?
The new Image component takes requires a sprite to render.
What should work is download a PNG texture using the WWW class, then creating a sprite and finally assigning it to the component.
Here's some sample code.
Create a new Monobehaviour, paste below code into it (I called my script "LoadImageToButton")
Create a new UIButton
Attach the Monobehaviour created in Step 1 to the Button
In the Button's "OnClick" event, Drag the button created in Step 2 (this same button) into the GameObject field
Select the "LoadImage" function as the function to call for the OnClick event. (In my case it was "LoadImageToButton.LoadImage")
Hit Play, click the button. You should see the button's image change (It looks terrible, but it works)
See the pictures attached for actual results.
//This is the method you call if you use the "OnClick" event from a button click.
//We cannot call the Coroutine function below, because it breaks the rule for
//the event system. i.e. Must be a return type of void.
public void LoadImage () {
//Call the actual loading method
StartCoroutine(RealLoadImage());
}
//This is where the actual code is executed
private IEnumerator RealLoadImage () {
//A URL where the image is stored
string url = "http://www.axsu3d.com/DLs/AxSWP8Plugin/TileLogo.png";
//Call the WWW class constructor
WWW imageURLWWW = new WWW(url);
//Wait for the download
yield return imageURLWWW;
//Simple check to see if there's indeed a texture available
if(imageURLWWW.texture != null) {
//Construct a new Sprite
Sprite sprite = new Sprite();
//Create a new sprite using the Texture2D from the url.
//Note that the 400 parameter is the width and height.
//Adjust accordingly
sprite = Sprite.Create(imageURLWWW.texture, new Rect(0, 0, 400, 400), Vector2.zero);
//Assign the sprite to the Image Component
GetComponent<UnityEngine.UI.Image>().sprite = sprite;
}
yield return null;
}