最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to customize strapi image upload to use third party library for image compression? - Stack Overflow

programmeradmin3浏览0评论

I'm new to strapi, and im trying to find a way to press image that is uploaded to strapi which will then be served to a static gatsby site. Is there any way i can do this? I found image-pressor.js npm library but i dont know how to integrate it into strapi both for the field in each content type and for the WYSWYG editor. Can someone please help me? If possible, can we customize the it on upload to Strapi based on the display size in gatsby?

1st attempt at integrating image-pressor:

Here's my upload.js:

const Compressor = require('image-pressor')
module.exports = {
upload: async (ctx) => {
    // Retrieve provider configuration.
    const config = await strapi.store({
      environment: strapi.config.environment,
      type: 'plugin',
      name: 'upload'
    }).get({ key: 'provider' });

    // Verify if the file upload is enable.
    if (config.enabled === false) {
      strapi.log.error('File upload is disabled');
      return ctx.badRequest(null, ctx.request.admin ? [{ messages: [{ id: 'Upload.status.disabled' }] }] : 'File upload is disabled');
    }

    // Extract optional relational data.
    const { refId, ref, source, field } = ctx.request.body.fields;
    let { files = {} } = ctx.request.body.files;

    if (_.isEmpty(files)) {
      return ctx.send(true);
    }

    //integrate image-pressor library to enhance uploaded image
    var imageCompressor = new Compressor.ImageCompressor;

    var pressorSettings = {
            toWidth : 100,
            toHeight : 100,
            mimeType : 'image/png',
            mode : 'strict',
            quality : 0.6,
            grayScale : true,
            sepia : true,
            threshold : 127,
            vReverse : true,
            hReverse : true,
            speed : 'low'
        };

    files.map(file => imageCompressor.run(file, pressorSettings), () => {})

    // Transform stream files to buffer
    // const buffers = await strapi.plugins.upload.services.upload.bufferize(ctx.request.body.files.files);
    const buffers = await strapi.plugins.upload.services.upload.bufferize(files.files);
    const enhancedFiles = buffers.map(file => {
      if (file.size > config.sizeLimit) {
        return ctx.badRequest(null, ctx.request.admin ? [{ messages: [{ id: 'Upload.status.sizeLimit', values: {file: file.name} }] }] : `${file.name} file is bigger than limit size!`);
      }

      // Add details to the file to be able to create the relationships.
      if (refId && ref && field) {
        Object.assign(file, {
          related: [{
            refId,
            ref,
            source,
            field
          }]
        });
      }

      return file;
    });

    // Something is wrong (size limit)...
    if (ctx.status === 400) {
      return;
    }

    const uploadedFiles = await strapi.plugins.upload.services.upload.upload(enhancedFiles, config);

    // Send 200 `ok`
    ctx.send(uploadedFiles.map((file) => {
      // If is local server upload, add backend host as prefix
      if (file.url && file.url[0] === '/') {
        file.url = strapi.config.url + file.url;
      }

      if (_.isArray(file.related)) {
        file.related = file.related.map(obj => obj.ref || obj);
      }

      return file;
    }));
  },

and i got this error, running strapi start:

/home/mike/Desktop/clik.asia.admin/node_modules/image-pressor/image-pressor.js:295
})(window, document);
   ^

ReferenceError: window is not defined
    at Object.<anonymous> (/home/mike/Desktop/clik.asia.admin/node_modules/image-pressor/image-pressor.js:295:4)
    at Module._pile (module.js:652:30)
    at Object.Module._extensions..js (module.js:663:10)
    at Module.load (module.js:565:32)
    at tryModuleLoad (module.js:505:12)
    at Function.Module._load (module.js:497:3)
    at Module.require (module.js:596:17)
    at require (internal/module.js:11:18)
    at Object.<anonymous> (/home/mike/Desktop/clik.asia.admin/plugins/upload/controllers/Upload.js:10:20)
    at Module._pile (module.js:652:30)

I'm new to strapi, and im trying to find a way to press image that is uploaded to strapi which will then be served to a static gatsby site. Is there any way i can do this? I found image-pressor.js npm library but i dont know how to integrate it into strapi both for the field in each content type and for the WYSWYG editor. Can someone please help me? If possible, can we customize the it on upload to Strapi based on the display size in gatsby?

1st attempt at integrating image-pressor:

Here's my upload.js:

