javafx 2.1 how to save an Image after modification using ColorAdjust - image

I just make a class that let me modify an image like saturation brightness, contrast and hue using ColorAjust Class.
But i dont know how to save that image after making those modifications.
Here is the code:
final Stage imageProcessStage = new Stage();
imageProcessStage.initModality(Modality.APPLICATION_MODAL);
imageImageProcess = new Image(ImagePathImageProcess);
imageViewImageProcess = ImageViewBuilder.create().image(imageImageProcess).build();
ColorAdjust colorAdjust = ColorAdjustBuilder.create().build();
imageViewImageProcess.setEffect(colorAdjust);
//
Label saturationLabel = LabelBuilder.create().text("Saturation").build();
GridPane.setConstraints(saturationLabel, 0, 0);
Slider saturationSlider = SliderBuilder.create().value(50).build();
colorAdjust.saturationProperty().bind(saturationSlider.valueProperty().divide(50).subtract(1));
GridPane.setConstraints(saturationSlider, 1, 0);
GridPane.setHgrow(saturationSlider, Priority.ALWAYS);
Label saturationValueLabel = LabelBuilder.create().minWidth(75).maxWidth(75).build();
saturationValueLabel.textProperty().bind(colorAdjust.saturationProperty().multiply(100).asString("%.2f%%"));
GridPane.setConstraints(saturationValueLabel, 2, 0);
//
Label hueLabel = LabelBuilder.create().text("Hue").build();
GridPane.setConstraints(hueLabel, 0, 1);
Slider hueSlider = SliderBuilder.create().value(50).build();
colorAdjust.hueProperty().bind(hueSlider.valueProperty().divide(50).subtract(1));
GridPane.setConstraints(hueSlider, 1, 1);
GridPane.setHgrow(hueSlider, Priority.ALWAYS);
Label hueValueLabel = LabelBuilder.create().minWidth(75).maxWidth(75).build();
hueValueLabel.textProperty().bind(colorAdjust.hueProperty().multiply(100).asString("%.2f%%"));
GridPane.setConstraints(hueValueLabel, 2, 1);
//
Label brightnessLabel = LabelBuilder.create().text("Brightness").build();
GridPane.setConstraints(brightnessLabel, 0, 2);
Slider brightnessSlider = SliderBuilder.create().value(50).build();
colorAdjust.brightnessProperty().bind(brightnessSlider.valueProperty().divide(50).subtract(1));
GridPane.setConstraints(brightnessSlider, 1, 2);
GridPane.setHgrow(brightnessSlider, Priority.ALWAYS);
Label brightnessValueLabel = LabelBuilder.create().minWidth(75).maxWidth(75).build();
brightnessValueLabel.textProperty().bind(colorAdjust.brightnessProperty().multiply(100).asString("%.2f%%"));
GridPane.setConstraints(brightnessValueLabel, 2, 2);
//
Label contrastLabel = LabelBuilder.create().text("Contrast").build();
GridPane.setConstraints(contrastLabel, 0, 3);
Slider contrastSlider = SliderBuilder.create().value(50).build();
colorAdjust.contrastProperty().bind(contrastSlider.valueProperty().divide(50).subtract(1));
GridPane.setConstraints(contrastSlider, 1, 3);
GridPane.setHgrow(contrastSlider, Priority.ALWAYS);
Label contrastValueLabel = LabelBuilder.create().minWidth(75).maxWidth(75).build();
contrastValueLabel.textProperty().bind(colorAdjust.contrastProperty().multiply(100).asString("%.2f%%"));
GridPane.setConstraints(contrastValueLabel, 2, 3);
//Validate Button
Button btnValider = new Button("Valider");
btnValider.setOnAction(new EventHandler<ActionEvent>() {
public void handle(ActionEvent event) {
// SAVE IMAGE HERE
}
});

Upgrade to JavaFX 2.2 and use the following code in your button event handler.
ImageIO.write(
SwingFXUtils.fromFXImage(
imageViewImageProcess.snapshot(null, null), null
),
"png",
new File("valider.png")
);
Note that the 2.2 is currently in developer preview rather than a GA product, so you may encounter some issues and bugs until the new 2.2 methods have been thoroughly QAed.
Here is a complete, executable example: https://gist.github.com/2870355

