Convert image to byte array without using SwingFXUtils - javafx

In the answer of the question getPublicStorage(“Pictures”) lists no files we have tried solution 1 and 2 but in the byte array process seems the array does not represent the actual image.
Used code:
Services.get(PicturesService.class).ifPresent(service -> {
            service.takePhoto(false).ifPresent(image -> {
                imageView.setImage(image);
 
                PixelReader pixelReader = image.getPixelReader();
                int width = (int) image.getWidth();
                int height = (int) image.getHeight();
                byte[] buffer = new byte[width * height * 4];
                pixelReader.getPixels(0, 0, width, height, PixelFormat.getByteBgraInstance(), buffer, 0, width * 4);
 
                //Test
                ByteArrayInputStream in = new ByteArrayInputStream(buffer);
                Image image2 = new Image(in);
 
                try {
                    in.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
 
                imageView.setImage(image2);
                //Test
 
                proceedImage(buffer);
            });
        });
 
private void proceedImage(byte[] arrayImage) {
        this.arrayImage = arrayImage;
 
        enableZoom(true);
 
        apply = true;
    }
Exception:
W/System.err(15096): com.sun.javafx.iio.ImageStorageException: No loader for image data
W/System.err(15096):    at com.sun.javafx.iio.ImageStorage.loadAll(ImageStorage.java:276)
W/System.err(15096):    at com.sun.javafx.tk.quantum.PrismImageLoader2.loadAll(PrismImageLoader2.java:142)
W/System.err(15096):    at com.sun.javafx.tk.quantum.PrismImageLoader2.<init>(PrismImageLoader2.java:77)
W/System.err(15096):    at com.sun.javafx.tk.quantum.QuantumToolkit.loadImage(QuantumToolkit.java:740)
W/System.err(15096):    at javafx.scene.image.Image.loadImage(Image.java:1073)
W/System.err(15096):    at javafx.scene.image.Image.initialize(Image.java:804)
W/System.err(15096):    at javafx.scene.image.Image.<init>(Image.java:707)
W/System.err(15096):    at org.openjanela.dialog.ImageViewDialog.lambda$null$5(ImageViewDialog.java:260)
Any idea for a fix \ tweak \ workaround would be much appreciated.

Related

order matters in styles components

I noted that the styled-Component/Wrapper approach below can go wrong as a Child component CSS may be overridden by its parent. I came up with a simplified sample below:
This is the Parent component and its Styled-Component Wrapper:
 import styled from "styled-components";
const Child = () => {
  return (
    <ChildWrapper>
      <div className="nice-box" />
    </ChildWrapper>
  );
};
const Parent = () => {
  return (
    <ParentWrapper>
      <div className="nice-box" />
      <Child />
    </ParentWrapper>
  );
};
const ChildWrapper = styled.div`
  .nice-box {
    border: 3px solid green;
    height: 100px;
    width: 100px;
  }
`;
const ParentWrapper = styled.div`
  .nice-box {
    border: 3px solid black;
    height: 50px;
    width: 50px;
  }
`;
export default Parent;
BUT if you put "ChildWrapper" after "ParentWrapper" it works and the child will have its own
style!
How to prevent the parent's style to be used for the child?
To achieve expected result, add &&&(to get higher specificity) to the nice-box class of ChildWrapper to avoid overwrite
const ChildWrapper = styled.div`
&&& .nice-box {
border: 3px solid green;
height: 100px;
width: 100px;
}
`;
Sample working code for reference - https://codesandbox.io/s/kind-blackwell-gk6tfx?file=/src/Child.js
Reference link for more details from official documentation - https://styled-components.com/docs/faqs#how-can-i-override-styles-with-higher-specificity

React: how to make an input only as wide as the amount of text provided?

Simple enough question:
I am trying to create inputs that are as large as the text supplied to them.
Sandbox: https://codesandbox.io/s/long-snowflake-6u13n?file=/src/Test.jsx
My design intention is to generate inputs dynamically and then allow the user to have styles specific to each input that visually help break up each sentence based on outside events. But before I can move forward, it's really important that my input container is only as large as the text within.
why not use a textarea? -- I have data that is particular to each sentence that I want to create unique styles for.
Any thoughts?
Here is an approach from plain HTML/CSS and a working snippet , hidding the value typed inside a span behind the input set in an absolute position. CSS can make both span and input matching the same lenght/width. Stretching/collapsing a parent (label) will finish the job.
In the courtesy of #silvenon you may also find a react sample below the snippet
var val = document.querySelector('#test');
let tpl = document.querySelector('#tpl');
let text = val.value;
tpl.textContent= text;
val.addEventListener("input", function () {// onchange ...
let text= val.value;
//console.log(text);
tpl.textContent= text;
});
label {
display: inline-block;
position: relative;
min-width: 2em;
min-height: 1.4em;
}
#tpl {
white-space: pre;
/* max-width : could be wised to set a maximum width and overflow:hidden; */
}
#test {
font-family: inherit;
font-size: inherit;
position: absolute;
vertical-align: top;
top: 0;
left: 0;
width: 100%;
background: white;
}
<label><span id="tpl"></span><input id='test' value="Some test to try" ></label>
In the courtesy of #silvenon, you may find a react sample of that code.
const SentenceInput = styled.input`
padding: 0;
margin: 0;
border: none;
border: 1px solid black;
/* added styles */
font-family: inherit;
font-size: inherit;
position: absolute;
vertical-align: top;
top: 0;
left: 0;
width: 100%;
background: white;
`
const Label = styled.label`
display: inline-block;
position: relative;
min-width: 2em;
min-height: 1.4em;
`
const Template = styled.span`
white-space: pre;
/* max-width : could be wised to set a maximum width and overflow:hidden; */
`
const Sentence = ({ initialValue }) => {
const [value, setValue] = React.useState(initialValue)
return (
<Label>
<Template>{value}</Template>
<SentenceInput
type="text"
value={value}
onChange={(event) => {
setValue(event.target.value)
}}
/>
</Label>
)
}
Using ch unit would work if the typeface was monospace, otherwise character width varies. I would approach this problem by rendering an inline element holding the same text, measuring it and hiding it instantly every time the input field value changes.
To do this it's best to create a separate component for rendering sentences, let's call it Sentence:
const Test = () => {
return (
<div className="App">
{value.map(({ sentence }, i) => {
return (
<Sentence
initialValue={sentence}
key={i}
/>
);
})}
</div>
);
};
Test would pass the initial value, then Sentence will continue maintaining its own state:
const Sentence = ({ initialValue }) => {
const [value, setValue] = React.useState(initialValue)
return (
<SentenceInput
type="text"
value={value}
onChange={(event) => {
setValue(event.target.value)
}}
/>
)
}
Next, I'd add a span element that will serve as a measurer element, where the text should be styled the same way as in input elements, so the measurements turn out accurate. In your example in Chrome that would mean setting the font size to 13.3333px.
Now for the trickiest part, we need to combine useEffect and useLayoutEffect; useEffect will make the measurer visible, then useLayoutEffect will measure it and hide it
This is the result:
const Sentence = ({ initialValue }) => {
const [value, setValue] = React.useState(initialValue)
const [visible, setVisible] = React.useState(false)
const [width, setWidth] = React.useState('auto')
const measurer = React.useRef(null)
React.useEffect(() => {
setVisible(true)
}, [value])
React.useLayoutEffect(() => {
if (visible) {
const rect = measurer.current.getBoundingClientRect()
setWidth(rect.width)
setVisible(false)
}
}, [visible])
return (
<>
<span
ref={measurer}
style={{ fontSize: '13.3333px' }}
>
{visible && value}
</span>
<SentenceInput
type="text"
value={value}
style={{ width: width + 1 }}
onChange={(event) => {
setValue(event.target.value)
}}
/>
</>
)
}
I added 1px to the computed width because it seems to remove a small horizontal scroll in the input fields.
This is for you to tweak further the way you want, for example how it should behave when it reaches the viewport width.
The <input> size attribute can be used to set the width. It works in the same way as ch units e.g. <input size="10"> has a width of 10ch. As with ch units, it works perfectly with monospaced fonts but is only an approximation when it comes to proportionally-spaced fonts.
To get a more accurate measurement with proportionally-spaced fonts, you can use the scrollWidth property of the <input> element itself to calculate the width. The trick is to set the value to 'auto' first to capture the content width before setting the value. Set the input padding to zero if you want to fit the content exactly.
import React, { useEffect, useRef } from "react";
const data = [
  { sentence: "Hello world, how are you?" },
  { sentence: "Sometimes in rains in the summer." },
  {
    sentence:
      "Depending where you currently live, it my even rain in the winter."
  }
];
const SentenceInput = (props) => {
  const { value, onChange } = props;
  const inputRef = useRef(null);
  useEffect(() => {
    const input = inputRef.current;
    input.style.width = 'auto';
    input.style.width = `${input.scrollWidth}px`;
  });
  return <input ref={inputRef} type="text" value={value} onChange={onChange} />;
};
const Test = () => {
  const handleChange = () => {};
  return (
    <div className="App">
      {data.map(({ sentence }, i) => {
        return (
          <SentenceInput key={i} value={sentence} onChange={handleChange} />
        );
      })}
    </div>
  );
};
export default Test;

