I have this small issue
I am using Ant Design and its components
https://ant.design/components/upload/
I am trying to upload images, and it all works fine, But i need to add a validation to verify if the file is correct. That is if a user renames any other file to a .jpg or .png extension, i need to validate that and show them an alert.
How can i achieve that, Currently we convert the image in base64 using FileReader
You can create a function and return something like this.
const verifyImage = (img) => {
return new Promise((resolve, reject) => {
const reader = new FileReader()
reader.addEventListener('load', event => {
let picFile = event.target
let imgNew = new Image()
imgNew.addEventListener('load', () => {
resolve(reader.result)
})
imgNew.addEventListener('error', () => {
reject()
})
imgNew.src = picFile.result
})
reader.readAsDataURL(img)
})
}
Related
i 'm getting some Kml's from server (by axios) and loading them on map:
// functional Component KmlManager ->
const map = useMap()
const addTrackAndBoundsFromKml = kmltext => {
const parser = new DOMParser();
var kml = parser.parseFromString(kmltext,"text/xml");
const track = new L.KML(kml);
map.addLayer(track);
};
React.useEffect(() => {
axios.get('url')
.then( res => {
const allLayouts = res.data
allLayouts.forEach(element => {addTrackAndBoundsFromKml(element.kml)})
})
})
code above is using This approach
it is working fine and loading Kml's. but now I want to add click listener and popup to each Kml Layout.
i tried this for popup but no luck:
const track = new L.KML(kml).bindPupop("text of the popup");
could not figured out how to add onclick.
it it possible with this approach? Thanks!
It returns a pdf with the API request and I save this pdf to the src/pdfs location with the name 'label.pdf' and when I open this pdf file, it opens it with a hash code. I have no idea how to prevent this.
My Component:
const getLabels = useSelector(state => state.getLabel)
const {time,loading:loadingLabel,success:successLabel} = getLabels
useEffect(() => {
if(successLabel === true && loadingLabel === false){
window.open(require('../pdfs/label'+time+'.pdf') ,"_blank")
dispatch({type:LABEL_GET_RESET})
}
},[dispatch,navigate,successLabel,time,loadingLabel])
I have an upload button like this. I want to show preview of uploaded Image on a div. Hence, I want the previewImage. This is how i'm trying to achieve it but onPreview is not getting fired at all.
It's a functional component. Sandbox=> https://codesandbox.io/s/silly-breeze-2gvewe
function AddAttachment(props) {
const getBase64 = (file)=>{
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = () => resolve(reader.result);
reader.onerror = error => reject(error);
});
}
const onChange = ({ fileList: newFileList }) => {
setFileList(()=>(newFileList));
console.log(fileList);
};
const handlePreviewImage = async (file)=>{
if (!file.url && !file.preview) {
file.preview = await getBase64(file.originFileObj);
}
setBase64({
previewImage: file.url || file.preview,
previewVisible: true,
previewTitle: file.name || file.url.substring(file.url.lastIndexOf('/') + 1),
});
}
return (
<UploadButton
fileList={fileList}
onPreview ={handlePreviewImage}
onChange={onChange}
aspect={2} listType="picture" />
)
}
From the docs:
onPreview
A callback function, will be executed when file link or preview icon is clicked.
When you try clicking on the preview image or link, you should see handlePreviewImage get called.
I am want to save image as base64 to aws s3 bucket. There is a lambda that will decoder the base64.
These are my current states for the images. One is for selected file that is the image and the one is for the image that is seen as preview on the page.
const [selectedFile, setSelectedFile] = useState('')
const [preview, setPreview] = useState()
Then I have useEffect function for selecting the file and also sets the object URL as the preview image.
useEffect(() => {
if (!selectedFile) {
setPreview(undefined)
return
}
const objectURL = window.URL.createObjectURL(selectedFile)
setPreview(objectURL)
return () => window.URL.revokeObjectURL(objectURL)
}, [selectedFile])
const selectFile = (event) => {
setSelectedFile(event.target.files[0])
}
And this is the input component where the onChange function is called.
<Input
style={input}
type='file'
accept='.jpg, .png|image/*'
id='image'
name='Upload image'
onChange={selectFile}
/>
Is there a better way to handle the base64 conversion?
I managed to solve this by relatively short lines of code. I take the selectedFile from the state and then convert it to base64. I tested it with the separate button and I got base64 image in the console.
const convertToBase64 = () => {
const reader = new FileReader()
reader.readAsDataURL(selectedFile)
reader.onload = () => {
console.log('called: ', reader)
setBase64IMG(reader.result)
}
}
I am developing a course platform using ReactJS. When the user finishes a course he can download the PDF file.
I need a version of the same file as an image (png or jpg), but I haven't found any way to do that. Can someone help me?
To generate the PDF certificate I'm using the lib: React-PDF.
This is my code to generate pdf file:
<PDFDownloadLink
document={
<Certificate course={course} name={name} date={today()} />
}
fileName="somename.pdf"
>
{({ blob, url, loading, error }) => {
return loading ? 'Loading document...' : 'Download now!';
}}
</PDFDownloadLink>
I created a helper function: convertPdfToImages which takes in the pdf file and returns an array of images encoded in base64, using the pdfjs package.
npm install pdfjs-dist -S
const PDFJS = require("pdfjs-dist/webpack");
const readFileData = (file) => {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onload = (e) => {
resolve(e.target.result);
};
reader.onerror = (err) => {
reject(err);
};
reader.readAsDataURL(file);
});
};
//param: file -> the input file (e.g. event.target.files[0])
//return: images -> an array of images encoded in base64
const convertPdfToImages = async (file) => {
const images = [];
const data = await readFileData(file);
const pdf = await PDFJS.getDocument(data).promise;
const canvas = document.createElement("canvas");
for (let i = 0; i < pdf.numPages; i++) {
const page = await pdf.getPage(i + 1);
const viewport = page.getViewport({ scale: 1 });
const context = canvas.getContext("2d");
canvas.height = viewport.height;
canvas.width = viewport.width;
await page.render({ canvasContext: context, viewport: viewport }).promise;
images.append(canvas.toDataURL());
}
canvas.remove();
return images;
}
Please use this library
https://www.npmjs.com/package/react-pdf-to-image
It is pretty straight forward. It will return the list of images (each page in the pdf as one image)
import React from 'react';
import {PDFtoIMG} from 'react-pdf-to-image';
import file from './pdf-sample.pdf';
const App = () =>
<div>
<PDFtoIMG file={file}>
{({pages}) => {
if (!pages.length) return 'Loading...';
return pages.map((page, index)=>
<img key={index} src={page}/>
);
}}
</PDFtoIMG>
</div>
export default App;
if you want to just download the each pdf page as image instead of component please follow below code
import PDFJS from 'pdfjs-dist/webpack';
this is the dependency library for react-pdf-to-image. Then read the pdf file(I'm giving base64 as input)
PDFJS.getDocument(blob).promise.then(pdf => {
const pages = [];
this.pdf = pdf;
for (let i = 0; i < this.pdf.numPages; i++) {
this.getPage(i + 1).then(result => {
// the result is the base 64 version of image
});
}
})
after reading each page, read each page as image from getPage method as below
getPage = (num) => {
return new Promise((resolve, reject) => {
this.pdf.getPage(num).then(page => {
const scale = "1.5";
const viewport = page.getViewport({
scale: scale
});
const canvas = document.createElement('canvas');
const canvasContext = canvas.getContext('2d');
canvas.height = viewport.height || viewport.viewBox[3]; /* viewport.height is NaN */
canvas.width = viewport.width || viewport.viewBox[2]; /* viewport.width is also NaN */
page.render({
canvasContext, viewport
}).promise.then((res) => {
resolve(canvas.toDataURL());
})
})
})
}