Skip to content

Commit

Permalink
All the encoders that Chrome/Safari/Firefox support out of the box. (#74
Browse files Browse the repository at this point in the history
)

* All the encoders that Chrome/Safari/Firefox support out of the box.

* Typo
  • Loading branch information
jakearchibald authored Jul 2, 2018
1 parent 807a76d commit 3867448
Show file tree
Hide file tree
Showing 10 changed files with 134 additions and 11 deletions.
16 changes: 16 additions & 0 deletions src/codecs/browser-bmp/encoder.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { canvasEncode } from '../../lib/util';
import { canvasEncodeTest } from '../generic/util';

export interface EncodeOptions { }
export interface EncoderState { type: typeof type; options: EncodeOptions; }

export const type = 'browser-bmp';
export const label = 'Browser BMP';
export const mimeType = 'image/bmp';
export const extension = 'bmp';
export const defaultOptions: EncodeOptions = {};
export const featureTest = () => canvasEncodeTest(mimeType);

export function encode(data: ImageData, options: EncodeOptions) {
return canvasEncode(data, mimeType);
}
16 changes: 16 additions & 0 deletions src/codecs/browser-gif/encoder.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { canvasEncode } from '../../lib/util';
import { canvasEncodeTest } from '../generic/util';

export interface EncodeOptions {}
export interface EncoderState { type: typeof type; options: EncodeOptions; }

export const type = 'browser-gif';
export const label = 'Browser GIF';
export const mimeType = 'image/gif';
export const extension = 'gif';
export const defaultOptions: EncodeOptions = {};
export const featureTest = () => canvasEncodeTest(mimeType);

export function encode(data: ImageData, options: EncodeOptions) {
return canvasEncode(data, mimeType);
}
16 changes: 16 additions & 0 deletions src/codecs/browser-jp2/encoder.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { canvasEncode } from '../../lib/util';
import { canvasEncodeTest } from '../generic/util';

export interface EncodeOptions { }
export interface EncoderState { type: typeof type; options: EncodeOptions; }

export const type = 'browser-jp2';
export const label = 'Browser JPEG 2000';
export const mimeType = 'image/jp2';
export const extension = 'jp2';
export const defaultOptions: EncodeOptions = {};
export const featureTest = () => canvasEncodeTest(mimeType);

export function encode(data: ImageData, options: EncodeOptions) {
return canvasEncode(data, mimeType);
}
16 changes: 16 additions & 0 deletions src/codecs/browser-pdf/encoder.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { canvasEncode } from '../../lib/util';
import { canvasEncodeTest } from '../generic/util';

export interface EncodeOptions { }
export interface EncoderState { type: typeof type; options: EncodeOptions; }

export const type = 'browser-pdf';
export const label = 'Browser PDF';
export const mimeType = 'application/pdf';
export const extension = 'pdf';
export const defaultOptions: EncodeOptions = {};
export const featureTest = () => canvasEncodeTest(mimeType);

export function encode(data: ImageData, options: EncodeOptions) {
return canvasEncode(data, mimeType);
}
16 changes: 16 additions & 0 deletions src/codecs/browser-tiff/encoder.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { canvasEncode } from '../../lib/util';
import { canvasEncodeTest } from '../generic/util';

export interface EncodeOptions { }
export interface EncoderState { type: typeof type; options: EncodeOptions; }

export const type = 'browser-tiff';
export const label = 'Browser TIFF';
export const mimeType = 'image/tiff';
export const extension = 'tiff';
export const defaultOptions: EncodeOptions = {};
export const featureTest = () => canvasEncodeTest(mimeType);

export function encode(data: ImageData, options: EncodeOptions) {
return canvasEncode(data, mimeType);
}
11 changes: 2 additions & 9 deletions src/codecs/browser-webp/encoder.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { canvasEncode } from '../../lib/util';
import { canvasEncodeTest } from '../generic/util';

export interface EncodeOptions { quality: number; }
export interface EncoderState { type: typeof type; options: EncodeOptions; }
Expand All @@ -8,15 +9,7 @@ export const label = 'Browser WebP';
export const mimeType = 'image/webp';
export const extension = 'webp';
export const defaultOptions: EncodeOptions = { quality: 0.5 };

export async function featureTest() {
const data = new ImageData(1, 1);
const blob = await encode(data, defaultOptions);
// According to the spec, the blob should be null if the format isn't supported…
if (!blob) return false;
// …but Safari falls back to PNG, so we need to check the mime type.
return blob.type === mimeType;
}
export const featureTest = () => canvasEncodeTest(mimeType);