A general purpose and simpler version of the code:
private void saveImage(
Image i,
String extension,
String pathname)
throws IOException {
ImageIO.write(
SwingFXUtils.fromFXImage(
image,
null),
extension,
new File(
pathname));
}

Related

How to animate texture coordinates in javafx

Is there some kind of animation for liquid surfaces that mimics waves by animating uvcoordinates like in the picture below?
Can this method be recreated in the JavaFX framework?
animating by replacing textcoordinate values
Animating by replacing texture coordinate values . In this aproach , an integer property changes its value over time with the help of timeline object . there is a listener that will trigger an update in texture u and v coordinate values every time integer property changes . The result will remap normalmap over time bringing a sense of motion.
As you can see the animation only moves in one direction . even if the normal map is seamless tile texture ; this animation is not . it will be reset every 20 seconds . this aproach need improvements , but it's a good starting point I think.
This is a single javafx functional javafx app you can try
normal map file is at this page
App.java
public class App extends Application {
private final float[] uvCoords = {3, 0, 3, 3, 0, 0, 0, 3};
private final IntegerProperty keyCycle = new SimpleIntegerProperty();
#Override
public void start(Stage stage) {
PerspectiveCamera camera = new PerspectiveCamera(true);
camera.setTranslateZ(-8);
camera.setTranslateY(10);
camera.setRotationAxis(Rotate.X_AXIS);
camera.setRotate(45);
PointLight pointLight = new PointLight(Color.LIGHTYELLOW);
pointLight.setTranslateZ(-2.5);
pointLight.setTranslateY(-1.5);
pointLight.setRotationAxis(Rotate.Y_AXIS);
pointLight.setQuadraticAttenuation(0.1);
MeshView meshView = makeMeshView();
PhongMaterial material = new PhongMaterial(new Color(0, 1, 1, 0.5));
material.setSpecularColor(Color.LIGHTYELLOW);
material.setSpecularPower(512);
Image image = new Image("normal.jpg");
material.setBumpMap(image);
meshView.setMaterial(material);
makeCycle();
keyCycle.addListener(e -> {
float add = keyCycle.getValue() / 30000f;
TriangleMesh mesh = (TriangleMesh) meshView.getMesh();
for (int i = 0; i < uvCoords.length; i++) {
uvCoords[i] += add;
}
mesh.getTexCoords().set(0, uvCoords, 0, uvCoords.length);
});
Group group3d = new Group(camera, meshView, pointLight);
Scene scene = new Scene(group3d, 640, 480, true, SceneAntialiasing.BALANCED);
scene.setCamera(camera);
scene.setFill(Color.PERU);
stage.setTitle("Animating uv coordinates in javafx");
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch();
}
private MeshView makeMeshView() {
TriangleMesh mesh = new TriangleMesh();
MeshView mv = new MeshView(mesh);
mesh.getPoints().addAll(-3, -3, 0, 3, -3, 0, -3, 3, 0, 3, 3, 0);
mesh.getTexCoords().addAll(uvCoords);
mesh.getFaces().addAll(0, 0, 3, 3, 1, 1, 0, 0, 2, 2, 3, 3);
return mv;
}
private void makeCycle() {
KeyValue start = new KeyValue(keyCycle, 0, Interpolator.LINEAR);
KeyValue end = new KeyValue(keyCycle, 24 * 20, Interpolator.LINEAR);
KeyFrame kf = new KeyFrame(Duration.seconds(20), start, end);
Timeline tm = new Timeline(kf);
tm.setCycleCount(100);
tm.play();
}
}

Java-FX How to set image in a GridPane on click - game Othello

