add resize image based on url
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
### Simple image resizer
|
### Simple image resizer
|
||||||
|
|
||||||
Run :
|
#### Run :
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
npm i
|
npm i
|
||||||
@@ -12,3 +12,35 @@ or from docker image [solehudin5699/img-resizer](https://hub.docker.com/r/solehu
|
|||||||
```bash
|
```bash
|
||||||
docker run -it --name img-resizer -p 5000:5000 -d solehudin5699/img-resizer
|
docker run -it --name img-resizer -p 5000:5000 -d solehudin5699/img-resizer
|
||||||
```
|
```
|
||||||
|
|
||||||
|
#### Demo :
|
||||||
|
|
||||||
|
- Resize from uploaded image, visit :
|
||||||
|
|
||||||
|
> Local --> http://localhost:5000/
|
||||||
|
|
||||||
|
> My website: https://img-resizer.escloud.my.id/
|
||||||
|
|
||||||
|
- Resize from image url :
|
||||||
|
|
||||||
|
> https://img-resizer.escloud.my.id/{IMAGE-URL}{?|&}width={VALUE}&height={VALUE}&quality={90}&format={format that you want}"
|
||||||
|
|
||||||
|
- Notes:
|
||||||
|
|
||||||
|
- IMAGE-URL: image url that will we resize/format
|
||||||
|
- width: width that will we return (optional, max 5000)
|
||||||
|
- height: height that will we return (optional, max 5000)
|
||||||
|
- quality: quality image that will we return (optional, max 100)
|
||||||
|
- format: format image (optional, use jpeg or jpg, png, or webp)
|
||||||
|
- If IMAGE-URL have query, add "&" at the end IMAGE-URL, then add query width, height, or other that you want.
|
||||||
|
Example:
|
||||||
|
|
||||||
|
IMAGE-URL=https://avatars.githubusercontent.com/u/65361695?v=4
|
||||||
|
|
||||||
|
Use: https://img-resizer.escloud.my.id/https://avatars.githubusercontent.com/u/65361695?v=4&width=100.
|
||||||
|
|
||||||
|
If not, use "?" followed query you want, example
|
||||||
|
|
||||||
|
IMAGE-URL=https://avatars.githubusercontent.com/u/65361695
|
||||||
|
|
||||||
|
Use: https://img-resizer.escloud.my.id/https://avatars.githubusercontent.com/u/65361695?width=100
|
||||||
|
|||||||
+43
-16
@@ -1,43 +1,53 @@
|
|||||||
const sharp = require('sharp');
|
const sharp = require("sharp");
|
||||||
const fs = require('fs');
|
const fs = require("fs");
|
||||||
|
const axios = require("axios");
|
||||||
|
|
||||||
const resizer = async (req, res) => {
|
const resizer = async (req, res) => {
|
||||||
const { width, height, quality, format } = req.query;
|
const { width, height, quality, format } = req.query;
|
||||||
const { filename } = req.params;
|
const { filename } = req.params;
|
||||||
|
|
||||||
|
const imageUrl = req.url.startsWith("/image/resize/")
|
||||||
|
? req.url.slice(14)
|
||||||
|
: "";
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
let bufferImage;
|
||||||
|
if (imageUrl) {
|
||||||
|
bufferImage = await imageUrlToBuffer(imageUrl);
|
||||||
|
}
|
||||||
|
|
||||||
if (width) {
|
if (width) {
|
||||||
if (parseInt(width) > 5000) {
|
if (parseInt(width) > 5000) {
|
||||||
fs.unlinkSync('public/' + filename);
|
|
||||||
return res.status(400).json({
|
return res.status(400).json({
|
||||||
success: false,
|
success: false,
|
||||||
message: 'Error. Width must be <=5000',
|
message: "Error. Width must be <=5000",
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (height) {
|
if (height) {
|
||||||
if (parseInt(height) > 5000) {
|
if (parseInt(height) > 5000) {
|
||||||
fs.unlinkSync('public/' + filename);
|
|
||||||
return res.status(400).json({
|
return res.status(400).json({
|
||||||
success: false,
|
success: false,
|
||||||
message: 'Error. Height must be <=5000',
|
message: "Error. Height must be <=5000",
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (quality) {
|
if (quality) {
|
||||||
if (parseInt(quality) > 100) {
|
if (parseInt(quality) > 100) {
|
||||||
fs.unlinkSync('public/' + filename);
|
|
||||||
return res.status(400).json({
|
return res.status(400).json({
|
||||||
success: false,
|
success: false,
|
||||||
message: 'Error. Quality must be <=100',
|
message: "Error. Quality must be <=100",
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const image = sharp(`./public/${filename}`);
|
const image = sharp(bufferImage || `./public/${filename}`);
|
||||||
let formatImage = (await image.metadata()).format;
|
let formatImage = (await image.metadata()).format;
|
||||||
formatImage = format || formatImage === 'svg' ? 'png' : formatImage;
|
|
||||||
|
formatImage =
|
||||||
|
format === "svg" || formatImage === "svg" ? "png" : format || formatImage;
|
||||||
const widthImage = width ? parseInt(width) : (await image.metadata()).width;
|
const widthImage = width ? parseInt(width) : (await image.metadata()).width;
|
||||||
const heightImage = height
|
const heightImage = height
|
||||||
? parseInt(height)
|
? parseInt(height)
|
||||||
@@ -51,18 +61,35 @@ const resizer = async (req, res) => {
|
|||||||
.withMetadata()
|
.withMetadata()
|
||||||
.toBuffer();
|
.toBuffer();
|
||||||
|
|
||||||
res.setHeader('content-type', 'image');
|
res.setHeader("content-type", "image");
|
||||||
res.send(resizedImage);
|
res.send(resizedImage);
|
||||||
|
|
||||||
fs.unlinkSync('public/' + filename);
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
fs.unlinkSync('public/' + filename);
|
res.setHeader("content-type", "application/json");
|
||||||
res.setHeader('content-type', 'application/json');
|
|
||||||
res.status(500).json({
|
res.status(500).json({
|
||||||
success: false,
|
success: false,
|
||||||
message: 'Internal server error',
|
message: error?.message || "Internal server error",
|
||||||
});
|
});
|
||||||
|
} finally {
|
||||||
|
if (filename) {
|
||||||
|
fs.unlinkSync("public/" + filename);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
async function imageUrlToBuffer(imageUrl) {
|
||||||
|
try {
|
||||||
|
const response = await axios.get(imageUrl, { responseType: "arraybuffer" });
|
||||||
|
|
||||||
|
if (response.status !== 200) {
|
||||||
|
throw new Error(`HTTP error! Status: ${response.status}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const buffer = Buffer.from(response.data);
|
||||||
|
|
||||||
|
return buffer;
|
||||||
|
} catch (error) {
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
module.exports = resizer;
|
module.exports = resizer;
|
||||||
|
|||||||
@@ -15,10 +15,15 @@ app.use(bodyParser.json());
|
|||||||
app.use(bodyParser.urlencoded({ extended: false }));
|
app.use(bodyParser.urlencoded({ extended: false }));
|
||||||
app.use(express.static("public"));
|
app.use(express.static("public"));
|
||||||
|
|
||||||
|
//GET UI
|
||||||
app.get("/", async (req, res) => {
|
app.get("/", async (req, res) => {
|
||||||
res.sendFile(path.join(__dirname, "./public/index.html"));
|
res.sendFile(path.join(__dirname, "./public/index.html"));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// GET/DOWNLOAD IMAGE
|
||||||
app.get("/public/:filename", resizer);
|
app.get("/public/:filename", resizer);
|
||||||
|
|
||||||
|
//UPLOAD IMAGE
|
||||||
app.post("/", uploadMiddleware, (req, res) => {
|
app.post("/", uploadMiddleware, (req, res) => {
|
||||||
res.json({
|
res.json({
|
||||||
success: true,
|
success: true,
|
||||||
@@ -27,6 +32,9 @@ app.post("/", uploadMiddleware, (req, res) => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
//RESIZE IMG FROM URL (query-> width,height,format,quality)
|
||||||
|
app.get("/image/resize/*", resizer);
|
||||||
|
|
||||||
app.listen(PORT, () => {
|
app.listen(PORT, () => {
|
||||||
console.log(`Server running on port ${PORT}`);
|
console.log(`Server running on port ${PORT}`);
|
||||||
});
|
});
|
||||||
|
|||||||
Generated
+48
@@ -76,6 +76,21 @@
|
|||||||
"resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
|
||||||
"integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg=="
|
"integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg=="
|
||||||
},
|
},
|
||||||
|
"asynckit": {
|
||||||
|
"version": "0.4.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
|
||||||
|
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
|
||||||
|
},
|
||||||
|
"axios": {
|
||||||
|
"version": "1.6.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/axios/-/axios-1.6.7.tgz",
|
||||||
|
"integrity": "sha512-/hDJGff6/c7u0hDkvkGxR/oy6CbCs8ziCsC7SqmhjfozqiJGc8Z11wrv9z9lYfY4K8l+H9TpjcMDX0xOZmx+RA==",
|
||||||
|
"requires": {
|
||||||
|
"follow-redirects": "^1.15.4",
|
||||||
|
"form-data": "^4.0.0",
|
||||||
|
"proxy-from-env": "^1.1.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"base64-js": {
|
"base64-js": {
|
||||||
"version": "1.5.1",
|
"version": "1.5.1",
|
||||||
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
|
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
|
||||||
@@ -211,6 +226,14 @@
|
|||||||
"simple-swizzle": "^0.2.2"
|
"simple-swizzle": "^0.2.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"combined-stream": {
|
||||||
|
"version": "1.0.8",
|
||||||
|
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
|
||||||
|
"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
|
||||||
|
"requires": {
|
||||||
|
"delayed-stream": "~1.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"concat-stream": {
|
"concat-stream": {
|
||||||
"version": "1.6.2",
|
"version": "1.6.2",
|
||||||
"resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz",
|
"resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz",
|
||||||
@@ -320,6 +343,11 @@
|
|||||||
"gopd": "^1.0.1"
|
"gopd": "^1.0.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"delayed-stream": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ=="
|
||||||
|
},
|
||||||
"delegates": {
|
"delegates": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz",
|
||||||
@@ -452,6 +480,21 @@
|
|||||||
"unpipe": "~1.0.0"
|
"unpipe": "~1.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"follow-redirects": {
|
||||||
|
"version": "1.15.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.5.tgz",
|
||||||
|
"integrity": "sha512-vSFWUON1B+yAw1VN4xMfxgn5fTUiaOzAJCKBwIIgT/+7CuGy9+r+5gITvP62j3RmaD5Ph65UaERdOSRGUzZtgw=="
|
||||||
|
},
|
||||||
|
"form-data": {
|
||||||
|
"version": "4.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
|
||||||
|
"integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
|
||||||
|
"requires": {
|
||||||
|
"asynckit": "^0.4.0",
|
||||||
|
"combined-stream": "^1.0.8",
|
||||||
|
"mime-types": "^2.1.12"
|
||||||
|
}
|
||||||
|
},
|
||||||
"forwarded": {
|
"forwarded": {
|
||||||
"version": "0.2.0",
|
"version": "0.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
|
||||||
@@ -801,6 +844,11 @@
|
|||||||
"ipaddr.js": "1.9.1"
|
"ipaddr.js": "1.9.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"proxy-from-env": {
|
||||||
|
"version": "1.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
|
||||||
|
"integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="
|
||||||
|
},
|
||||||
"pump": {
|
"pump": {
|
||||||
"version": "3.0.0",
|
"version": "3.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
"author": "",
|
"author": "",
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"axios": "^1.6.7",
|
||||||
"body-parser": "^1.19.2",
|
"body-parser": "^1.19.2",
|
||||||
"dotenv": "^16.0.3",
|
"dotenv": "^16.0.3",
|
||||||
"express": "^4.17.3",
|
"express": "^4.17.3",
|
||||||
|
|||||||
Reference in New Issue
Block a user