Skip to content

Commit

Permalink
adding a browser implementation using canvas to encode the resulting …
Browse files Browse the repository at this point in the history
…image
  • Loading branch information
catdad committed Nov 28, 2023
1 parent 2a3d82d commit b49f183
Show file tree
Hide file tree
Showing 4 changed files with 89 additions and 0 deletions.
6 changes: 6 additions & 0 deletions browser.js
Original file line number Diff line number Diff line change
@@ -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;
40 changes: 40 additions & 0 deletions formats-browser.js
Original file line number Diff line number Diff line change
@@ -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');
};
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
41 changes: 41 additions & 0 deletions test/browser.test.js
Original file line number Diff line number Diff line change
@@ -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'));
});

0 comments on commit b49f183

Please sign in to comment.