How to get file buffer from file

i’m Uploading an image on image selection.

export function btnUpload_change(event) {
var files = $w( ‘#btnUpload’ ).value;
upload(files[ 0 ])
.then( function (results) {
console.log(results);
})
. catch(function (err) {
console.log( "Promise rejection error: " + err);
});
console.log(files);
}
As given link i need buffer to upload an image.
https://www.wix.com/velo/reference/wix-media-backend/mediamanager-obj/upload

But how to convert uploaded image into buffer?

In backend
export async function upload(buffer){
try {
console.log( ‘into file upload function’ );
return mediaManager.upload(
“/myfolder” ,
buffer,
“testimage” ,
{
“mediaOptions” : {
“mimeType” : “image/jpeg” ,
“mediaType” : “image”
},
“metadataOptions” : {
“isPrivate” : false ,
“isVisitorUpload” : false ,
“context” : {
“someKey1” : “someValue1” ,
“someKey2” : “someValue2”
}
}
}
);
} catch (err) {
console.log(err);
}
}

Before I answer, any reason you are not using the startUpload() function?

  1. I want to save file in specific folder.
  2. I want to upload this file on aws for that i need to pass buffer data in aws upload method.

My priority is to Upload file on AWS. All I need is to covert the selected file into any of the below formats. Currently, I’m sending a file but it’s giving me an error.

This is my Backend aws code.

In body in need pass data (Image in string,Stream,Buffer Or Blob)

Can you provide the answer to this question? This is very related to an issue I am currently facing. Thanks in advance for any help!

This request appears not to have an answer?
I also would like to know how to crate a buffer for an file input.
I’m don’t want to use the wix element because it allows no control of where the image will be stored.

Did you already construct a → “Blob” / File-Selector (using an HTML-Component)?

Or how do you select your wished file(s)?

And before we continue, i also first want to ask you, why not using the normal UPLOAD-BUTTON function, like already asked here…

What is your usecase? What are you trying to achieve, creating the wished functionality?

@russian-dima as I mentioned, I don’t want to use the standaard wix upload button, because it’s to limited.

@pimdorrestijn
Ok, how to solve your issue? There are different ways of how to do it.

One way would be…

  1. Creating a File-Selector/Blob in an HTML-Component (HTML-+JS-Code)
  2. Generating an UPLOAD-URL (needed to do the upload)
  3. Connect the communication between HTML-Component and PAGE (you will need this to send UPL-URL to your HTML-Component.
  4. In your HTML-Component you choose your wished file using your created File-Selector.
  5. Fileselector sends INFO-DATA back to PAGE (if needed) and also starts the UPLOAD.
  6. Also you should learn about → BASE64

Edit: I am currently working on a similar project, so if you need more help or even a service you can contact me (look into profile).

@russian-dima I just found out that wix does not support importing backend functions into custom elements.
I guess that’s why you pointed out the interaction between page and element → thnx.
Currently already trying to map a custom event for the interaction between page and custom element to handle the call towards the backend script.
I guess then I can some how get a blob?!?
Workaround with event is not so nice, I’ll just archive it under wix-illities (thnx though)

I can’t tell you anything about Custom-Elements, because i have never touched them before (yet). Perhaps in future. I am using the html-component for my purposes and it works like it should.

To answer your question on buffer, you do this:

const fetch = require('node-fetch'); //NPM package I like using but you can use wix-fetch

let buffer = await create_buffer(); //This is the buffer
let encoded_file = await encoder(buffer); //This is the base64 encoded result

const create_buffer = () => {
    return fetch(YOUR_URL, {
        method: 'GET',
        encoding: null
    })
    .then( (res) => {
        return res.buffer(); //This is the buffer
    });
}

const encoder = (string) => {
    var encryptedBytes = Buffer.from(string);
    var encoded = encryptedBytes.toString('base64');
    return encoded;
}

But you will not be able to directly upload a file without going thru the wix media manager natively, with custom html code or custom element you may be.

@shantanukumar847
Just to understand your statement right Shan, …

But you can’t upload a file directly without using the Wix Media Manager natively, with custom HTML or custom element that you may be.

Is the problem the missing option of creating a file-selector without html-component or custom element? I also still have the question, if it is somehow possible to avoid the HTML-way and do it somehow by an NPM-installation or similar workaround.

Once i have had a little conversation with J.D. here in one of the posts, where he talked about that he is using another way (if i understood him right). Can’t find the post again. :sleepy::sleepy::sleepy:

@shantanukumar847 Another try to ask ^^

Ok, my question is, why do i need this …

const fetch = require('node-fetch'); //NPM package I like using but you can use wix-fetch

let buffer = await create_buffer(); //This is the buffer
let encoded_file = await encoder(buffer); //This is the base64 encoded result

const create_buffer = () => {
    return fetch(YOUR_URL, {
        method: 'GET',
        encoding: null
    })
    .then( (res) => {
        return res.buffer(); //This is the buffer
    });
}

const encoder = (string) => {
    var encryptedBytes = Buffer.from(string);
    var encoded = encryptedBytes.toString('base64');
    return encoded;
}

When i am forced to use HTML-Component to make a FILE-SELECTION, i also can use the HTML-Component to make buffer and UPLOAD directly aswell, right?

The NPM-Package would be useless in this case, or do i mix-up something?

<html>
  <head>
  </head>
  <body id="body" style="text-align:center;">
    <input type="file", name="fileSelector1", id="fileSelector", accept="image/*", onchange="openFile(event)", multiple><br>
    <div>
      <p id="imgElement" style="color:green; font-size: 20px; font-weight: bold;"></p>
    </div>
    <script type="text/javascript"> 
      //-----------------------------------------------
      var openFile = async function(event) {var data={};    
        var input = await event.target;									 
        var inputDATA = input.files[0];						
        var fileName = inputDATA.name;						
        var fileType = inputDATA.type;						
        var fileSize = inputDATA.size;						
       	var accepted = input.accept;							
        var filesTotal = input.files.length;
        //------------------------------------        
        var reader = new FileReader(); 
         reader.onloadend = async function (event) {var img = new Image(); 
          img.src = await event.target.result;
          img.onload = function () {
            data.height = img.height;
            data.width = img.width;
            data.fileName = fileName;
            data.fileSize = fileSize;
            data.fileType = fileType;
            data.filesTotal = filesTotal;
            data.accepted = accepted;    
            data.base64 = img.src;	 
            if (filesTotal>=0) {window.parent.postMessage(data,"*");}
          };
        };
	reader.readAsDataURL(inputDATA);    
        //-----------------------------------
        window.onmessage = (async(event) => {
          var uploadURL = event.data; 
          var formData = await new FormData();
          formData.append('upload_token', '');
          formData.append('file', inputDATA);
          let request = await new XMLHttpRequest();   
          request.open("POST", uploadURL);
          request.responseType = "json";
          request.onreadystatechange = function() {
            if (request.readyState == XMLHttpRequest.DONE) {
              const response = request.response; 
              let resultUrl = 'https://static.wixstatic.com/media/' + response[0].file_name;
              data.fileInfo=request.response[0];
              window.parent.postMessage(data,"*");
            }
          }
          request.send(formData);          
        });
      };
      //----------------------------------- 
    </script>
  </body>
</html>

By the way, here a working example… (not perfect yet, but works already…):grin:
The only problem → you get catched in a LOOP. And i did not found out how to stop the loop.

https://russian-dima.wixsite.com/login-system/vnbadgemgm

You will have to open the Badge-Upload-Menu…

Do an UPLOAD…(of a pic)…


Take a look onto given RESULTS…

Adding the following line…

var fileSRC =  input.files[0].stream;         	console.log("File-SRC: ", fileSRC);

Should give back the BUFFER-Array, as i can remember.

@russian-dima If you are using html then of course you have another way but the solution i gave was in response to the “How to get file buffer from file” for any files uploaded via the native wix upload button (to the media manager) :slight_smile:

@shantanukumar847
Ah ok, in your case the file already exists in the Media-Manager, right? Ok understood.

@shantanukumar847
Any idea how to stop the looping between PAGE and HTML-Comp?
This happens after you have uploaded a file…(a never ending loop).

It starts a loop, between PAGE and HTML-Component (post-message/on-message),
which i can’t stop the right way. It should be just one upload :laughing:

@shantanukumar847 If you use the wix upload button, then you can simply use it’s upload File function.

As I was on a conference yesterday, I was not able to work on this.
However, I nearly have a solution which I will share in this post:

My case is an editable image gallery. To be precise an image gallery which allows the user to add, reorder and delete images.

Wix does not provide such an element for your website, thus I have choosen to create one myself using a custom element.
When using a custom element, there are some limitations:

  • custom elements can not import Web Modules; This inevidently means that additional javascript (say: a controller) is needed when you want to use wix media manager to upload new images to a specific folder.
  • support on getting and sending data on a custom html element is limited by wix through html attributes. Additionally a custom element can not use wix-storage; This inevidently means that if you want to chance the data set that a custom element uses, that you should handle those changes through (custom) events from custom element to a controller, which in turn will set the updated data through html attributes such that the custom element will show the updated data.

Given these limitations, the following solutions should work to implement the desired features (still implementing at this point):

Adding images:

  • custom element creates child elements being a hidden file input, a window clickable element which will forward the click event to the input
  • the custom element will subscribe to the change event of the file input and dispatch it as a new custom ‘upload’ event for the controller to handle.
  • the controller will handle the upload event by getting the event details (wrapping the file info from change event). From these details I use the arrayBuffer to get the data and I use the npm base64-arraybuffer to convert it to a base64 encoded string. This string of data can be transferred by the controller towards a web module in the backend that has access to the media manager to upload the new image to a specific media folder.
  • once the upload completes, the response will provide a wix link to the image.
  • the controller can substitute this link to a real static link and add it to the existing list of images. This updated list of images can be set as an html attribute which should trigger your custom element to rebuild it’s view based on the updated set.

Reordering images:
I expect the solution should be event based much like the solution as outlined with adding images. Were each image will have an index for ordering, the event will change the indices in the original data kept by the controller and set the updated data on the custom element.
This feature also requires you to store the gallery index somewhere. A logical place would be to store it in a data collection (image reference with gallery index). It would be the responsability of the controller to store this information when needed.

Removing an image:
Also using an event from custom element to the controller. There is one limitation. We can remove the image from the dataset, but we can not remove the image from the media folder as the media manager does not provide this functionality. So this solution will leave garbage.