const Compressor = require('image-pressor')
module.exports = {
upload: async (ctx) => {
    // Retrieve provider configuration.
    const config = await strapi.store({
      environment: strapi.config.environment,
      type: 'plugin',
      name: 'upload'
    }).get({ key: 'provider' });

    // Verify if the file upload is enable.
    if (config.enabled === false) {
      strapi.log.error('File upload is disabled');
      return ctx.badRequest(null, ctx.request.admin ? [{ messages: [{ id: 'Upload.status.disabled' }] }] : 'File upload is disabled');
    }

    // Extract optional relational data.
    const { refId, ref, source, field } = ctx.request.body.fields;
    let { files = {} } = ctx.request.body.files;

    if (_.isEmpty(files)) {
      return ctx.send(true);
    }

    //integrate image-pressor library to enhance uploaded image
    var imageCompressor = new Compressor.ImageCompressor;

    var pressorSettings = {
            toWidth : 100,
            toHeight : 100,
            mimeType : 'image/png',
            mode : 'strict',
            quality : 0.6,
            grayScale : true,
            sepia : true,
            threshold : 127,
            vReverse : true,
            hReverse : true,
            speed : 'low'
        };

    files.map(file => imageCompressor.run(file, pressorSettings), () => {})

    // Transform stream files to buffer
    // const buffers = await strapi.plugins.upload.services.upload.bufferize(ctx.request.body.files.files);
    const buffers = await strapi.plugins.upload.services.upload.bufferize(files.files);
    const enhancedFiles = buffers.map(file => {
      if (file.size > config.sizeLimit) {
        return ctx.badRequest(null, ctx.request.admin ? [{ messages: [{ id: 'Upload.status.sizeLimit', values: {file: file.name} }] }] : `${file.name} file is bigger than limit size!`);
      }

      // Add details to the file to be able to create the relationships.
      if (refId && ref && field) {
        Object.assign(file, {
          related: [{
            refId,
            ref,
            source,
            field
          }]
        });
      }

      return file;
    });

    // Something is wrong (size limit)...
    if (ctx.status === 400) {
      return;
    }

    const uploadedFiles = await strapi.plugins.upload.services.upload.upload(enhancedFiles, config);

    // Send 200 `ok`
    ctx.send(uploadedFiles.map((file) => {
      // If is local server upload, add backend host as prefix
      if (file.url && file.url[0] === '/') {
        file.url = strapi.config.url + file.url;
      }

      if (_.isArray(file.related)) {
        file.related = file.related.map(obj => obj.ref || obj);
      }

      return file;
    }));
  },

and i got this error, running strapi start:

/home/mike/Desktop/clik.asia.admin/node_modules/image-pressor/image-pressor.js:295
})(window, document);
   ^

ReferenceError: window is not defined
    at Object.<anonymous> (/home/mike/Desktop/clik.asia.admin/node_modules/image-pressor/image-pressor.js:295:4)
    at Module._pile (module.js:652:30)
    at Object.Module._extensions..js (module.js:663:10)
    at Module.load (module.js:565:32)
    at tryModuleLoad (module.js:505:12)
    at Function.Module._load (module.js:497:3)
    at Module.require (module.js:596:17)
    at require (internal/module.js:11:18)
    at Object.<anonymous> (/home/mike/Desktop/clik.asia.admin/plugins/upload/controllers/Upload.js:10:20)
    at Module._pile (module.js:652:30)
Share Improve this question edited Aug 28, 2018 at 9:44 m5kev4n asked Aug 24, 2018 at 4:05 m5kev4nm5kev4n 5711 gold badge8 silver badges20 bronze badges 1
  • This is an open issue in the gatsby strapi plugin: strapi/gatsby-source-strapi#8 – Fabian Schultz Commented Aug 24, 2018 at 14:33
Add a ment  | 

2 Answers 2

Reset to default 5

If you want you can customize the upload service to add a custom logic (using image-pressor.js) to press your images before uploading it.

Here is the controller of /upload route: https://github./strapi/strapi/blob/master/packages/strapi-plugin-upload/controllers/Upload.js#L12

Here is the service function: https://github./strapi/strapi/blob/master/packages/strapi-plugin-upload/services/Upload.js#L56

This is currently not possible only with Strapi. I suggest you to upload your files on Cloudinary (https://github./strapi/strapi/tree/master/packages/strapi-upload-cloudinary) and use their API to resize them.

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论