Skip to content

Commit 4f4b5a1

Browse files
committed
New: Support for HEIC image format
1 parent e56a026 commit 4f4b5a1

7 files changed

Lines changed: 106 additions & 7 deletions

File tree

CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
1212
- Support for `JP2` image format [`e11046b`](https://github.com/ollm/OpenComic/commit/e11046b4eca758f8b15c1caeb831a235a5f3d62c)
1313
- Support for `JXR` image format [`0e24922`](https://github.com/ollm/OpenComic/commit/0e2492264e1dbc94126c7d79e3e3c50fc426846c)
1414
- Support for `JXL` image format [`bd6fb0a`](https://github.com/ollm/OpenComic/commit/bd6fb0a8c8be3685b48c88fa21bbe2d3c384a491)
15-
- Thumbnail generation speed has been improved
15+
- Thumbnail generation speed has been improved [`155f064`](https://github.com/ollm/OpenComic/commit/155f064b4c9716c050a6231e44323169686997ea)
16+
- Support for `HEIC` image format
1617

1718

1819
## [v1.4.1](https://github.com/ollm/OpenComic/releases/tag/v1.4.1) (08-02-2025)

package-lock.json

Lines changed: 22 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@
8686
"fs-extra": "^11.3.0",
8787
"gm": "^1.25.0",
8888
"handlebars": "^4.7.8",
89+
"heic-decode": "^2.0.0",
8990
"image-size": "^1.2.0",
9091
"jimp": "^1.6.0",
9192
"jpegxr": "^0.3.0",

scripts/image.js

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
var sharp = false, jimp = false, imageMagick = false, graphicsMagick = false, imageSize = false;
1+
var sharp = false, jimp = false, imageMagick = false, graphicsMagick = false, imageSize = false, heic = false;
22

33
async function resize(fromImage, toImage, config = {})
44
{
@@ -384,7 +384,21 @@ async function getSizes(images)
384384
{
385385
const extension = fileExtension(image.image);
386386

387-
if(inArray(extension, imageExtensions.jp2))
387+
if(inArray(extension, imageExtensions.heic))
388+
{
389+
if(heic === false)
390+
heic = require('heic-decode');
391+
392+
const buffer = await fsp.readFile(image.image);
393+
const images = await heic.all({buffer});
394+
const properties = images[0] || {width: 1, height: 1};
395+
396+
size = {
397+
width: properties.width,
398+
height: properties.height,
399+
};
400+
}
401+
else if(inArray(extension, imageExtensions.jp2))
388402
{
389403
if(pdfjsDecoders === false)
390404
await loadPdfjsDecoders();

scripts/opencomic.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,10 @@ var compatibleMime = [
155155
'image/webp',
156156
'image/avif',
157157
'image/avif-sequence',
158+
'image/heic',
159+
'image/heif',
160+
'image/heic-sequence',
161+
'image/heif-sequence',
158162
];
159163

160164
// This image formats requires conversion to Blob to be displayed
@@ -165,6 +169,11 @@ var blobMime = [
165169
'image/jpm',
166170
// jxl
167171
'image/jxl',
172+
// heic
173+
'image/heic',
174+
'image/heif',
175+
'image/heic-sequence',
176+
'image/heif-sequence',
168177
];
169178

170179
// This image formats requires conversion to PNG to be displayed
@@ -301,6 +310,8 @@ var imageExtensions = {
301310
'webp',
302311
'avif',
303312
'avifs',
313+
'heic',
314+
'heif',
304315
],
305316
blob: [ // This image formats requires conversion to Blob to be displayed
306317
// jp2
@@ -314,6 +325,9 @@ var imageExtensions = {
314325
'jpx',
315326
// jxl
316327
'jxl',
328+
// heic
329+
'heic',
330+
'heif',
317331
],
318332
convert: [ // This image formats requires conversion to PNG to be displayed
319333
// jxr
@@ -374,6 +388,10 @@ var imageExtensions = {
374388
'avif',
375389
'avifs',
376390
],
391+
heic: [
392+
'heic',
393+
'heif',
394+
],
377395
};
378396

379397
var compatibleImageExtensions = [

scripts/worker/convert-image.js

Lines changed: 45 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
const fs = require('fs');
22

3-
var jpegxr = false;
3+
var jpegxr = false, heic = false;
44

55
async function jp2(path)
66
{
@@ -69,7 +69,6 @@ async function jxr(path)
6969
bitsString: pixelInfo.bitDepth,
7070
bitsPerPixel: pixelInfo.bitsPerPixel,
7171
premultiplied: pixelInfo.premultipledAlpha,
72-
pixelInfo: pixelInfo,
7372
removeAlpha: true,
7473
};
7574
}
@@ -111,6 +110,41 @@ async function jxl(path)
111110
return false;
112111
}
113112

113+
async function _heic(path)
114+
{
115+
const buffer = fs.readFileSync(path);
116+
117+
if(heic === false)
118+
heic = require('heic-decode');
119+
120+
try
121+
{
122+
const image = await heic({buffer});
123+
124+
const len = image.data.length;
125+
126+
const width = image.width;
127+
const height = image.height;
128+
129+
const channels = Math.round(len / (width * height));
130+
131+
return {
132+
buffer: image.data,
133+
width: width,
134+
height: height,
135+
length: len,
136+
channels: channels,
137+
bits: channels > 4 ? 16 : 8,
138+
};
139+
}
140+
catch(error)
141+
{
142+
return {error: error};
143+
}
144+
145+
return false;
146+
}
147+
114148
async function convert(path, mime)
115149
{
116150
switch (mime)
@@ -133,6 +167,15 @@ async function convert(path, mime)
133167
return jxl(path);
134168

135169
break;
170+
case 'image/heic':
171+
case 'image/heif':
172+
case 'image/heic-sequence':
173+
case 'image/heif-sequence':
174+
175+
return _heic(path);
176+
177+
break;
178+
136179
}
137180

138181
return false;

scripts/workers.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -245,7 +245,7 @@ async function convertImage(path, options = {})
245245
{
246246
const bits = result.bits;
247247

248-
if(bits > 8 && result.buffer instanceof Uint8Array)
248+
if(bits > 8 && (result.buffer instanceof Uint8Array || result.buffer instanceof Uint8ClampedArray))
249249
result.buffer = convertBuffer(result.buffer, bits, result.bitsString);
250250

251251
const raw = {
@@ -300,7 +300,7 @@ async function convertImageToBlob(path, options = {})
300300
{
301301
const bits = result.bits;
302302

303-
if(bits > 8 && result.buffer instanceof Uint8Array)
303+
if(bits > 8 && (result.buffer instanceof Uint8Array || result.buffer instanceof Uint8ClampedArray))
304304
result.buffer = convertBuffer(result.buffer, bits, result.bitsString);
305305

306306
const raw = {

0 commit comments

Comments
 (0)