Hi i'm trying to click on a position (from 0 to 7) in my GridPane.
I would set an image inside it. I tryed everything but i can't see any improvement...
This is my board
Here my code on click on grid
#FXML
private void clickGrid(MouseEvent event) {
myGrid = new GridPane();
black = new Image("othello/images/black.png");
white = new Image("othello/images/white.png");
empty = new Image("othello/images/empty.png");
Node source = (Node)event.getSource() ;
Integer colIndex = GridPane.getColumnIndex(source);
Integer rowIndex = GridPane.getRowIndex(source);
System.out.printf("Mouse clicked cell [%d, %d]%n", colIndex.intValue(), rowIndex.intValue());
myGrid.add(new ImageView(white), colIndex, rowIndex);
}
Here my code when i click restart
#FXML
private void restartGame(ActionEvent event)throws Exception{
myGrid = new GridPane();
black = new Image("othello/images/black.png");
white = new Image("othello/images/white.png");
empty = new Image("othello/images/empty.png");
for (int i = 0; i < 8; i++){ //Per righe
for (int j = 0; j < 8; j++){ // Per colonne
myGrid.add(new ImageView(empty), i, j);
}
}
myGrid.add(new ImageView(black), 3, 3);
myGrid.add(new ImageView(black), 4, 3);
myGrid.add(new ImageView(white), 4, 4);
myGrid.add(new ImageView(white), 4, 3);
}
black is my piece colored of black, for white is white.
Source path
I have main project in src of netbeans.
Inside it, i have:
- othello (it contains my main)
- othello.images (it cointains all my image also backgrounds)
- othello.view (it contains my FXML files)
- othello.model (now nothing)
- othello.controller (it contains the controllers about the fxml files)
I think you don't see new images because you add to a new Grid, not to the existent one:
myGrid = new GridPane(); // !!! here a problem
myGrid.add(new ImageView(white), colIndex, rowIndex);
Don't create a new GridPane on every click:
myGrid = new GridPane(); // delete this
delete this line, and add an image to the GridPane you've prepared in FXML

xamarin Forms - Is it possible to get Grid row selection event?

