How to set backgroundImage from input file? - javascript

I hope to set background image from input local file.
But it occurs 'net::ERR_UNKNOWN_URL_SCHEME' error message.
My input tag:
<input
accept="image/*"
className="input_img"
type="file"
onChange={e => this.uploadImage(e)}
/>
My uploadImage function:
uploadImage = e => {
let node = document.getElementById("result");
node.style.backgroundImage = "url(" + e.target.result + ")";
};
How do I do it?

You could use a FileReader to read the data of the file, and then set the backgroundImage with the result.
Example
class App extends Component {
uploadImage = (e) => {
const { files } = e.target;
if (files.length === 0) {
return;
}
const file = files[0];
const fileReader = new FileReader();
fileReader.onload = () => {
this.background.style.backgroundImage = `url(${fileReader.result})`;
};
fileReader.readAsDataURL(file);
};
render() {
return (
<div>
<input
accept="image/*"
className="input_img"
type="file"
onChange={this.uploadImage}
/>
<div
style={{width: 200, height: 200}}
ref={ref => this.background = ref}
></div>
</div>
);
}
}

Related

How to set cropper width and height

I am trying to add an image cropper component to my project, for that using the react-cropper package. But there is a problem that how to add a fixed width and height for cropper box like "width:200px; height:300px;"
import React, { useState } from "react";
import Cropper from "react-cropper";
import "cropperjs/dist/cropper.css";
import "./Demo.css";
type Props = {
LabelName?: string;
};
export const Demo = (props:Props) => {
const {LabelName} = props;
const [image, setImage] = useState("");
const [cropData, setCropData] = useState("#");
const [cropper, setCropper] = useState<any>();
const onChange = (e: any) => {
e.preventDefault();
let files;
if (e.dataTransfer) {
files = e.dataTransfer.files;
} else if (e.target) {
files = e.target.files;
}
const reader = new FileReader();
reader.onload = () => {
setImage(reader.result as any);
};
reader.readAsDataURL(files[0]);
};
const getCropData = () => {
if (typeof cropper !== "undefined") {
setCropData(cropper.getCroppedCanvas().toDataURL());
}
};
return (
<div>
<div style={{ width: "100%" }}>
<input type="file" onChange={onChange} />
<br />
<Cropper
zoomTo={0.5}
initialAspectRatio={1}
preview=".img-preview"
src={image}
viewMode={1}
minCropBoxHeight={10}
minCropBoxWidth={10}
background={false}
responsive={true}
autoCropArea={1}
checkOrientation={false}
onInitialized={(instance) => {
setCropper(instance);
}}
guides={true}
/>
</div>
<br style={{ clear: "both" }} />
</div>
);
};
export default Demo;
Now I can change like this,
But my requirement is to fix that copper size, Please give me a solution to fix this situation.
Size:
minCropBoxWidth: 200,
minCropBoxHeight: 300,
Required aspect ratio:
aspectRatio: 1 / 1.5,
Block change cropBox:
cropBoxResizable: false,

How to Read mutliple images with FileReader

I Wanna Select Multiple Image from one input And Read It With File Reader , and if i leave it like this, it give me one picutre
const [image , setImage] = useState('');
const [imageSelected , setImageSelected] = useState(null);
const onImageChange = event => {
const reader = new FileReader();
reader.onload = () => {
if(reader.readyState === 2){
setImageSelected(reader.result)
console.log(reader.result)
}
}
setImage(event.target.files[0]);
reader.readAsDataURL(event.target.files[0])
console.log(image)
}
HTML
<label htmlFor="image" className = "col-span-3 ">
{
!imageSelected ? <PhotoCameraIcon fontSize="120" className ="border rounded p-2 h-24 text-8xl text-gray-600 cursor-pointer" /> : (
<img src={imageSelected} alt="" className = "h-44" />
)
}
<input hidden multiple onChange={onImageChange} type="file" name="image" id="image" />
</label>
import "./styles.css";
import React, {Component} from 'react';
export default class App extends Component {
constructor (props){
super(props);
this.state={
images: null
}
}
readFileContents = async (file) => {
return new Promise((resolve, reject) => {
let fileReader = new FileReader();
fileReader.onload = () => {
resolve(fileReader.result);
};
fileReader.onerror = reject;
fileReader.readAsDataURL(file);
});
}
readAllFiles = async (AllFiles) => {
const results = await Promise.all(AllFiles.map(async (file) => {
const fileContents = await this.readFileContents(file);
return fileContents;
//let a = URL.createObjectURL(fileContents);
//return a;
}));
console.log(results, 'resutls');
return results;
}
handleUpload = (e) => {
let AllFiles = [];
[...e.target.files].map(file => AllFiles.push(file));
this.readAllFiles(AllFiles).then(result => {
let allFileContents = [];
result.map(res =>{
allFileContents.push(res);
})
this.setState({images: allFileContents});
}).catch(err => {
alert(err);
});
}
render = () => {
return (<div>
<input type="file" multiple onChange={(e) => this.handleUpload(e)}/>
{this.state.images && this.state.images.map((img, idx)=>{
return <img width={100} height={50} src={img} alt={idx} key={idx} />
})
}
</div>
)
}
}

