ext.js 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. const fs = require('fs-extra')
  2. const os = require('os')
  3. const path = require('path')
  4. const util = require('util')
  5. const exec = util.promisify(require('child_process').exec)
  6. const { pipeline } = require('stream/promises')
  7. module.exports = {
  8. key: 'sharp',
  9. title: 'Sharp',
  10. description: 'Process and transform images. Required to generate thumbnails of uploaded images and perform transformations.',
  11. async isCompatible () {
  12. return os.arch() === 'x64'
  13. },
  14. isInstalled: false,
  15. isInstallable: true,
  16. async check () {
  17. this.isInstalled = await fs.pathExists(path.join(WIKI.SERVERPATH, 'node_modules/sharp/wiki_installed.txt'))
  18. return this.isInstalled
  19. },
  20. async install () {
  21. try {
  22. const { stdout, stderr } = await exec('node install/libvips && node install/dll-copy', {
  23. cwd: path.join(WIKI.SERVERPATH, 'node_modules/sharp'),
  24. timeout: 120000,
  25. windowsHide: true
  26. })
  27. await fs.ensureFile(path.join(WIKI.SERVERPATH, 'node_modules/sharp/wiki_installed.txt'))
  28. this.isInstalled = true
  29. WIKI.logger.info(stdout)
  30. WIKI.logger.warn(stderr)
  31. } catch (err) {
  32. WIKI.logger.error(err)
  33. }
  34. },
  35. sharp: null,
  36. async load () {
  37. if (!this.sharp) {
  38. this.sharp = require('sharp')
  39. }
  40. },
  41. /**
  42. * RESIZE IMAGE
  43. */
  44. async resize ({
  45. format = 'png',
  46. inputStream = null,
  47. inputPath = null,
  48. outputStream = null,
  49. outputPath = null,
  50. width = null,
  51. height = null,
  52. fit = 'cover',
  53. background = { r: 0, g: 0, b: 0, alpha: 0 },
  54. kernel = 'lanczos3'
  55. }) {
  56. this.load()
  57. if (inputPath) {
  58. inputStream = fs.createReadStream(inputPath)
  59. }
  60. if (!inputStream) {
  61. throw new Error('Failed to open readable input stream for image resizing.')
  62. }
  63. if (outputPath) {
  64. outputStream = fs.createWriteStream(outputPath)
  65. }
  66. if (!outputStream) {
  67. throw new Error('Failed to open writable output stream for image resizing.')
  68. }
  69. if (format === 'svg') {
  70. return pipeline([inputStream, outputStream])
  71. } else {
  72. const transformer = this.sharp().resize({
  73. width,
  74. height,
  75. fit,
  76. background,
  77. kernel
  78. }).toFormat(format)
  79. return pipeline([inputStream, transformer, outputStream])
  80. }
  81. }
  82. }