Skip to content

Commit d7a0322

Browse files
Merge pull request #59 from Jonniie/feature/image-optimization
Added image optimization using Sharp.js
2 parents e095adf + 41903e5 commit d7a0322

File tree

4 files changed

+774
-3
lines changed

4 files changed

+774
-3
lines changed

index.js

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,27 @@ function createApp(dependencies = {}) {
3333
app.use(express.json());
3434
const express = require('express');
3535
const cors = require('cors');
36+
const multer = require('multer');
37+
const path = require('path');
38+
const fs = require('fs');
39+
const sharp = require('sharp');
40+
const app = express();
41+
const port = 3000;
42+
43+
const uploadDir = path.join(__dirname, 'uploads');
44+
if (!fs.existsSync(uploadDir)) {
45+
fs.mkdirSync(uploadDir, { recursive: true });
46+
}
47+
48+
const storage = multer.diskStorage({
49+
destination: (req, file, cb) => cb(null, uploadDir),
50+
filename: (req, file, cb) => cb(null, `${Date.now()}_${file.originalname}`)
51+
});
52+
const upload = multer({ storage });
53+
54+
app.use(cors());
55+
app.use(express.json());
56+
app.use('/uploads', express.static(path.join(__dirname, 'uploads')));
3657
const {
3758
createConditionProofService,
3859
ConditionProofError,
@@ -504,6 +525,56 @@ app.post('/api/asset/:id/metadata', async (req, res) => {
504525
}
505526
});
506527

528+
app.post('/api/images/optimize', upload.single('image'), async (req, res) => {
529+
try {
530+
if (!req.file) {
531+
return res.status(400).json({ error: 'No image file provided' });
532+
}
533+
534+
const { width = 300, height = 300 } = req.query;
535+
const inputPath = req.file.path;
536+
const filename = path.basename(req.file.originalname, path.extname(req.file.originalname));
537+
const outputFilename = `${filename}_${width}x${height}.webp`;
538+
const optimizedDir = path.join(__dirname, 'uploads', 'optimized');
539+
540+
if (!fs.existsSync(optimizedDir)) {
541+
fs.mkdirSync(optimizedDir, { recursive: true });
542+
}
543+
544+
const outputPath = path.join(optimizedDir, outputFilename);
545+
546+
await sharp(inputPath)
547+
.resize(parseInt(width), parseInt(height), { fit: 'cover' })
548+
.toFormat('webp', { quality: 80 })
549+
.toFile(outputPath);
550+
551+
res.json({
552+
success: true,
553+
original: req.file.filename,
554+
optimized: outputFilename,
555+
path: `/uploads/optimized/${outputFilename}`
556+
});
557+
} catch (error) {
558+
res.status(500).json({ error: error.message });
559+
}
560+
});
561+
562+
app.get('/api/images/optimize/:filename', async (req, res) => {
563+
try {
564+
const filename = req.params.filename;
565+
const filePath = path.join(__dirname, 'uploads', 'optimized', filename);
566+
567+
if (!fs.existsSync(filePath)) {
568+
return res.status(404).json({ error: 'Image not found' });
569+
}
570+
571+
res.set('Content-Type', 'image/webp');
572+
res.sendFile(filePath);
573+
} catch (error) {
574+
res.status(500).json({ error: error.message });
575+
}
576+
});
577+
507578
app.put('/api/asset/:id/metadata', async (req, res) => {
508579
try {
509580
const { id } = req.params;

0 commit comments

Comments
 (0)