Skip to content

Commit

Permalink
feat: Added the ability to skip EXIF data during image encoding
Browse files Browse the repository at this point in the history
  • Loading branch information
yegor-pelykh committed Jul 15, 2024
1 parent 861db9a commit 661552d
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 10 deletions.
7 changes: 7 additions & 0 deletions src/formats/encoder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,13 @@ export interface EncoderEncodeOptions {
* If false or undefined, all frames of the image will be encoded if the encoder supports animation.
*/
singleFrame?: boolean;

/**
* Determines if EXIF metadata should be skipped during encoding.
* - true: EXIF metadata will be skipped.
* - false or undefined: EXIF metadata will be included in the encoded image.
*/
skipExif?: boolean;
}

/**
Expand Down
23 changes: 14 additions & 9 deletions src/formats/jpeg-encoder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,6 @@ import { MemoryImage } from '../image/image.js';
import { Encoder, EncoderEncodeOptions } from './encoder.js';
import { JpegMarker } from './jpeg/jpeg-marker.js';

/**
* Object interface for specifying JpegEncoder.encode parameters.
*/
export interface JpegEncoderEncodeOptions extends EncoderEncodeOptions {
/** Chroma (sub)sampling format for JPEG encoding. */
chroma?: JpegChroma;
}

/**
* JPEG Chroma (sub)sampling format.
*/
Expand All @@ -28,6 +20,16 @@ export enum JpegChroma {
yuv420,
}

/**
* Interface representing the options for the JpegEncoder.encode method.
*/
export interface JpegEncoderEncodeOptions extends EncoderEncodeOptions {
/**
* Chroma subsampling format used in JPEG encoding.
*/
chroma?: JpegChroma;
}

/**
* Encode an image to the JPEG format.
*/
Expand Down Expand Up @@ -932,6 +934,7 @@ export class JpegEncoder implements Encoder {
* @returns {Uint8Array} The encoded JPEG image as a Uint8Array.
*/
public encode(opt: JpegEncoderEncodeOptions): Uint8Array {
const skipExif = opt.skipExif ?? false;
const image = opt.image;
const chroma = opt.chroma ?? JpegChroma.yuv444;

Expand All @@ -942,7 +945,9 @@ export class JpegEncoder implements Encoder {
// Add JPEG headers
JpegEncoder.writeMarker(fp, JpegMarker.soi);
JpegEncoder.writeAPP0(fp);
JpegEncoder.writeAPP1(fp, image.exifData);
if (!skipExif) {
JpegEncoder.writeAPP1(fp, image.exifData);
}
this.writeDQT(fp);
JpegEncoder.writeSOF0(fp, image.width, image.height, chroma);
JpegEncoder.writeDHT(fp);
Expand Down
3 changes: 2 additions & 1 deletion src/formats/tiff-encoder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ export class TiffEncoder implements Encoder {
* @returns {Uint8Array} The encoded image.
*/
public encode(opt: EncoderEncodeOptions): Uint8Array {
const skipExif = opt.skipExif ?? false;
let image = opt.image;

const out = new OutputBuffer();
Expand All @@ -61,7 +62,7 @@ export class TiffEncoder implements Encoder {
// structure).

const exif = new ExifData();
if (image.exifData.size > 0) {
if (image.exifData.size > 0 && !skipExif) {
exif.imageIfd.copyFrom(image.exifData.imageIfd);
}

Expand Down
15 changes: 15 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -521,6 +521,13 @@ export interface EncodeOptions {
* The image to be encoded.
*/
image: MemoryImage;

/**
* Determines if EXIF metadata should be skipped during encoding.
* - true: EXIF metadata will be skipped.
* - false or undefined: EXIF metadata will be included in the encoded image.
*/
skipExif?: boolean;
}

/**
Expand Down Expand Up @@ -1007,12 +1014,14 @@ export function decodeNamedImage(
export function encodeImageByMimeType(
opt: EncodeImageByMimeTypeOptions
): Uint8Array | undefined {
const skipExif = opt.skipExif ?? false;
const encoder = findEncoderForMimeType(opt.mimeType);
if (encoder === undefined) {
return undefined;
}
return encoder.encode({
image: opt.image,
skipExif: skipExif,
});
}

Expand All @@ -1029,12 +1038,14 @@ export function encodeImageByMimeType(
export function encodeNamedImage(
opt: EncodeNamedImageOptions
): Uint8Array | undefined {
const skipExif = opt.skipExif ?? false;
const encoder = findEncoderForNamedImage(opt.name);
if (encoder === undefined) {
return undefined;
}
return encoder.encode({
image: opt.image,
skipExif: skipExif,
});
}

Expand Down Expand Up @@ -1062,11 +1073,13 @@ export function decodeJpg(opt: DecodeOptions): MemoryImage | undefined {
* @returns {Uint8Array} The encoded image bytes.
*/
export function encodeJpg(opt: EncodeJpgOptions): Uint8Array {
const skipExif = opt.skipExif ?? false;
const quality = opt.quality ?? 100;
const chroma = opt.chroma ?? JpegChroma.yuv444;
return new JpegEncoder(quality).encode({
image: opt.image,
chroma: chroma,
skipExif: skipExif,
});
}

Expand Down Expand Up @@ -1288,9 +1301,11 @@ export function decodeTiff(
*/
export function encodeTiff(opt: EncodeAnimatedOptions): Uint8Array {
const singleFrame = opt.singleFrame ?? false;
const skipExif = opt.skipExif ?? false;
return new TiffEncoder().encode({
image: opt.image,
singleFrame: singleFrame,
skipExif: skipExif,
});
}

Expand Down

0 comments on commit 661552d

Please sign in to comment.