export function encode(data: ImageData, { quality }: EncodeOptions) {
return canvasEncode(data, mimeType, quality);
Expand Down
20 changes: 18 additions & 2 deletions src/codecs/encoders.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,26 @@ import * as identity from './identity/encoder';
import * as browserPNG from './browser-png/encoder';
import * as browserJPEG from './browser-jpeg/encoder';
import * as browserWebP from './browser-webp/encoder';
import * as browserGIF from './browser-gif/encoder';
import * as browserTIFF from './browser-tiff/encoder';
import * as browserJP2 from './browser-jp2/encoder';
import * as browserBMP from './browser-bmp/encoder';
import * as browserPDF from './browser-pdf/encoder';

export interface EncoderSupportMap {
[key: string]: boolean;
}

export type EncoderState =
identity.EncoderState | mozJPEG.EncoderState | browserPNG.EncoderState |
browserJPEG.EncoderState | browserWebP.EncoderState;
browserJPEG.EncoderState | browserWebP.EncoderState | browserGIF.EncoderState |
browserTIFF.EncoderState | browserJP2.EncoderState | browserBMP.EncoderState |
browserPDF.EncoderState;
export type EncoderOptions =
identity.EncodeOptions | mozJPEG.EncodeOptions | browserPNG.EncodeOptions |
browserJPEG.EncodeOptions | browserWebP.EncodeOptions;
browserJPEG.EncodeOptions | browserWebP.EncodeOptions | browserGIF.EncodeOptions |
browserTIFF.EncodeOptions | browserJP2.EncodeOptions | browserBMP.EncodeOptions |
browserPDF.EncodeOptions;
export type EncoderType = keyof typeof encoderMap;

export const encoderMap = {
Expand All @@ -22,6 +31,13 @@ export const encoderMap = {
[browserPNG.type]: browserPNG,
[browserJPEG.type]: browserJPEG,
[browserWebP.type]: browserWebP,
// Safari & Firefox only:
[browserBMP.type]: browserBMP,
// Safari only:
[browserGIF.type]: browserGIF,
[browserTIFF.type]: browserTIFF,
[browserJP2.type]: browserJP2,
[browserPDF.type]: browserPDF,
};

export const encoders = Array.from(Object.values(encoderMap));
Expand Down
13 changes: 13 additions & 0 deletions src/codecs/generic/util.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { canvasEncode } from '../../lib/util';

export async function canvasEncodeTest(mimeType: string) {
try {
const blob = await canvasEncode(new ImageData(1, 1), mimeType);
// According to the spec, the blob should be null if the format isn't supported…
if (!blob) return false;
// …but Safari & Firefox fall back to PNG, so we need to check the mime type.
return blob.type === mimeType;
} catch (err) {
return false;
}
}
10 changes: 10 additions & 0 deletions src/components/app/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@ import * as identity from '../../codecs/identity/encoder';
import * as browserPNG from '../../codecs/browser-png/encoder';
import * as browserJPEG from '../../codecs/browser-jpeg/encoder';
import * as browserWebP from '../../codecs/browser-webp/encoder';
import * as browserGIF from '../../codecs/browser-gif/encoder';
import * as browserTIFF from '../../codecs/browser-tiff/encoder';
import * as browserJP2 from '../../codecs/browser-jp2/encoder';
import * as browserBMP from '../../codecs/browser-bmp/encoder';
import * as browserPDF from '../../codecs/browser-pdf/encoder';
import {
EncoderState,
EncoderType,
Expand Down Expand Up @@ -62,6 +67,11 @@ async function compressImage(
case browserPNG.type: return browserPNG.encode(source.data, encodeData.options);
case browserJPEG.type: return browserJPEG.encode(source.data, encodeData.options);
case browserWebP.type: return browserWebP.encode(source.data, encodeData.options);
case browserGIF.type: return browserGIF.encode(source.data, encodeData.options);
case browserTIFF.type: return browserTIFF.encode(source.data, encodeData.options);
case browserJP2.type: return browserJP2.encode(source.data, encodeData.options);
case browserBMP.type: return browserBMP.encode(source.data, encodeData.options);
case browserPDF.type: return browserPDF.encode(source.data, encodeData.options);
default: throw Error(`Unexpected encoder ${JSON.stringify(encodeData)}`);
}
})();
Expand Down
11 changes: 11 additions & 0 deletions src/components/options/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@ import * as identity from '../../codecs/identity/encoder';
import * as browserPNG from '../../codecs/browser-png/encoder';
import * as browserJPEG from '../../codecs/browser-jpeg/encoder';
import * as browserWebP from '../../codecs/browser-webp/encoder';
import * as browserGIF from '../../codecs/browser-gif/encoder';
import * as browserTIFF from '../../codecs/browser-tiff/encoder';
import * as browserJP2 from '../../codecs/browser-jp2/encoder';
import * as browserBMP from '../../codecs/browser-bmp/encoder';
import * as browserPDF from '../../codecs/browser-pdf/encoder';
import {
EncoderState,
EncoderType,
Expand All @@ -25,6 +30,12 @@ const encoderOptionsComponentMap = {
[browserPNG.type]: undefined,
[browserJPEG.type]: BrowserJPEGEncoderOptions,
[browserWebP.type]: BrowserWebPEncoderOptions,
[browserBMP.type]: undefined,
// Only Safari supports the rest, and it doesn't support quality settings.
[browserGIF.type]: undefined,
[browserTIFF.type]: undefined,
[browserJP2.type]: undefined,
[browserPDF.type]: undefined,
};

interface Props {
Expand Down

0 comments on commit 3867448

Please sign in to comment.