How to save the value of a variable converted to base64?

I am using a .zip file with thousands of geographical coordinates and converting to base64.
I can convert the file to base64, the problem is to save the result of this variable for later use.
I'm trying to use setState to save the variable's value but nothing happens.
Can you tell me what I'm doing wrong?
Here's my code I put in codesandbox
And here the zilFile I'm converting
const [zipFile, setZipFile] = useState("");
const [base64, setBase64] = useState("");
const getBase64 = (file, cb) => {
let reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = function () {
cb(reader.result);
};
reader.onerror = function (error) {};
};
const toBase64 = async () => {
let auxZip = "";
await getBase64(zipFile, (result) => {
auxZip = result.substring(28);
console.log("auxZip: ", auxZip);
setBase64(auxZip);
});
};
const onSave = () => {
toBase64();
console.log("base64: ", base64);
};
const handleZipChangle = (event) => {
const file = event.target.files[0];
setZipFile(file);
};
I have fixed like this, it worked perfectly, please take a look.
import React, { useState } from "react";
import "./styles.css";
import FormControl from "#material-ui/core/FormControl";
import Typography from "#material-ui/core/Typography";
export default function App() {
const [base64, setBase64] = useState("");
const getBase64 = (file, cb) => {
let reader = new FileReader();
reader.readAsDataURL(file);
reader.onloadend = (e) => {
cb(e.target.result);
};
reader.onerror = function (error) {};
};
const onSave = () => {
console.log("base64: ", base64);
};
const handleZipChangle = (event) => {
const file = event.target.files[0];
let auxZip = "";
getBase64(file, (result) => {
auxZip = result.substring(28);
setBase64(auxZip);
});
};
return (
<div className="App">
<FormControl>
<Typography>Select Zip File:</Typography>
<input
accept="zip/*"
type="file"
id="contained-button-file"
onChange={handleZipChangle}
/>
</FormControl>
<div style={{ marginTop: "30px" }}>
<button onClick={onSave}>SAVE</button>
</div>
</div>
);
}
or if you want to use zip file, you can use useEffect to check the state loaded and call getBase64
useEffect(() => {
let auxZip = "";
zipFile &&
getBase64(zipFile, (result) => {
auxZip = result.substring(28);
setBase64(auxZip);
});
}, [zipFile]);
const onSave = () => {
console.log("base64: ", base64);
};
const handleZipChangle = (event) => {
const file = event.target.files[0];
setZipFile(file);
};
Your auxZip has been set. Cause function toBase64 is async, the auxZip is empty.
You can check by:
const toBase64 = async () => {
let auxZip = "";
getBase64(zipFile, (result) => {
auxZip = result.substring(28);
// console.log("auxZip: ", auxZip);
setBase64(auxZip);
});
};
console.log(base64);
const onSave = async () => {
await toBase64();
console.log("base64: ", base64);
};

crop image in reactjs using html5 canvas

