Angular - Sharp keeps image processing after creating a thumbnail

Discussão em 'Angular' iniciado por Zander, Fevereiro 3, 2025.

  1. Zander

    Zander Guest

    I'm using Angular, and I have my server.js that, when uploading an image, Sharp creates a thumbnail.

    The main issue is that if later I want to delete the main image, it won't let me because something is using it.

    File not accessible: C:\Users\...\uploads\Fan-Art\test-1738586514023.jpg Error: EPERM: operation not permitted, unlink 'C:\Users\...\furwork\uploads\Fan-Art\test-1738586514023.jpg'

    Even if I try to delete the image manually, it tells me that something is using it and prevents to delete it. But if I stop the server.js I can delete it without any problem.

    I tried not to create a thumbnail, and I could delete the image accordingly without any problem, deleting it from the website and manually.

    This is my endpoint on the server.js

    app.post('/upload-submission', upload.any(), async (req, res) => {
    const folderPath = req.body.folderPath;
    const targetDir = path.join(__dirname, folderPath);
    console.log('Resolved path:', targetDir);

    if (!fs.existsSync(targetDir)) {
    console.log(`Path ${targetDir} does not exist.`);
    return res.status(400).json({ error: `Path ${targetDir} does not exist.` });
    }

    try {
    let mainFile = null;
    let additionalImages = [];

    // Process uploaded files
    for (const file of req.files) {
    const fileExt = path.extname(file.originalname);
    let fileName;

    if (file.fieldname === 'image') {
    // Handle main image
    fileName = `${req.body.fileId}${fileExt}`;
    mainFile = {
    path: path.join(folderPath, fileName)
    };
    } else if (file.fieldname.startsWith('image-')) {
    // Handle additional images
    fileName = `${req.body.fileId}-${file.fieldname}${fileExt}`;
    additionalImages.push({
    path: path.join(folderPath, fileName)
    });
    } else {
    continue;
    }

    // Move file to target directory
    const uploadedFilePath = path.join(targetDir, fileName);
    await fs.promises.rename(file.path, uploadedFilePath);
    }

    if (!mainFile) {
    return res.status(400).json({ error: 'Main image is required.' });
    }

    // Generate the thumbnail and ensure it finishes before proceeding
    const thumbnailName = `thumb-${path.basename(mainFile.path)}`;
    const thumbnailPath = path.join(targetDir, thumbnailName);

    try {
    // This ensures the Sharp process finishes before continuing
    await sharp(path.join(targetDir, path.basename(mainFile.path)))
    .resize(150, 150)
    .toFile(thumbnailPath);
    console.log("Thumbnail created successfully.");
    } catch (err) {
    console.error('Error creating thumbnail:', err);
    throw new Error('Error creating thumbnail');
    }

    // Add metadata
    const metadata = {
    path: mainFile.path,
    thumbnail: path.join(folderPath, thumbnailName),
    title: req.body.title,
    description: req.body.description,
    rating: req.body.rating,
    keywords: JSON.parse(req.body.keywords),
    id: req.body.fileId,
    price: req.body.price,
    additionalImages: additionalImages // Store array of additional images
    };

    const jsonFilePath = path.join(targetDir, 'images.json');
    let images = [];

    try {
    const data = await fs.promises.readFile(jsonFilePath, 'utf8');
    images = JSON.parse(data);
    } catch (readErr) {
    if (readErr.code !== 'ENOENT') {
    console.log('Error parsing images.json');
    return res.status(500).json({ error: 'Error parsing images.json' });
    }
    }

    images.unshift(metadata);
    await fs.promises.writeFile(jsonFilePath, JSON.stringify(images, null, 2));

    // Add a small delay to ensure the file handle is released
    setTimeout(() => {
    res.status(200).json({ message: 'Images uploaded successfully', metadata });
    }, 1000); // Delay of 1000ms to allow file handle to be released

    } catch (err) {
    console.error('An error occurred:', err);
    res.status(500).json({ error: 'An error occurred during the upload process.' });
    }
    });

    Versions using:
    "express": "^4.21.1",
    "axios": "^1.7.8",
    "sharp": "^0.33.5",
    "multer": "^1.4.5-lts.1",
    "@angular/core": "^18.2.0",

    Hope you can help me with this!

    Continue reading...

Compartilhe esta Página