removing image metadata from a buffer file in node js - javascript

I have the following code that downloads an image from URL
let imageBuffer = await rp.get({
url: pictureUrl,
encoding: null
});
and i wanted to remove the image metadata from this file. Is it possible to remove the metadata without actually saving the buffer first into a file ?

Related

How do I convert an ObjectURL to a DB Insertable BLOB

Sending PHP the retval of the Object URL created from an image (blob:http://...) and using PHP's base64_encode() along side with file_get_contents() returns an error claiming that there is no stream or file.
How about send url of image. then use file_get_contents('http://...') to get the image file content.
For example, your image url is http://example.com/test.jpg
JS
// if image is a link
axiso.post(url, {image: "http://example.com/test.jpg"})
// if image is file select from local, upload file
let data = new FormaData();
formData.append("image", this.files[0]);
axiso.post(url, data, {headers: {'Content-Type': 'multipart/form-data'}})
PHP
// get file content from image link
file_get_contents('http://example.com/test.jpg')
// get content from upload file
$name= "image";
file_get_contents($_FILES[$name]);

Excel file from server to client | Javascript

What I want to do: I have on the server side a file 'test_download.xlsx', and want to send it to the client side so that I can apply XLSX.read() on the retrieved object.
So I tried it this way
Server :
let filename = 'test_download.xlsx';
const buffer = fs.readFileSync(filename)
res.json(buffer);
Client :
file = await axios.get('/dataexplorer/test');
console.log(file);
console.log(XLSX.read(file.data, {type: "buffer"}));
First log :
Second log :
The problem is that it doesn't match my excel file at all just in terms of sheets (my file has 3 different sheet names)
Do you have any idea what the problem is?
Thanks
On the server-side just use:
const filename = 'test_download.xlsx';
// make sure to include the name and the extension of the file in the path
const filepath = 'your/path/to/the/file/test_download.xlsx';
/** filename is optional:
* if you don't pass it, the name of the file in the filepath will be used
* if you pass it the file at hte filepath will be downloaded with the name of `filename`
*/
res.download(filepath, filename);
This will return a blob to the client(make sure to include the correct headers for the response type) and then you can just save it or work with it with :
file = await axios.get('/dataexplorer/test',{ responseType: "blob"});
const ab = await file.data.arrayBuffer();
XLSX.read(Buffer.from(ab),{type:"buffer"})

Write image file to Firebase Storage from HTTP function

I am trying to write an image Firebase Storage via a Cloud Function (for more suitable write access).
My current attempt is to read the file object on the client, send it (the data) to an http firebase function, and then save it to storage from there. After saving the file successfully, I try using the download url as an img src value, but the file does not display. I also see an error in the Storage console (Error loading preview) when attempting to view the file.
If I save the data in Storage as base64, I can copy the contents of the file into the img src attribute, and it displays fine. However, I'd like to simply use the download URL as I could do if I just uploaded the image via the client SDK or directly via the console.
In the client, I'm simply using FileReader to read the uploaded file for sending. I've tried all the ways of reading it (readAsText,readAsBinaryString, readAsDataURL, readAsArrayBuffer), but none seem to solve the issue.
Here is how I am uploading the file via the Firebase Function:
import * as functions from 'firebase-functions';
import * as admin from 'firebase-admin';
import * as path from 'path';
import * as os from 'os';
import * as fs from 'fs-extra';
export default functions.https.onCall(async(req, context) => {
const filename = req.filename;
const bucket = admin.storage().bucket(environment.bucket)
const temp_filename = filename;
const temp_filepath = path.join(os.tmpdir(), temp_filename);
await fs.outputFile(temp_filepath, req.data, {});
// Upload.
await bucket.upload(temp_filepath, {destination: 'logos'})
.then((val) => {})
.catch((err) => {});
});
This uploads the file successfully, however, the Download URL does not work when used as the img src attribute.
One thing I have noticed is that when using the client SDK to send a file (via AngularFireStorage), the payload is the raw png contents. E.g. a snippet of the file:
PNG
IHDRÈÈ­X®¤IDATx^í]
Eµ¾·{&1,!dù»*yVQ#PTEDPA>ÊâC\P"ÈÄ"
F}òIW÷üCL#BÉL÷}
....
However, reading the file as text does not yield this encoding. I have tried several other encodings.
Any help would be immensely appreciated.
Edit
Here is what I mean about using the download URL:
<img alt='logo' src='https://firebasestorage.googleapis.com/v0/b/y<project-name>/o/logos%2FAnM65PlBGluoIzdgN9F5%2Fuser.png?alt=media&token=<token>' />
The above src url is the one provided in the Firebase Storage console when clicking on the file. It is labeled as 'Download URL' (I believe this is the one retrieved by calling getDownloadUrl() via the sdk).
When using AngularFireStorage to put the file in storage, the Download URL will work. When I say it 'will work', I mean the image will display properly. When using FileReader to pass the data to an http cloud function to upload (as seen above), the image will not display. In other words, after uploading the file via the backend, the download url does in fact provide what was uploaded, it's just not in a format that an img tag can display.
One possible issue may be that I am not getting the encoding correct when using FileReader readAsText. Here is what I am doing with FileReader:
const reader = new FileReader();
reader.onloadend = () => {
firebase.functions().httpsCallable('http_put_logo')(reader.result);
};
// Have tried various encodings here, as well as all reader methods.
reader.readAsText(file);
Edit 2
All of the discussion on this question so far seems to be around correctly getting the download URL. I'm not sure if Firebase docs have this information, but the download URL is available in the Storage console. I'm simply copying and pasting that URL to for testing purposes at the moment.
The reason why I am doing this is because I plan to save these image URLs in the DB since they are going to be frequently used and publicly readable. So, I'm not going to use the getDownLoadURL() method to fetch these images, I'm simply just going to link to them directly in img tags.
Here is an image of my console to see what I mean (bottom right):
You just have to click it and copy it. You can then open it in a browser tab, download it, use it as a src value, etc.
Edit 3
Here is an image of what the request payload looks like when using the client sdk:
Here is when I read the file as text and send to backend for upload:
Notice there are differences in the payloads. That's why I'm uncertain if I'm properly reading the file or encoding it incorrectly.
What part of your code is taking care of getting the URL? I recently used a similar approach to uploading images to Firebase Storage using cloud functions. What worked best for me was to execute a different function to get the URL after the upload is complete. Something like this:
const bucket = admin.storage().bucket(environment.bucket)
const temp_filename = filename;
const temp_filepath = path.join(os.tmpdir(), temp_filename);
await fs.outputFile(temp_filepath, req.data, {});
// Upload.
await bucket.upload(temp_filepath, {destination: 'images'})
.then((val) => {retrieveUrl(temp_filename)})
.catch((err) => {});
retrieveUrl = (imageName) => {
const storage = firebase.storage();
storage.ref(`/images/${imageName}.jpg`).getDownloadURL()
.then( url => {
/*Save the url to a variable or attach it directly to the src of your image, depending on the structure of your project*/
})
.catch(err => console.log(err));
}
Keep in mind that you need to install firebase in your project in order to call firebase.storage.

