Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Merged
merged 2 commits into from
Jul 2, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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