How can I fix the error when using the Sharp library? - node.js

I want to resize and compress images using sharp library in node.js. The code was taken from this article, but for some reason returns an error.
Error
PS D:\Code\Web\image-compressor-nodejs> node index.js
[Error: ./uploads/2022-08-10T18:35:49.251Z-2021-11-18_23.44.45.png.webp: unable to open for write
windows error: ���������� �� �������� �������.
]
Code
const express = require("express");
const multer = require("multer");
const sharp = require("sharp");
const fs = require("fs");
const app = express();
const storage = multer.memoryStorage();
const upload = multer({ storage });
app.use(express.static("./uploads"));
app.post("/", upload.single("picture"), async (req, res) => {
try {
fs.access("./uploads", (error) => {
if (error) {
fs.mkdirSync("./uploads");
}
});
const { buffer, originalname } = req.file;
const timestamp = new Date().toISOString();
const ref = `${timestamp}-${originalname}.webp`;
await sharp(buffer)
.webp({ quality: 20 })
.toFile("./uploads/" + ref);
const link = `http://localhost:3000/${ref}`;
return res.json({ link });
} catch (error) {
console.log(error);
}
});
app.listen(3000);

Related

how do I receive an image that I've uploaded to my server using multer and nodejs in my angular app?

Please I'm new to Nodejs and I'm trying to create an image uploader that will upload files to my server using Nodejs and multer, but the problem is in getting the image back to be displayed in my angular app.
This is the backend code:
const express = require('express');
const multer = require('multer');
const cors = require('cors');
const app = express();
var corsOptions = {
origin: "*",
optionsSuccessStatus: 200,
}
app.use(cors(corsOptions));
app.use(express.static('uploads'));
const storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, "uploads");
},
filename: function (req, file, cb) {
cb(null, `${Date.now()}_${file.originalname}`);
},
})
const upload = multer({ storage });
app.post('/file', upload.single('file'), (req, res) => {
const file = req.file;
if (file) {
res.json(file);
} else {
throw new Error('File upload unsuccessful')
}
})
const port = 3000;
app.listen(port, () => console.log(`Server running on port ${3000}`));
This is my app.html code:
<input type="file" name="image" (change)="upload($event)">
This is my app.ts code:
upload(event: any) {
const file = event.target.files[0];
const formdata = new FormData();
formdata.append('file', file)
this.httpClient.post('http://localhost:3000/file', formdata)
.subscribe((data) => {
console.log(data);
},
(error) => {
console.log(error)
})
Please help me retrieve the image so that I can use it in my angular app. Thank you.
There are two ways you can achieve this. Both the approaches have their own pros and cons.
Store the image locally and send the URL back to the browser.
if (req.files) {
const fileNames = [];
for (let i = 0; i < req.files.length; i++) {
const file = req.files[i];
const relPath = "your/img/path";
const dirName = path.join(BASE_APP_PATH, relPath);
const relFileName = path.join(
relPath,
`${i + 1}_${file.originalname.replace(",", "")}`
);
const img_location = `${dirName}/${
i + 1
}_${file.originalname}`;
if (!fs.existsSync(dirName)) fs.mkdirSync(dirName, { recursive: true });
fs.writeFileSync(img_location, file.buffer, {});
fileNames.push(relFileName);
}
}
Get the image and send back base64 to the browser.
const encoded = req.files[0].buffer.toString('base64')

how to download and save video using nodejs

i want to download video from tiktok
using nodejs and tiktok-scraper-without-watermark package
but when the mp4 file downloaded wont open
is there is any more work
http://localhost:7780/tik?title=test&url=https://www.tiktok.com/#youneszarou/video/6942436555692805381
my attempt is
const https = require("https");
const fs = require("fs");
const express = require("express");
const router = express.Router();
const tiktok = require("tiktok-scraper-without-watermark");
const pool = require("../config/db");
router.get("/", async (req, res) => {
try {
const { title, url } = req.query;
const path = process.cwd() + `/videos/${title}.mp4`;
const tik = await tiktok.tiktokdownload(url);
//console.log("tik", tik);
const requ = https.get(tik.nowm, (response) => {
const file = fs.createWriteStream(path);
response.pipe(file);
file.on("error", function (err) {
console.log("err", err);
});
file.on("finish", function () {
file.close();
console.log("done");
});
});
requ.on("err", (error) => {
console.log("error", error);
});
res.status(200).json(tik);
} catch (error) {
console.log("error", error);
res.status(401).json(error);
}
});
module.exports = router;
the result of tiktok package is
{
nowm: "https://ttdownloader.com/dl.php?v=YTo0OntzOjk6IndhdGVybWFyayI7YjowO3M6NzoidmlkZW9JZCI7czozMjoiYzc5YWZmNmIwYzkwNzk2ZDMxODg0YmU0MmMxMjJjNGIiO3M6MzoidWlkIjtzOjMyOiJlZDBiNGY4ZWFmZjJjMjllNjZiMzEzZjc0YTMxZWYzOCI7czo0OiJ0aW1lIjtpOjE2NDg5MTAxMjg7fQ==",
wm: "https://ttdownloader.com/dl.php?v=YTo0OntzOjk6IndhdGVybWFyayI7YjoxO3M6NzoidmlkZW9JZCI7czozMjoiYzc5YWZmNmIwYzkwNzk2ZDMxODg0YmU0MmMxMjJjNGIiO3M6MzoidWlkIjtzOjMyOiJlZDBiNGY4ZWFmZjJjMjllNjZiMzEzZjc0YTMxZWYzOCI7czo0OiJ0aW1lIjtpOjE2NDg5MTAxMjg7fQ==",
audio: "https://ttdownloader.com/mp3.php?v=YTozOntzOjc6InZpZGVvSWQiO3M6MzI6ImM3OWFmZjZiMGM5MDc5NmQzMTg4NGJlNDJjMTIyYzRiIjtzOjM6InVpZCI7czozMjoiZWQwYjRmOGVhZmYyYzI5ZTY2YjMxM2Y3NGEzMWVmMzgiO3M6NDoidGltZSI7aToxNjQ4OTEwMTI4O30="
}

Storing Images in Mongodb With GridFS Using Express Server

I am trying to upload, save and display images in MongoDB using express server and GridFS.
Data is sent with FormData with vue.js on the front-end and that part works well.
Images are getting to the server, and it stores that data, but I can not display the uploaded image, instead I get this
It displays the Image in some encoding I guess.
Here is server code for receiving, storing and displaying images.
const express = require('express')
const mongodb = require('mongodb')
const path = require('path')
const crypto = require('crypto')
const mongoose = require('mongoose')
const multer = require('multer')
const GridFsStorage = require('multer-gridfs-storage')
const Grid = require('gridfs-stream')
const methodOverride = require('method-override')
const config = require('../../config/keys')
const morgan = require('morgan')
const images = express()
// MIDDLEWARE
images.use(methodOverride('_method'))
// images.use(morgan("default"))
// MONGO URI
const mongoURI = config.dbUrl
// CREATE MONGO CONNECTION
const conn = mongoose.createConnection(mongoURI)
// INITALIZE GRID FS
let gfs
conn.once('open', () => {
gfs = Grid(conn.db, mongoose.mongo)
gfs.collection('uploads')
})
// CREATING STORAGE ENGINE
const storage = new GridFsStorage({
url: mongoURI,
file: (req, file) => {
return new Promise((resolve, reject) => {
const filename = file.originalname
const fileInfo = {
filename,
bucketName: 'uploads'
}
resolve(fileInfo)
})
}
})
const upload = multer({ storage })
// POST REQUEST UPLOADS FILE TO DATABASE
images.post('/', upload.single('image'), (req, res) => {
console.log('POST REQUEST TO HTTP://LOCALHOST:3000/API/BACKEND/IMAGES/')
res.json(req.file)
console.log(req.file)
})
// GET REQUEST
images.get('/', async (req, res) => {
console.log('GET REQUEST TO HTTP://LOCALHOST:3000/API/BACKEND/IMAGES/')
const posts = await load();
res.send(await posts.find({}).toArray())
})
images.get('/:filename', (req, res) => {
gfs.files.findOne({ filename: req.params.filename }, (err, file) => {
// Check if file
if (!file || file.length === 0) {
return res.status(404).json({
err: 'No file exists'
});
}
// Check if image
if (file.contentType === 'image/jpeg' || file.contentType === 'image/png') {
// Read output to browser
const readstream = gfs.createReadStream(file.filename);
readstream.pipe(res);
} else {
res.status(404).json({
err: 'Not an image'
});
}
});
});
// LOADING FUNCTION FOR MONGODB
async function load() {
const client = await mongodb.MongoClient.connect
(`${config.dbUrl}`, {
useNewUrlParser: true,
useUnifiedTopology: true
});
return client.db('myCluster').collection('uploads.files');
}
module.exports = images
Every help would be nice and much appreciated! Thanks! :)