react-transition-group CSSTransition slide in on render

I'm trying to have a component conditionally render in React and slide it when it does render
packages:
"react": "^16.8.6",
"react-transition-group": "^4.0.1",
code snippet:
{ expanded && (
<CSSTransition in={expanded} timeout={500} classNames="slide">
<div className="expandedDiv"></div>
</CSSTransition>
)}
css:
.slide-enter {
transform: translateX(-100%);
transition: .3s linear;
}
.slide-enter-active {
transform: translateX(0%);
}
.slide-exit {
transform: translateX(0%);
transition: .3s linear;
}
.slide-exit-active {
transform: translateX(-100%);
}
structure:
+------------------------------+
| | | header |
| | |____________+
| | | content |
| | | |
| | | |
| nav | expanded | |
| | | |
| | | |
| | | |
+------------------------------+
Expanded should slide in on true, and slide out on false, it is expandedDiv from the code snippet
The div just pops in with no animation. Expected behaviour is a linear transition from left to right
Thanks
I need to see a little bit more of your code to understand exactly what you're trying to do. But if I got it right, try doing it like this:
<CSSTransition
in={expanded}
appear={true}
key = {this.props.location.key}
timeout={500}
classNames="slide">
<div className='expandedDiv'> </div>
</CSSTransition>
<CSSTransition
in={expanded}
timeout={300}
classNames="slide"
unmountOnExit
onEnter={() => this.toggleExpanded(true)}
onExited={() => this.toggleExpanded(false)}
>
<div className="expandedDiv">
</div>
</CSSTransition>
</div>