How do i get row id of grid row selection? I want to add row unique id and i want it on tapped or on clicked. please suggest me if anyone have any idea.
I want to do some thing like this, if i click on the row and i get id. with this id i will fetch another records and send user on another page. for this i need unique id of the row.
i have grid like bellow:
Below is the code i use:
public BusList(Common busdata)
{
InitializeComponent();
this.BindingContext = this;
List<BusDetail> Bus = new List<BusDetail>
{
...
new BusDetail("Nita Travel","Mumbai", "Navsari",new DateTime(2017, 3, 9), "10:15 AM", "09:15 AM")
};
Label header = new Label
{
Text = "GridView Demo",
FontSize = Device.GetNamedSize(NamedSize.Large, typeof(Label)),
HorizontalOptions = LayoutOptions.Center
};
var controlGrid = new Grid
{
RowSpacing = 2,
ColumnSpacing = 2,
Margin = new Thickness(5, Device.OnPlatform(5, 0, 0), 5, 5)
};
controlGrid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(30) });
for (int i = 0; i < Bus.Count(); i++)
{
controlGrid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(30) });
}
controlGrid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) });
controlGrid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) });
controlGrid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) });
controlGrid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) });
Bus = Bus.Where(x => x.FromDest.ToLower().Contains(busdata.FromDest.ToLower()) && x.FromDate == busdata.FromDate).ToList();
controlGrid.Children.Add(new Label { Text = "ID", Font = Font.SystemFontOfSize(NamedSize.Large).WithAttributes(FontAttributes.Bold), BackgroundColor = Color.Gray }, 0, 0);
controlGrid.Children.Add(new Label { Text = "Travel Name", Font = Font.SystemFontOfSize(NamedSize.Large).WithAttributes(FontAttributes.Bold), BackgroundColor = Color.Gray }, 1, 0);
controlGrid.Children.Add(new Label { Text = "Arr Time", Font = Font.SystemFontOfSize(NamedSize.Large).WithAttributes(FontAttributes.Bold), BackgroundColor = Color.Gray }, 2, 0);
controlGrid.Children.Add(new Label { Text = "Dep Time", Font = Font.SystemFontOfSize(NamedSize.Large).WithAttributes(FontAttributes.Bold), BackgroundColor = Color.Gray }, 3, 0);
for (int i = 0; i < Bus.Count(); i++)
{
var clickableRow = new ContentView();
var tapGestureRecognizer = new TapGestureRecognizer();
tapGestureRecognizer.SetBinding(TapGestureRecognizer.CommandProperty, "RowTappedCommand");
tapGestureRecognizer.SetBinding(TapGestureRecognizer.CommandParameterProperty, i.ToString());
clickableRow.GestureRecognizers.Add(tapGestureRecognizer);
clickableRow.BindingContext = i.ToString();
controlGrid.Children.Add(clickableRow, 0, i);
Grid.SetColumnSpan(clickableRow, 3);
controlGrid.Children.Add(new Label { Text = Bus[i].TravelName, BindingContext = Bus[i].TravelName, BackgroundColor = Color.LightGray, VerticalTextAlignment = TextAlignment.Center }, 1, i + 1);
controlGrid.Children.Add(new Label { Text = Bus[i].ArrivalTime, BindingContext = Bus[i].ArrivalTime, BackgroundColor = Color.LightGray, VerticalTextAlignment = TextAlignment.Center }, 2, i + 1);
controlGrid.Children.Add(new Label { Text = Bus[i].DepartureTime, BindingContext= Bus[i].DepartureTime, BackgroundColor = Color.LightGray, VerticalTextAlignment = TextAlignment.Center }, 3, i + 1);
}
this.Padding = new Thickness(10, Device.OnPlatform(20, 0, 0), 10, 5);
this.Content = new StackLayout
{
Children =
{
header,
controlGrid
}
};
}
public void RowTappedCommand(string index)
{
var tappedRow = int.Parse(index);
}
You could add a ContentView to each row on the first column and span it across all columns by using the ColumnSpan property. Then you'd handle the taps with a TouchGestureListener. When creating the Command, you'd also include a CommandParameter which contains the index of the row in question.
Outside the constructor, define this:
public ICommand RowTappedCommand { get; private set; }
Then add the following code somewhere after InitializeComponent:
RowTappedCommand = new Command<string>(RowTapped);
Then create the clickable ContentView controls for each row:
var clickableRow = new ContentView {
HorizontalOptions = LayoutOptions.FillAndExpand,
VerticalOptions = LayoutOptions.FillAndExpand
}
var tapGestureRecognizer = new TapGestureRecognizer();
tapGestureRecognizer.SetBinding(TapGestureRecognizer.CommandProperty, "RowTappedCommand");
var binding = new Binding();
binding.Source = i.ToString();
tapGestureRecognizer.SetBinding(TapGestureRecognizer.CommandParameterProperty, binding); // This is the index of the row
clickableRow.GestureRecognizers.Add(tapGestureRecognizer);
controlGrid.Children.Add(clickableRow, 0, 0);
Grid.SetColumnSpan(clickableRow,3);
You also need to define the method that matches the name defined in the CommandProperty. If you have a view model defined for the view you need to do it there. Otherwise, you'll need to add the method to your view's code behind file (xaml.cs).
void RowTapped(string index)
{
var tappedRow = int.Parse(index);
// Do something with the value
}
Remember to set the BindingContext correctly so that your command gets called. Here's more information about Commands in Xamarin.Forms:
Update: There were a few mistakes that needed to be fixed.
Command wasn't defined correctly.
The binding for the command property needs to be pointing to a static value
Simplifying Events with Commanding

xamarin screen design from code behind

