Equivalent of BufferedImage (java awt) on JavaFx - javafx

I'm working with JavaFx and i'm looking for an equivalent of the AWT BufferedImage. I saw that I can used SwingFXUtils to used an awt BufferedImage with JavaFx but I don't want to used awt.
In fact I'm looking for a structure to display a table of pixel witch is associated to a ColorModel.
Does anybody know some equivalent with JavaFx ?
Thanks a lot.

The closest you get to a BufferedImage in JavaFX is javafx.scene.image.WritableImage. It is a subclass of javafx.scene.image.Image, and was introduced in JavaFX 2.2.
Depending on your use case, javafx.scene.canvas.Canvas and javafx.scene.canvas.GraphicsContext (similar to a Graphics2D Java2D) might be a better fit.
To paint on a Canvas node and get the contents in a WritableImage, use (adapted from the Canvas JavaDoc):
// Create canvas
Canvas canvas = new Canvas(250, 250);
GraphicsContext gc = canvas.getGraphicsContext2D();
// Paint on it
gc.setFill(Color.BLUE);
gc.fillRect(75, 75, 100, 100);
// NOTE: The canvas must be part of a Scene for the following to work properly, omitted for brevity
// Obtain a snapshot of the canvas
WritableImage image = canvas.snapshot(null, null);
See Working with Canvas from he JavaFX tutorials for more information.

Related

Can't see the texture of the Sphere from inside in JavaFX [duplicate]

Is it possible to create a photosphere in JavaFX that is similar to photoshpere in Google map? If yes, how?
The answer is yes, you can create a photosphere in JavaFX.
As for the how, there's an easy solution based on a sphere from the 3D API, but we can implement an improved solution, with a custom mesh.
Let's start by using a regular sphere. We just need a 360º image, like this one.
As we want to see from the inside of the sphere, we have to flip the image horizontally, and add it to the sphere material's diffusion map.
Then we just need to set up a camera in the very center of the sphere, add some lights and start spinning.
#Override
public void start(Stage primaryStage) {
PerspectiveCamera camera = new PerspectiveCamera(true);
camera.setNearClip(0.1);
camera.setFarClip(10000.0);
camera.setFieldOfView(90);
Sphere sphere = new Sphere(1000);
sphere.setCullFace(CullFace.NONE);
PhongMaterial material = new PhongMaterial();
/*
"SonyCenter 360panorama" by François Reincke - Own work. Made using autostitch (www.autostitch.net)..
Licensed under CC BY-SA 3.0 via Wikimedia Commons - http://commons.wikimedia.org/wiki/File:SonyCenter_360panorama.jpg#mediaviewer/File:SonyCenter_360panorama.jpg
*/
material.setDiffuseMap(new Image(getClass().getResource("SonyCenter_360panorama_reversed.jpg").toExternalForm()));
sphere.setMaterial(material);
Group root3D = new Group(camera,sphere,new AmbientLight(Color.WHITE));
Scene scene = new Scene(root3D, 800, 600, true, SceneAntialiasing.BALANCED);
scene.setCamera(camera);
primaryStage.setTitle("PhotoSphere in JavaFX3D");
primaryStage.setScene(scene);
primaryStage.show();
final Timeline rotateTimeline = new Timeline();
rotateTimeline.setCycleCount(Timeline.INDEFINITE);
camera.setRotationAxis(Rotate.Y_AXIS);
final KeyValue kv1 = new KeyValue(camera.rotateProperty(), 360);
final KeyFrame kf1 = new KeyFrame(Duration.millis(30000), kv1);
rotateTimeline.getKeyFrames().addAll(kf1);
rotateTimeline.play();
}
Now you will want to add some controls to the camera (so you can navigate). You will discover that this solution has a weak spot at the top and bottom of the sphere, due to the fact that all the top or bottom side of the image is located in one point:
You can find a solution to this problem at the F(X)yz library here. A custom mesh called SegmentedSphereMesh allows you to crop the extremes of the sphere, so the image can keep its aspect ratio without being stretched.
If you clone and build the repo, add FXyz.jar to your project, and just replace Sphere in the previous snippet with this:
SegmentedSphereMesh sphere = new SegmentedSphereMesh(100,0,26,1000);
sphere.setCullFace(CullFace.NONE);
sphere.setTextureModeImage(getClass().getResource("SonyCenter_360panorama_reversed.jpg").toExternalForm());
In the same library you can find SkyBox, based on a cube and one square image on each of its faces. Also check the advanced camera options.
Finally, note that this and more 3D advanced shapes are now demonstrated in the F(X)yz-Sampler application.

Canvas image not grabbed in QQuickWindow

I need to capture an image from QML which has Canvas elements. Whereas Canvases are displayed fine they are not correctly saved in the picture snapshots.
I have used QQuickWindow grabWindow method as described in the solutions of this link and the images are saved in the UI thread called by afterRendering signal (I have tried frameSwapped signal too). Result is that all QML objects are saved but not Canvas objects.
Both the renderStrategy and renderTargetof Canvases are set to the default values. They are simple Canvases as shown below:
Canvas {
id:canvas
onPaint:{
var ctx = canvas.getContext('2d');
ctx.beginPath();
ctx.moveTo(20, 0);
ctx.bezierCurveTo(-10, 90, 210, 90, 180, 0);
ctx.stroke();
//...
}
}
I have noticed that the afterRendering signal is called multiple times.
Any suggestion is really appreciated! :)

In Qt, how to perform hide operation in smoother way?