HTML5 canvas element not inheriting width and height of parent? WHY?

canvas1 and canvas2 not inheriting the parent width and height from css like I was expecting. I can fix this by assigning canvas1 and canvas2 width and height explicitly with javascript, but I was hoping for a less hackish way to solve this, i.e. pure css.
`
<!DOCTYPE HTML>
<html>
<head>
<style>
#parent {
width: 1000px;
height: 600px;
}
#div1 {
position: absolute;
z-index:0;
}
#div2 {
position: absolute;
z-index:1;
}
</style>
</head>
<body>
<div id="parent">
<div id="div1">
<canvas id="canvas1">
</canvas>
</div>
<div id="div2">
<canvas id="canvas2">
</canvas>
</div>
</div>
<script>
var parent = document.getElementById("parent");
var parentWidth = parent.offsetWidth;
var parentHeight = parent.offsetHeight;
alert("parentWidth = " + parentWidth);
alert("parentHeight = " + parentHeight);
var div1 = document.getElementById("div1");
var div1Width = div1.offsetWidth;
var div1Height = div1.offsetHeight;
alert("div1Width = " + div1Width);
alert("div1Height = " + div1Height);
var canvas1 = document.getElementById("canvas1");
var canvas1Width = canvas1.offsetWidth;
var canvas1Height = canvas1.offsetHeight;
alert("canvas1Width = " + canvas1Width);
alert("canvas1Height = " + canvas1Height);
var div2 = document.getElementById("div2");
var div2Width = div2.offsetWidth;
var div2Height = div2.offsetHeight;
alert("div2Width = " + div2Width);
alert("div2Height = " + div2Height);
var canvas2 = document.getElementById("canvas2");
var canvas2Width = canvas2.offsetWidth;
var canvas2Height = canvas2.offsetHeight;
alert("canvas2Width = " + canvas2Width);
alert("canvas2Height = " + canvas2Height);
</script>
</body>
</html> `