I am new to xamarin.i am trying to create accordian control in xamarin forms.i had created also.in which at starting level i had put only buttons and label like this
for demo purpose.this is i binded from code behind.like this
var vViewLayout1 = new StackLayout()
{
Children = {
new Label { Text = "Regular Board Meeting",HorizontalOptions=LayoutOptions.Center },
new StackLayout
{
Spacing = 5,
Orientation = StackOrientation.Horizontal,
VerticalOptions= LayoutOptions.Center,
HorizontalOptions= LayoutOptions.End,
Children =
{
new Image { Source = "Chat.png"},
new Button { Text ="Reject",BackgroundColor = Color.Red,TextColor = Color.White},
new Button { Text ="Approve",BackgroundColor = Color.Green,TextColor = Color.White}
}
},
//new Label { Text = "Name : S Ravi Kumar" },
//new Label { Text = "Roles : Father,Trainer,Consultant,Architect" }
}
};
var vFirstAccord = new AccordionSource()
{
HeaderText = "ReportToBoardJune 1,2016",
HeaderTextColor = Color.White,
HeaderBackGroundColor = Color.Red,
ContentItems = vViewLayout1
};
return vResult;
but i want to display data such like this
so ,how can i create this from code behind.and which control i should use for box that i highlighed by red arrow.boxview or any other availble in xamarine like table or anything else.
i just started xamarin.so i dont have any idea about its controls.any suggestion or help is apriciated.thanks in advance.
Based on the comments you're going to use grid, and your question is now essentially How can I make a border round the grid in the code behind file?
There is no specific border property for grid as you've discovered. What I've done a few times is create a simple 3x3 grid, and placed 4 boxviews around the edges:
BoxView border()
{
BoxView res = new BoxView
{
Color = Color.Black,
HeightRequest = 4,
WidthRequest = 4
}
return res;
}
Grid gridWithBorder = new Grid
{
RowDefinitions =
{
new RowDefinition { Height = GridLength.Auto},
new RowDefinition { Height = GridLength.Auto},
new RowDefinition { Height = GridLength.Auto}
},
ColumnDefinitions =
{
new ColumnDefinition { Width = GridLength.Auto },
new ColumnDefinition { Width = GridLength.Auto },
new ColumnDefinition { Width = GridLength.Auto }
}
};
gridWithBorder.Children.Add(border(), 0, 3, 0, 1); //add top border
gridWithBorder.Children.Add(border(), 0, 1, 0, 3); // left border
gridWithBorder.Children.Add(border(), 0, 3, 2, 3); // bottom border
gridWithBorder.Children.Add(border(), 2, 3, 0, 3); // right
After this I then add the rest of the layout to row 1 column 1

javafx 2.1 cannot update ImageView after editing its Image

