diff --git a/browser.js b/browser.js new file mode 100644 index 0000000..fc9deb3 --- /dev/null +++ b/browser.js @@ -0,0 +1,6 @@ +const decode = require('heic-decode'); +const formats = require('./formats-browser.js'); +const { one, all } = require('./lib.js')(decode, formats); + +module.exports = one; +module.exports.all = all; diff --git a/formats-browser.js b/formats-browser.js new file mode 100644 index 0000000..3092ac0 --- /dev/null +++ b/formats-browser.js @@ -0,0 +1,40 @@ +module.exports = {}; + +const initializeCanvas = ({ data, width, height }) => { + const canvas = document.createElement('canvas'); + canvas.width = width; + canvas.height = height; + const ctx = canvas.getContext('2d'); + + const imageData = new ImageData(data, width, height); + + ctx.putImageData(imageData, 0, 0); + + return canvas; +}; + +const convert = async ({ data, width, height }, ...blobArgs) => { + const canvas = initializeCanvas({ data, width, height }); + + const blob = await new Promise((resolve, reject) => { + canvas.toBlob(blob => { + if (blob) { + return resolve(blob); + } + + return reject(new Error('failed to convert the image')); + }, ...blobArgs); + }); + + const arrayBuffer = await blob.arrayBuffer(); + + return new Uint8Array(arrayBuffer); +}; + +module.exports.JPEG = async ({ data, width, height, quality }) => { + return convert({ data, width, height }, 'image/jpeg', quality); +}; + +module.exports.PNG = async ({ data, width, height }) => { + return convert({ data, width, height }, 'image/png'); +}; diff --git a/package.json b/package.json index 1f51608..f80fce8 100644 --- a/package.json +++ b/package.json @@ -28,10 +28,12 @@ "homepage": "https://github.com/catdad-experiments/heic-convert#readme", "devDependencies": { "buffer-to-uint8array": "^1.1.0", + "canvas": "^2.11.2", "chai": "^4.2.0", "eslint": "^5.16.0", "file-type": "^13.1.0", "fs-extra": "^8.1.0", + "jsdom": "^22.1.0", "mocha": "^7.0.0", "node-fetch": "^2.6.0", "pixelmatch": "^5.2.1", diff --git a/test/browser.test.js b/test/browser.test.js new file mode 100644 index 0000000..6f1cf63 --- /dev/null +++ b/test/browser.test.js @@ -0,0 +1,41 @@ +const JSDOM = require('jsdom').JSDOM; +const canvas = require('canvas'); +const runTests = require('./run-tests.js'); + +describe('heic-convert (browser)', () => { + before(() => { + const { window } = new JSDOM(``, { + pretendToBeVisual: true + }); + + global.window = window; + global.document = window.document; + global.ImageData = canvas.ImageData; + + // okay, now we are getting hacky... jsdom folks got into a + // fight when talking about implementing this spec, which + // is now broadly supported across all evergreen browsers + // https://github.com/jsdom/jsdom/issues/2555 + global.window.Blob.prototype.arrayBuffer = async function() { + const blob = this; + const fileReader = new window.FileReader(); + + var arrayBuffer = new Promise(r => { + fileReader.onload = function(event) { + r(event.target.result); + }; + + fileReader.readAsArrayBuffer(blob); + }); + + return arrayBuffer; + }; + }); + + after(() => { + global.window.close(); + delete global.window; + }); + + runTests(require('../browser')); +});