Upload Image to Supabase Storage Using Storage APIs - request

Supabase is wonderful !! I am trying to upload an image to the public bucket using POST request to <SUPABASE_URL>/storage/v1/object/<BUCKET_NAME>/<IMAGE_NAME>.
The difficult is I have only base64 encoded image string and I am not able to make a successful request to above endpoint. Have tried numerous iterations of setting Content-type but no luck.
I am trying to upload my image from Appsmith which provides base64 format for the image from where I will have to hit the above endpoint.
Please help me out here.

I'm glad to be able to find another Supabase fan like me!
I hear your pain. Could you try this technique to convert base 64 string to a blob object?
const byteCharacters = atob(b64Data);
const byteNumbers = new Array(byteCharacters.length);
for (let i = 0; i < byteCharacters.length; i++) {
byteNumbers[i] = byteCharacters.charCodeAt(i);
}
const byteArray = new Uint8Array(byteNumbers);
const blob = new Blob([byteArray], {type: contentType});
The blob variable at the end is the variable you can use to upload to Supabase.
Also, have you considered using the Supabase-js SDK? It will make your life a lot easier as they provide better API's to interact with Supabase.
You can get the supabase-js package here:
https://www.npmjs.com/package/#supabase/supabase-js
And you can find some sample code here:
https://supabase.io/docs/reference/javascript/storage-from-upload
In your case, you could do something like this to upload your file:
const { data, error } = await supabase
.storage
.from('avatars')
.upload('public/sample.png', blob, {
cacheControl: 3600,
upsert: false
})

Related

How to send a local image instead of URL to Computer Vision API using React

I would like to upload local image file and extract text from it. I followed the below link and it works as expected when I pass URL. https://learn.microsoft.com/en-us/azure/developer/javascript/tutorial/static-web-app/add-computer-vision-react-app
I managed to configure for local image and get the base64 encoded dataURL of the uploaded image. But when I pass base64 encoded dataURL to Computer Vision API , it says "Input data is not a valid image" (POST 400 status code). I am getting error in the line that is shown below:
const analysis = await computerVisionClient.analyzeImage(urlToAnalyze, { visualFeatures });
The code I have included for handling local image:
const handleChange = (e) => {
var file = e.target.files[0];
var reader = new FileReader();
reader.onloadend = function()
{
setFileSelected(reader.result) // this is the base64 encoded dataurl
}
reader.readAsDataURL(file);
}
In computerVision.js file, I have changed the 'contentType' in header as below.
const computerVisionClient = new ComputerVisionClient(
new ApiKeyCredentials({ inHeader: {'Ocp-Apim-Subscription-Key': key, 'Content-Type': 'application/octet-stream'} }), endpoint);
I tried replacing client.read() with readTextInStream() as per docs in computerVision.js (please refer above link), but still throws error.
May I know why I get the error "Input data is not a valid image" ? Thanks.
Here is the link for input requirements.
There is a brand new online portal provided by Microsoft https://preview.vision.azure.com/demo/OCR
The advantage is that it will directly list your available resources so you just have to pick the right one, then you test, and there are also some samples.

Is it possible to directly upload images captured by camera to Firebase Storage?

I'm using React.js to create an application that would take a photo and upload it to Firebase Storage. I am using the react-webcam library, which uses this command to take a photo:
const ImageSrc = webcamRef.current.getScreenshot();
This is how I tried uploading the photo to Storage:
storage.ref(`/images`).put(imageSrc)
.on("state_changed" , alert("success") , alert)
However, the file that is uploaded is undefined (no photo).
I tried to construct an URL of the photo using blob:
const imageUrl = window.URL.createObjectURL(new Blob(webcamRef.current.getScreenshot()))
But I get this error: >Failed to construct 'Blob': The provided value cannot be converted to a sequence.
In the library it is stated that getScreenshot - Returns a base64 encoded string of the current webcam image. So, I tried to use the atob command, but I get the error: Failed to execute 'atob' on 'Window': The string to be decoded is not correctly encoded.
Does anyone know how I could upload the image to Firebase Storage? Any help would be appreciated!
Instead of blob, try using putString() command like this:
const task = firebase.storage().ref(`/images`).putString(imageSrc, 'data_url')
As explained in the doc, if you want to upload from a Base64url formatted string, you need to call the putString() method as follows (example from the doc):
var message = '5b6p5Y-344GX44G-44GX44Gf77yB44GK44KB44Gn44Go44GG77yB';
ref.putString(message, 'base64url').then((snapshot) => {
console.log('Uploaded a base64url string!');
});
In your case, since getScreenshot() returns a base64 encoded string, it would be something like:
const imageSrc = webcamRef.current.getScreenshot();
storage.ref(`/images`).putString(imageSrc, 'imgBase64')
.on("state_changed" , alert("success") , alert)

Upload images to Azure blob from front end (React)