In Qt, whenever a widget is set to hide, I want to perform the action in smooth way.
Is there any standard function for that?
Heres example for show and hide button:
void MainWindow::hideButton(){
QGraphicsOpacityEffect* fade_effect = new QGraphicsOpacityEffect(this);
ui->pushButton->setGraphicsEffect(fade_effect);
QPropertyAnimation *animation = new QPropertyAnimation(fade_effect, "opacity");
animation->setEasingCurve(QEasingCurve::InOutQuad);
animation->setDuration(5000);
animation->setStartValue(1);
animation->setEndValue(0.01);
animation->start(QPropertyAnimation::DeleteWhenStopped);
}
void MainWindow::showButton(){
QGraphicsOpacityEffect* fade_effect = new QGraphicsOpacityEffect(this);
ui->pushButton->setGraphicsEffect(fade_effect);
QPropertyAnimation *animation = new QPropertyAnimation(fade_effect, "opacity");
animation->setEasingCurve(QEasingCurve::InOutQuad);
animation->setDuration(5000);
animation->setStartValue(0.01);
animation->setEndValue(1.0);
animation->start(QPropertyAnimation::DeleteWhenStopped);
}
Use the animation framework and set the geometry to 0,0 for the height and width, when you restore it just set it back to the previous height and width value. There's various easing effects in there for you to use as you do it, and a few code examples.

Qt QLabel fails to resize

I implemented QLabel much like Qt's ImageViewer example, except I use QGridLayout for positioning my widgets. I also implemented similar lines for scaling my QLabel using QScrollBar, but QLabel just doesn't scale like it should inside the QScrollArea. I am not sure if it is related to some kind of GridLayout management issue or something else. I have been reading everywhere and trying different things for 3 days now. Below I list the relevant portion of my code.
In my Viewer class constructor:
{
imageLabel1 = new QLabel;
imageLabel1->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
imageLabel1->setScaledContents(true);
scrollArea1 = new QScrollArea;
scrollArea1->setWidget(imageLabel1);
scrollArea1->setWidgetResizable(true);
....
QGridLayout *centralLayout = new QGridLayout;
centralLayout->addWidget(scrollArea1, 0, 0);
...}
and my scaleImage method:
void Viewer::scaleImage1(int factor)
{
Q_ASSERT(imageLabel1->pixmap());
scaleFactor *= (1 + factor);
//imageLabel1->resize(scaleFactor* imageLabel1->pixmap()->size());
imageLabel1->pixmap()->toImage().scaled(scaleFactor* imageLabel1->pixmap()->size(), Qt::KeepAspectRatio, Qt::FastTransformation);
imageLabel1->adjustSize();
adjustScrollBar(scrollArea1->horizontalScrollBar(), factor);
adjustScrollBar(scrollArea1->verticalScrollBar(), factor);
imageLabel1->update();
}
My scaleImage1 function is a public slot, and it receives signal from a scrollbar that goes between 0 and 2 so that, into the scaleFactor, the imageLabel1 is designed to be capable of being zoomed in up to 3 times its original size. But when I run the code, I don’t observe the imageLabel becoming enlarged inside the QScrollArea, which I saw in the imageViewer demo. The imageLabel1 simply retains the original size as it is loaded and does not respond to the valueChange() of scrollbar.
I'd appreciate your advice/tips very much.
I think is because you set QSizePolicy::Minimum to the imageLabel, try with MinimumExpanding or other that better fit your needs.

add uicomponent inside a sprite

i want to add UIComponent inside a spite. here is the code:
private function make() : void {
var circle : Sprite = new Sprite();
circle.graphics.beginFill(0xFF0000, 0.2);
circle.graphics.drawCircle(0, 0, 20);
var button : Button = new Button();
button.label = "testing...";
var wrapper : UIComponent = new UIComponent();
circle.addChild( button );
wrapper.addChild( circle );
addChild( wrapper );
}
the problem is that button is added, but is not displayed. if i do reversed - add sprite to uicomponent - everything works fine, but this way it doesn't work. i tried to use invalidate functions for button etc... even tried making "circle" as UIMovieClip, but no luck - button is still invisible. also if i simply do "addChild( button );" - it is shown, what the... please help, what i am doing wrong? how can i add a button inside a sprite?
Short answer, you can't. What you CAN do is instead of using Sprite, you use UIComponent for your circle.
The reason for this is that UIComponent has A LOT of code that changes how it behaves, including how to add and layout children. You could essentially take the same code to a Sprite since UIComponent does extend it, however that would be VERY redundant. This works great for me:
private function make() : void {
var circle : UIComponent= new UIComponent();
circle.graphics.beginFill(0xFF0000, 0.2);
circle.graphics.drawCircle(0, 0, 20);
var button : Button = new Button();
button.label = "testing...";
var wrapper : UIComponent = new UIComponent();
circle.addChild( button );
wrapper.addChild( circle );
addChild( wrapper );
}
Unfortunately, in order to use Sprite the way you are trying to do it, you would have to extend Sprite and implement IUIComponent.
Taken from the Flex 3 Language Reference:
Note: While the child argument to the
method is specified as of type
DisplayObject, the argument must
implement the IUIComponent interface
to be added as a child of a container.
All Flex components implement this
interface.
Sprite does not implement IUIComponent, so you are experiencing a pretty typical issue. UIComponent's don't typically have speed issues when compared to Sprites, so I would recommend just drawing on your UIComponent.
As stated before, you /could/ extend Sprite to implement IUIComponent, but it's a pain.
Hope this helps!

Resources