How I can pause all video when I play a video youtube in page

I using iframe API Youtube for embbed a lot of video on my site. I want to pause all videos in a page when I click play a video. This is my code,it's works but it's look like complex. How make it simply.
<doctype html>
<html>
<head>
<title>Multiple YouTube Players</title>
<script src="http://code.jquery.com/jquery-1.10.1.min.js"></script>
</head>
<body>
<iframe id='player1' width="400" height="225" src="http://www.youtube.com/embed/H0GxG24qpYQ?enablejsapi=1" frameborder="0" allowfullscreen></iframe>
<iframe id='player2' width="400" height="225" src="http://www.youtube.com/embed/Dl_-iGvqZWA?enablejsapi=1" frameborder="0" allowfullscreen></iframe>
<iframe id='player3' width="400" height="225" src="http://www.youtube.com/embed/Dl_-iGvqZWA?enablejsapi=1" frameborder="0" allowfullscreen></iframe>
<iframe id='player4' width="400" height="225" src="http://www.youtube.com/embed/H0GxG24qpYQ?enablejsapi=1" frameborder="0" allowfullscreen></iframe>
<iframe id='player5' width="400" height="225" src="http://www.youtube.com/embed/Dl_-iGvqZWA?enablejsapi=1" frameborder="0" allowfullscreen></iframe>
<script type='text/javascript'>
function onYouTubeIframeAPIReady() {
player1 = new YT.Player('player1', {
events: {
'onStateChange': function(e) { if(e.data == YT.PlayerState.PLAYING) {player2.stopVideo();player3.stopVideo();player4.stopVideo();player5.stopVideo();} }
}
});
player2 = new YT.Player('player2', {
events: {
'onStateChange': function(e) { if(e.data == YT.PlayerState.PLAYING) {player1.stopVideo();player3.stopVideo();player4.stopVideo();player5.stopVideo();} }
}
});
player3 = new YT.Player('player3', {
events: {
'onStateChange': function(e) { if(e.data == YT.PlayerState.PLAYING) {player2.stopVideo();player1.stopVideo();player4.stopVideo();player5.stopVideo();} }
}
});
player4 = new YT.Player('player4', {
events: {
'onStateChange': function(e) { if(e.data == YT.PlayerState.PLAYING) {player2.stopVideo();player3.stopVideo();player1.stopVideo();player5.stopVideo();} }
}
});
player5 = new YT.Player('player5', {
events: {
'onStateChange': function(e) { if(e.data == YT.PlayerState.PLAYING){player2.stopVideo();player3.stopVideo();player4.stopVideo();player1.stopVideo();} }
}
});
}
</script>
<script type='text/javascript' src='https://www.youtube.com/iframe_api'></script></body>
</html>

Resources