The front end enables people to upload their photos, so i was sending the base64 to the server and working with it initially, but there are problems with firewall which blocks the request which contains base64. As an alternative solution I was trying to upload the image to azure blob get the file name and then send that to the server for processing where I generate a sas token for the blob validation and processing.
This works perfectly fine when I work locally and the front end connection works with #azure/storage-blob
and uploadBrowserData() when I send the arrayBuffer as the param
export const uploadSelfieToBlob = async arrayBuffer => {
try {
const blobURL = `https://${accountName}.blob.core.windows.net${sasString}`;
const blobServiceClient = new BlobServiceClient(blobURL, anonymousCredential);
const containerClient = blobServiceClient.getContainerClient(containerName);
let randomString = Math.random().toString(36).substring(7);
const blobName = `${randomString}_${new Date().getTime()}.jpg`;
const blockBlobClient = containerClient.getBlockBlobClient(blobName);
const uploadBlobResponse = await blockBlobClient.uploadBrowserData(arrayBuffer);
return { blobName, blobId: uploadBlobResponse.requestId };
} catch (error) {
console.log('error when uploading to blob', error);
throw new Error('Error Uploading the selfie to blob');
}
};
When I deploy this is not working, the front is deployed in the EastUs2 location and the local development location is different.
I thought the sasString generated for anonymous access had the timezone option so I generated 2 different one's one for local and one for hosted server with the same location selected.
Failed to send request to https://xxxx.blob.core.windows.net/contanainer-name/26pcie_1582087489288.jpg?sv=2019-02-02&ss=b&srt=c&sp=rwdlac&se=2023-09-11T07:57:29Z&st=2020-02-18T00:57:29Z&spr=https&sig=9IWhXo5i%2B951%2F8%2BTDqIY5MRXbumQasOnY4%2Bju%2BqF3gw%3D
What am I missing any lead would be helpful thanks
First, as mentioned in the comments there was an issue with the CORS Settings because of which you're getting the initial error.
AuthorizationResourceTypeMismatchThis
request is not authorized to perform this operation using this
resource type. RequestId:7ec96c83-101e-0001-4ef1-e63864000000
Time:2020-02-19T06:57:31.2867563Z
I looked up this error code here and then closely looked at your SAS URL.
One thing I noticed in your SAS URL is that you have set the signed resource type (srt) as c (container) and trying to upload the blob. If you look at the description of the kind of operations you can do using srt=c here, you will notice that blob related operations are not supported.
In order to perform blob related operations (like blob upload), you would need to set signed resource type value to o (for object).
Please regenerate your SAS Token and include signed resource type as object (you can also include container and/or service in there as well) and then your request should work. So essentially your srt in your SAS URL should be something like srt=o or srt=co or srt=sco.
I couldn't notice anything wrong with the code you mentioned about, but I have been using a different method to upload files to Azure Blog Storage using React, the method is exactly the same as in this blog article which works perfectly for me.
https://medium.com/#stuarttottle/upload-to-azure-blob-storage-with-react-34f37805fdfc

React / Rails API Image Uploading

I've built a React frontend along with a Rails API only backend. I want to allow the user to create a task and enter a title, description and upload an image.
So I've attempted to use DropZone to get access to the image and then send the image info along with the title and description to my Rails API via a post request using Axios.
I set up Carrierwave on my Rails API in hopes of uploading to an AWS S3 bucket once my Task has been added to the database per the post request.
None of this is working so my question is, should I take care of the image uploading to AWS on the react side and if so, how do I associate that image with the additional information I'm saving to my Rails database (title and description).
Thanks!
First, on React side, there should be no proble with title and description, but for image, you need to encode the image to Base64 string. It is something like this.
getBase64 = (callback) => {
const fileReader = new FileReader();
fileReader.onload = () => {
console.log(fileReader.result);
};
fileReader.readAsDataURL(fileToLoad);
fileReader.onerror = (error) => {
console.log('Error :', error);
};
}
Then, on Axios, send those 3 parameters alltogether with one POST request.
For Rails, you need to set up code that can read the Base64 string. Usually, you can use Paperclip or CarrierWavegem to add image attachment. It will look like this.
property_image = listing.property_images.new(param_image)
if param_image[:file_data]
image_file = Paperclip.io_adapters.for(param_image[:file_data])
image_file.original_filename = param_image[:image_file_name]
image_file.content_type = "image/png"
property_image.image = image_file
end
private
def param_image
params.permit(:image, :image_file_name, :file_data)
end

Is it possible to resend image url received from server back to it as an image after processing

I have a remote server which has profile data and an image and when I retrieve it, I get the image url, which I can display using the <img> tag, by using the url.
When I have to modify the details, I send a new image, for which I upload a new image using a small AngularJS function and send the whole data using formData and http request.
But, out of curiosity, I was wondering whether there is any way to send an object of the same image using the url I received from the server.
Another reason I thought of it was that I was thinking of maybe changing its dimensions,etc.
Just in case if I ever needed to generate a thumbnail of the image of a smaller size in future.
Solved it myself by looking around and generating a canvas from the url, through dataURI by using the function :
var byteString = atob(dataURI.split(',')[1]);
var ab = new ArrayBuffer(byteString.length);
var ia = new Uint8Array(ab);
for (var i = 0; i < byteString.length; i++) {
ia[i] = byteString.charCodeAt(i);
}
var blob= new Blob([ab], { type: 'image/jpeg' });
to create a blob to send the image back after scaling(was required).

Resources