I created an ImaveView and affect an Image object to it. The image is displayed correctly.
I also created a button that open up a new stage (with the image displayed inside) and some slidebars to make image processing.
So now after making some edits how can I update my ImageView with the new image ?
Here is what i have done:
//Boutton Traitement d'image
Button btnImageProcess = new Button("Traitement d'Image");
btnImageProcess.setOnAction(new EventHandler<ActionEvent>() {
public void handle(ActionEvent event) {
ImageProcess imageProcess = new ImageProcess();
imageImageProcess = new Image(ImagePathImageProcess);
imageViewImageProcess = ImageViewBuilder.create().image(imageImageProcess).build();
ColorAdjust colorAdjust = ColorAdjustBuilder.create().build();
imageViewImageProcess.setEffect(colorAdjust);
//
Label saturationLabel = LabelBuilder.create().text("Saturation").build();
GridPane.setConstraints(saturationLabel, 0, 0);
Slider saturationSlider = SliderBuilder.create().value(50).build();
colorAdjust.saturationProperty().bind(saturationSlider.valueProperty().divide(50).subtract(1));
GridPane.setConstraints(saturationSlider, 1, 0);
GridPane.setHgrow(saturationSlider, Priority.ALWAYS);
Label saturationValueLabel = LabelBuilder.create().minWidth(75).maxWidth(75).build();
saturationValueLabel.textProperty().bind(colorAdjust.saturationProperty().multiply(100).
asString("%.2f%%"));
GridPane.setConstraints(saturationValueLabel, 2, 0);
//
Label hueLabel = LabelBuilder.create().text("Hue").build();
GridPane.setConstraints(hueLabel, 0, 1);
Slider hueSlider = SliderBuilder.create().value(50).build();
colorAdjust.hueProperty().bind(hueSlider.valueProperty().divide(50).subtract(1));
GridPane.setConstraints(hueSlider, 1, 1);
GridPane.setHgrow(hueSlider, Priority.ALWAYS);
Label hueValueLabel = LabelBuilder.create().minWidth(75).maxWidth(75).build();
hueValueLabel.textProperty().bind(colorAdjust.hueProperty().multiply(100).asString("%.2f%%"));
GridPane.setConstraints(hueValueLabel, 2, 1);
//
Label brightnessLabel = LabelBuilder.create().text("Brightness").build();
GridPane.setConstraints(brightnessLabel, 0, 2);
Slider brightnessSlider = SliderBuilder.create().value(50).build();
colorAdjust.brightnessProperty().bind(brightnessSlider.valueProperty().divide(50).subtract(1));
GridPane.setConstraints(brightnessSlider, 1, 2);
GridPane.setHgrow(brightnessSlider, Priority.ALWAYS);
Label brightnessValueLabel = LabelBuilder.create().minWidth(75).maxWidth(75).build();
brightnessValueLabel.textProperty().bind(colorAdjust.brightnessProperty().multiply(100).
asString("%.2f%%"));
GridPane.setConstraints(brightnessValueLabel, 2, 2);
//
Label contrastLabel = LabelBuilder.create().text("Contrast").build();
GridPane.setConstraints(contrastLabel, 0, 3);
Slider contrastSlider = SliderBuilder.create().value(50).build();
colorAdjust.contrastProperty().bind(contrastSlider.valueProperty().divide(50).subtract(1));
GridPane.setConstraints(contrastSlider, 1, 3);
GridPane.setHgrow(contrastSlider, Priority.ALWAYS);
Label contrastValueLabel = LabelBuilder.create().minWidth(75).maxWidth(75).build();
contrastValueLabel.textProperty().bind(colorAdjust.contrastProperty().multiply(100).asString("%.2f%%"));
GridPane.setConstraints(contrastValueLabel, 2, 3);
//Validate Button
Button btnValider = new Button("Valider");
btnValider.setOnAction(new EventHandler<ActionEvent>() {
public void handle(ActionEvent event) {
imageProcessStage.hide();
ImageView imageView2 = new ImageView(imageViewImageProcess.getImage());
imageView.setImage(imageViewImageProcess.getImage());
}
});
GridPane.setConstraints(btnValider, 1, 4);
GridPane.setHgrow(btnValider, Priority.ALWAYS);
btnValider.setTranslateX(imageImageProcess.getWidth() / 12);
btnValider.setTranslateY(7);
//Validate Button
Button btnReset = new Button("Reset");
btnReset.setOnAction(new EventHandler<ActionEvent>() {
public void handle(ActionEvent event) {
ImageProcess ip = new ImageProcess();
ip.setImagePath(ImagePathImageProcess);
ip.start();
imageProcessStage.close();
}
});
GridPane.setConstraints(btnReset, 1, 4);
GridPane.setHgrow(btnReset, Priority.ALWAYS);
btnReset.setTranslateX(imageImageProcess.getWidth() / 12 + 82);
btnReset.setTranslateY(7);
//
GridPane sliderGrid = GridPaneBuilder.create().children(saturationLabel, saturationSlider, saturationValueLabel,
hueLabel, hueSlider, hueValueLabel,
brightnessLabel, brightnessSlider, brightnessValueLabel,
contrastLabel, contrastSlider, contrastValueLabel, btnValider, btnReset).build();
imageViewImageProcess.setFitWidth(imageImageProcess.getWidth() / 3);
imageViewImageProcess.setTranslateY(20);
//imageView.setFitHeight(image.getHeight()/2);
imageViewImageProcess.setPreserveRatio(true);
imageViewImageProcess.setSmooth(true);
imageViewImageProcess.setCache(true);
rootImageProcess = BorderPaneBuilder.create().center(imageViewImageProcess).top(sliderGrid).
build();
imageProcessStage.setTitle("Traitement d'image");
sceneImageProcess = new Scene(rootImageProcess);
sceneImageProcess.getStylesheets().add(ImageProcess.class.getResource("ImageProcess.css").
toExternalForm());
imageProcessStage.setScene(sceneImageProcess);
imageProcessStage.show();
}
});
You have...
ImageView imageView2 = new ImageView(imageViewImageProcess.getImage());
imageView.setImage(imageViewImageProcess.getImage());
That doesn't look useful

Resources