I am trying to crop an image in reactjs without using any library.First the user will upload image and the user will crop the image using raw js and replace the uploaded image.How can i do it without using any library.I want to use the crop component somthing like this in reactjsreference.For me html cansvas seems to be not working how can i do it using html canvas?this is the sandbox link:sandbox
this is the code i did for showing image:
import React, { Component } from "react";
class ReactCrop extends Component {
constructor(props) {
super(props);
this.state = {
file: null,
};
this.handleChange = this.handleChange.bind(this)
}
handleChange(event) {
this.setState({
file: URL.createObjectURL(event.target.files[0])
})
console.log("ok",this.state.file)
}
saveCroped() {
const width = 500;
const height = 300;
const fileName = e.target.files[0].name;
const reader = new FileReader();
reader.readAsDataURL(e.target.files[0]);
reader.onload = event => {
const img = new Image();
img.src = event.target.result;
img.onload = () => {
const elem = document.createElement('canvas');
elem.width = width;
elem.height = height;
const ctx = elem.getContext('2d');
// img.width and img.height will contain the original dimensions
ctx.drawImage(img, 0, 0, width, height);
ctx.canvas.toBlob((blob) => {
const file = new File([blob], fileName, {
type: 'image/jpeg',
lastModified: Date.now()
});
}, 'image/jpeg', 1);
},
reader.onerror = error => console.log(error);
};
}
componentDidMount() {
console.log('componentDidMount colling ...');
}
render() {
return (
<div className="app">
<div style={{width:'450px', margin:'0 auto'}}>
<label htmlFor="file" style={{paddingRight:'80px',marginLeft:'-10px'}}>
<input id="files" type="file" style={{border:'0px',paddingBottom:'12px'}} key={this.state.inputKey}
onChange={this.handleChange} type="file"/>
</label>
{this.state.file === null?
<p></p>
: <img style={{width:'362px',height:'365px',paddingTop:'10px',marginRight:'85px'}} onClick={this.rotate} src={this.state.file}/>
}
</div>
<button type="button" onClick={() => {this.saveCroped()}}>crop</button>
</div>
);
}
}
export default ReactCrop;
Interesting question. Here is a working example: (it wont download in online sandbox, but works fine on independent branches e.g. localhost, see console messages) sandbox
import React, { useRef, useEffect, useState } from "react";
const Crop = function(){
const canvas = useRef();
const file = useRef();
const preview = useRef();
const [imageParams, setImageParams] = useState();
const [context, setContext] = useState();
// Initialize
useEffect(function(){
file.current.onchange = onNewImage;
setContext( canvas.current.getContext('2d') );
},[])
// Draw image on imageParams Change
useEffect(function(){
if(!imageParams) return;
context.drawImage( preview.current, 0, 0, imageParams.width*(700/imageParams.height), 700 )
}, [imageParams])
// Get with and height, replace preview, set params
function onNewImage(){
const newImgUrl = URL.createObjectURL( file.current.files[0] );
const newImage = document.createElement('img');
newImage.setAttribute('src', newImgUrl);
newImage.onload = function(){
const {width, height} = newImage;
const type = file.current.files[0].type
newImage.setAttribute('width', '50px');
preview.current.parentElement.append(newImage);
preview.current.remove();
preview.current = newImage;
setImageParams({ width, height, type });
}
}
// Save image on click
function handleSave(){
canvas.current.toBlob(function(blob){
const anchor = document.createElement('a');
anchor.innerHTML = 'download';
anchor.download = "my_file."+imageParams.type.replace(/^.{1,}\//,'');
anchor.href = (window.webkitURL || window.URL).createObjectURL(blob);
anchor.dataset.downloadurl = [imageParams.type, anchor.download, anchor.href].join(':');
anchor.click();
preview.current.parentElement.append(anchor);
}, imageParams.type);
}
return <>
<div className="input">
<input
ref={file}
type="file"
accept="image/png, image/jpeg" />
<div
style={{width:"100px", display: 'inline-block'}}>
<img
ref={preview}
/>
</div>
<button
onClick={handleSave} >save image</button>
</div>
<div class="canvas">
<canvas
ref={canvas}
width='700px'
height='700px' />
</div>
</>;
}
export default Crop;

The FilePond onupdatefiles method is called two times, how can I prevent this?

FilePond onupdatefiles method is called two times.
As seen in the photo, two of the same file is selected. How can I prevent this?
React code
<Form className='orange-color ml-2'>
<FilePond
ref={ref => (ref)}
allowFileEncode={true}
allowMultiple={false}
oninit={() =>
console.log("FilePond "+formKey.toString()+" has initialised")
}
onupdatefiles={(fileItems) => {
const file = fileItems.map(fileItem => fileItem.file)
if (file[0]) {
const reader = new FileReader();
reader.readAsDataURL(file[0]);
reader.onload = (event) => {
const convertedResult = event.target.result
if (convertedResult) {
const regex = '(.*)(base64,)(.*)';
const matches = convertedResult.match(regex);
const val = matches[3];
changeSelected(val)
}
};
}
}
}
/>

Categories