pdf file is corrupted when a file encoded in base64 is downloaded

I try to download a pdf file that has been previously encoded using base 64.
I try to download it from an anchor tag, as follows
Download;
The file is downloaded but when I try to open it I get a message that the file has damage or is corrupted.
Interestingly, if I change href to an encode image data, the file is downloaded and opened as expected.
I found this example http://jsfiddle.net/filixix/0816jdfq/ and I see that is changed from data:application/pdf;base64, to data:application/octet-stream;base64, I tried but I am getting the same result.
Update
I am encode the pdf file as follows
const element = document.querySelector('#file'); // input type file
element.addEventListener('change', handleChange);
function handleChange() {
const file = this.files[0];
const fileReader = new FileReader();
fileReader.onload = function() {
const data = this.result;
// store data in database in a text type field
};
fileReader.readAsDataURL(file);
}
hen, in the view where I want to download the file, I realize the logic that I commented
General idea works as expected.
But I recommend You to keep pdf as file.
Cause Your corrupted pdf issue may be because of db field size (if You keep that string in db) or browser's request url limitations
So You're saying:
store data in database in a text type field
If You don't plan to move to file storage just change field type to: LONGBLOB

Edit a file to be uploaded

I would like to be able to edit a file that has been selected for upload. I want to search and replace text in case absolute files should be made relative...
I notice in the File API I can do some of it, but I get a little stuck:
document.getElementById('exampleInputFile').onchange = function(event) {
var fileToLoad = event.target.files[0];
if (fileToLoad) {
var reader = new FileReader();
reader.onload = function(fileLoadedEvent) {
var textFromFileLoaded = fileLoadedEvent.target.result;
//Use logic to remove absolute files
//Upload S3
};
reader.readAsText(fileToLoad, 'UTF-8');
}
};
I am trying to figure out how now to convert that text to a proper File so that I can upload it to S3 using an existing api that expects something returned by: event.target.files[0] code above.
I do not want the server to handle any heavy lifting here if I can avoid it (files can easily be a few megabytes since they can be 3D models).
Assuming you know the url of the file when it lands in the S3 bucket, you can retrieve the file using a http.get, which will give you the contents of the (I assume plain text file). You can then parse that file and do whatever modification you need to do on the contents. If the file has changed, you can then write it back to the S3 bucket to replace the original file.
On AWS you can use Lambda to execute NodeJS code when an event is triggered (for example an upload to a specified bucket).

Categories

Resources