while uploading image I cannot see the content

I have a problem uploading image file to my mongoDB using gridFS, but for some reason this doesn't work
this is my code :
const config = require("config");
const express = require("express");
const router = express.Router();
const dbURI = config.get("mongoURI");
const multer = require("multer");
const crypto = require("crypto");
const path = require("path");
const GridFsStorage = require("multer-gridfs-storage");
var storageImage = new GridFsStorage({
url: dbURI,
file: (req, file) => {
return new Promise((resolve, reject) => {
crypto.randomBytes(16, (err, buf) => {
if (err) {
return reject(err);
}
const filename = buf.toString("hex") + path.extname(file.originalname);
const fileInfo = {
filename: filename,
bucketName: "user_images"
};
resolve(fileInfo);
});
});
}
});
const uploadImage = multer({ storageImage });
router.post("/uploadImage", uploadImage.single("userImg"), (req, res) => {
console.log("uploading");
console.log(req.file);
res.json({ msg: "file uploaded successfully" });
});
module.exports = router;
when I console .log req.file I get undefined, does anyone know what the problem is?
I found the problem:
const uploadImage = multer({ storageImage });
it should be
const uploadImage= multer({storage:storageImage});

middleware is an object instead of a function

I'm trying to make a file upload API using multer gridFS, I used the documentation but I'm missing something:
this is my code:
const config = require("config");
const express = require("express");
const router = express.Router();
const dbURI = config.get("mongoURI");
const multer = require("multer");
const crypto = require("crypto");
const path = require("path");
const GridFsStorage = require("multer-gridfs-storage");
var storage = new GridFsStorage({
url: dbURI,
file: (req, file) => {
return new Promise((resolve, reject) => {
crypto.randomBytes(16, (err, buf) => {
if (err) {
return reject(err);
}
const filename = buf.toString("hex") + path.extname(file.originalname);
const fileInfo = {
filename: filename,
bucketName: "uploads"
};
resolve(fileInfo);
});
});
}
});
const upload = multer({ storage });
router.post("/upload", upload.single("file"), (req, res) => {
res.json({ msg: "file uploaded successfully" });
});
I get an error TypeError: Router.use() requires a middleware function but got a Object which basically tells me that upload.single is not a function, what is my error?
I found the mistake, I was missing module.exports = router;

Resources