Convert blob url to file or Base64 to upload to cloudinary - reactjs

I have converted the file to blob url by creating a canvas,
Now I want to convert blob url to either file type or base64 type to upload to cloudinary.
But it seems very challenging to me, as none of them are working.
The below code is to convert the images to the blob url, acutally I am square cropping them
CanvasUtils.js
export async function getCroppedImg(
imageSrc,
pixelCrop,
...
) {
...
return new Promise((resolve) => {
canvas.toBlob((file) => {
resolve(URL.createObjectURL(file));
}, "image/png");
});
My try's:
Converting blob url to blob oject and then to file format
for (let i = 0; i < imageUrls.length; i++) {
console.log("This is from within the loop: imageURL", imageUrls[i]);
let blob = new Blob([imageUrls[i]], { type: "image/jpg" });
console.log("Blob is ", blob);
var myFile = blobToFile(blob, "myimage.jpg");
// uploading code goes here [find the code below]
}
Converting blob url to blob oject and then to base64
let reader = new FileReader();
reader.readAsDataURL(blob); // converts the blob to base64 and calls onload
reader.onloadend = async function () {
let myFile = reader.result; // data url
// uploading code goes here [find the code below]
}
The uploading code to save it in cloudinary goes like.
console.log(typeof myFile);
data.append("file", myFile);
data.append("upload_preset", "myPreset");
const res = await fetch(
"https://api.cloudinary.com/v1_1/dpurb6xes/image/upload",
{
method: "Post",
body: data,
}
);
const response = await res.json();
console.log(response.secure_url);
Output for try 1 goes like:
Output for try 2 goes like:
What is the good request then ??

In both the cases you are actually converting the imageUrl into blob.
For some reason it doesn't work.
Instead converting the imageUrl directly to the blob worked for me.
The code goes like:
const getBase64FromUrl = async (url) => {
const data = await fetch(url);
const blob = await data.blob();
return new Promise((resolve) => {
const reader = new FileReader();
reader.readAsDataURL(blob);
reader.onloadend = () => {
const base64data = reader.result;
resolve(base64data)
};
});
};
And then use the function like this.
const myImage = await getBase64FromUrl(imageUrls[i]);

Related

React FileReader readAsDataURL not working: URL can't be decoded in flask backend as format == None

I'm working on a basic React web app where user can upload images, and images are send to the flask backend to be processed. I'm using FileReader class to convert the uploaded images through into URLs, and then send them to the backend, where I need to decode the URLs then converted it into an np.array for the processing.
The issue is, when I try to decode the image with image_data = base64.b64decode(image_url) and get the image with Image.open(io.BytesIO(image_data)), somehow it won't recognize the url as an image? Basically I got this error:
raise UnidentifiedImageError(
PIL.UnidentifiedImageError: cannot identify image file <_io.BytesIO object at 0x2e8950b30>
I checked the image format with image_format = imghdr.what(io.BytesIO(image_data)), and the image_format equals to None. Do I need to specify the format when encoding the image?
Here's my code:
in React App():
handleImageUploadSelect = (event) => {
let imageURLs = [];
const files = event.target.files;
for ( let i = 0; i < files.length; i++ ) {
// load file object
const file = files[i]
// file reader
const reader = new FileReader();
reader.onload = (event) => {
const dataURL = event.target.result;
// add dataURL to the state variable
imageURLs[i] = dataURL;
}
reader.readAsDataURL(file);
}
this.state.uploadImageURLs = imageURLs;
}
handleImageUpload = event => {
event.preventDefault();
// send uploadImageURLs back to flask server
const data = { images: this.state.uploadImageURLs };
console.log(data)
fetch('http://127.0.0.1:5000/add_images', {
method:'POST',
body: JSON.stringify(data),
headers: {
'Content-Type': 'application/json'
},
})
.then((response) => response.json())
.then((data) => {
// response data
console.log(data)
})
.catch((error) => {
console.error(error);
});
}
And in flask server file:
#main.route('/add_images', methods=['POST'])
#cross_origin()
def add_images():
data = request.get_json()
for imageURL in data['images']:
image_data = base64.b64decode(imageURL)
image = Image.open(io.BytesIO(image_data))
image_array = np.array(image)
# processing ...
return jsonify({"condition": "image received"})
Please Help! Thanks!

Can we render InputStream from Spring Boot Backend on React Frontend?

I have a virtual file system in my java spring boot backend that converts any file into an InputStream, I am sending this InputStream using REST to my React frontend. Is there anyway I can accordingly render this InputStream on the frontend?
This InputStream may be an text file, image file, xml file, etc.
Sure. I've an example using axios.
const readFile = async (filename: string) => {
try {
// fetch your file
const response = await axios.get(`/api/file/${filename}`, {
responseType: "arraybuffer",
});
// read your response into a blob
const file = new Blob([response.data], {
type: "text/plain",
});
// read your blob as text
const reader = new FileReader();
reader.onload = () => {
alert(reader.result);
};
reader.readAsText(file);
} catch (e) {
// error handling
console.error(e);
}
};
If you have an image you would want to use URL.createObjectURL:
const file = new Blob([response.data], {
type: "image/png",
});
const objectURL = URL.createObjectURL(file);
myImage.src = objectURL;

Upload blob file to cloudinary using React, Cloudinary Bad Request 400

I am trying to crop images from the selected files so, it is getting converted into blob,
Now i am facing difficulty in uploading them to the cloudinary , as it says its a bad request and
not getting uploaded.
The code goes like,
const blobToBase64 = (blob) => {
const reader = new FileReader();
reader.readAsDataURL(blob);
return new Promise((resolve) => {
reader.onloadend = () => {
resolve(reader.result);
};
});
};
const uploadFilesToCloud = async () => {
const data = new FormData();
for (let i = 0; i < imageUrls.length; i++) {
console.log("This is from within the loop: imageURL", imageUrls[i]);
blobToBase64(new Blob([imageUrls[i]])).then(async (myFile) => {
console.log(typeof myFile); // res is base64 now
console.log("This is from within the loop file BaseToBase64", myFile);
data.append("file", myFile);
data.append("upload_preset", "theVegCakeShop");
const res = await fetch(
"https://api.cloudinary.com/v1_1/dpurb6xes/image/upload",
{
method: "Post",
body: data,
}
);
const response = await res.json();
console.log(response.secure_url);
setImages((prev) => [...prev, response.secure_url]);
});
}
};
Output is
This is from within the loop: imageURL blob:http://localhost:8888/7fbda7a7-e4d5-4716-a888-c9dbd80cd4fb
string
This is from within the loop file BaseToBase64 data:application/octet-stream;base64,YmxvYjpodHRwOi8vbG9jYWxob3N0Ojg4ODgvN2ZiZGE3YTctZTRkNS00NzE2LWE4ODgtYzlkYmQ4MGNkNGZi
POST https://api.cloudinary.com/v1_1/dpurb6xes/image/upload 400 (Bad Request)
undefined
Your base64 data looks wrong, it's mimetype is application/octet-stream, it should be something like image/png for example. So it looks like the image URL you are passing is not really an image - once you start decoding actual images, it should upload fine.
Instead of actually converting the imageUrl into blob and then base64. Directly convert the imageUrl into Base64.
Using the following function.
const getBase64FromUrl = async (url) => {
const data = await fetch(url);
const blob = await data.blob();
return new Promise((resolve) => {
const reader = new FileReader();
reader.readAsDataURL(blob);
reader.onloadend = () => {
const base64data = reader.result;
resolve(base64data);
};
});
};
And then in your code.
for (let i = 0; i < imageUrls.length; i++) {
const finalImage = await getBase64FromUrl(imageUrls[i]);
data.append("file", myFile);
data.append("upload_preset", "theVegCakeShop");
const res = await fetch(
"https://api.cloudinary.com/v1_1/dpurb6xes/image/upload",
{
method: "Post",
body: data,
}
);
const response = await res.json();
console.log(response.secure_url);
setImages((prev) => [...prev, response.secure_url]);
}

I am uploading images to cloudinary onChange but having challenges saving the response images urls as a state array or object

After my images have been uploaded my response returns secured images urls. However i want to save the urls as an array or object of image urls as they are for my products gallery.
const multipleFilesUpload = async (files) => {
const formData = new FormData();
for (let i = 0; i < files.length; i++) {
let file = files[i];
formData.append("file", file);
formData.append("upload_preset", "kwingy");
axios
.post("https://api.cloudinary.com/v1_1/kwjsjsy/image/upload", formData)
.then((response) => {
console.log(response.data.secure_url);
});
}
};
When the images are uploaded its logging the urls of the multiple images. How do i save the urls as a state array or object as i will want to pass it to my database later on.......
below is my console log response
https://res.cloudinary.com/kwingy/image/upload/v1648607946/tudifdsk2j0dy7tpumze.png index.tsx:48:18
https://res.cloudinary.com/kwingy/image/upload/v1648607947/f8ylw5iwlaajzhjqr5ld.png index.tsx:48:18
https://res.cloudinary.com/kwingy/image/upload/v1648607946/kpyqcxxgysumahggerom.png index.tsx:48:18
​
You could restructure the code to queue up the uploads, run them concurrently, then pull out the secure links and write them to your DB. Something like this:
const multipleFilesUpload = async (files) => {
const formData = new FormData();
const postPromises = []
for (let i = 0; i < files.length; i++) {
let file = files[i];
formData.append("file", file);
formData.append("upload_preset", "kwingy");
postPromises.push(axios.post("https://api.cloudinary.com/v1_1/kwjsjsy/image/upload", formData))
}
try {
const results = await Promise.all(postPromises)
// Now pull out the urls and write to your DB...
console.log('secure_urls', results.map(({data:{secure_url}})=>secure_url))
} catch (error) {
// if any of the uploads fail, they all fail
console.log(error)
}
}
You could put the values into a state variable:
// state variable to hold your values
const [secureUrls] = useState([])
const multipleFilesUpload = async (files) => {
const formData = new FormData();
for (let i = 0; i < files.length; i++) {
let file = files[i];
formData.append("file", file);
formData.append("upload_preset", "kwingy");
axios
.post("https://api.cloudinary.com/v1_1/kwjsjsy/image/upload", formData)
.then((response) => {
console.log(response.data.secure_url);
// add url to the array of urls
secureUrls.push(response.data.secure_url)
});
}
};

How to convert blob into base64 in nextJs

I am getting the Image from an API response. I am trying to the get the image and display in the UI.
import FileReader from 'filereader';
export default async (req, res) => {
const { method } = req;
switch (method) {
case 'GET':
try {
const response = await fetch("imagepathurl", Constants.config);
const imageBlob = await response.blob()
console.log("imageBlob", imageBlob)
return new Promise((resolve, _) => {
const reader = new FileReader();
reader.onloadend = () => resolve(reader.result);
reader.readAsDataURL(imageBlob);
});
} catch (error) {
console.log("error", error);
}
break
default:
res.setHeader('Allow', ['GET', 'PUT', 'PATCH'])
res.status(405).end(`Method ${method} Not Allowed`)
}
}
I can able to capture imageBlob but from the fileReader() i am unable to capture and convert to base64.
In File Reader i am facing Error: cannot read as File: {}.
Please let me know the way i am doing is correct or can soneone guide me in fixing it.

Resources