Refactor preprocessors module

This commit is contained in:
Surma
2018-08-01 12:32:29 +01:00
parent dce4fc70ac
commit c550fe9283
7 changed files with 63 additions and 70 deletions

View File

@@ -10,8 +10,6 @@ import * as browserJP2 from './browser-jp2/encoder';
import * as browserBMP from './browser-bmp/encoder'; import * as browserBMP from './browser-bmp/encoder';
import * as browserPDF from './browser-pdf/encoder'; import * as browserPDF from './browser-pdf/encoder';
import * as quantizer from './imagequant/quantizer';
export interface EncoderSupportMap { export interface EncoderSupportMap {
[key: string]: boolean; [key: string]: boolean;
} }
@@ -28,13 +26,6 @@ export type EncoderOptions =
browserPDF.EncodeOptions; browserPDF.EncodeOptions;
export type EncoderType = keyof typeof encoderMap; export type EncoderType = keyof typeof encoderMap;
export interface Enableable {
enabled: boolean;
}
export interface PreprocessorState {
quantizer: Enableable & quantizer.QuantizeOptions;
}
export const encoderMap = { export const encoderMap = {
[identity.type]: identity, [identity.type]: identity,
[mozJPEG.type]: mozJPEG, [mozJPEG.type]: mozJPEG,

View File

@@ -1,18 +1,10 @@
import { h, Component } from 'preact'; import { h, Component } from 'preact';
import { bind } from '../../lib/util'; import { bind, inputFieldValueAsNumber } from '../../lib/util';
// import * as styles from './styles.scss';
import { QuantizeOptions } from './quantizer'; import { QuantizeOptions } from './quantizer';
type Props = { interface Props {
options: QuantizeOptions, options: QuantizeOptions;
onChange(newOptions: QuantizeOptions): void, onChange(newOptions: QuantizeOptions): void;
};
/**
* @param field An HTMLInputElement, but the casting is done here to tidy up onChange.
*/
function fieldValueAsNumber(field: any): number {
return Number((field as HTMLInputElement).value);
} }
export default class QuantizerOptions extends Component<Props, {}> { export default class QuantizerOptions extends Component<Props, {}> {
@@ -21,8 +13,8 @@ export default class QuantizerOptions extends Component<Props, {}> {
const form = (event.currentTarget as HTMLInputElement).closest('form') as HTMLFormElement; const form = (event.currentTarget as HTMLInputElement).closest('form') as HTMLFormElement;
const options: QuantizeOptions = { const options: QuantizeOptions = {
maxNumColors: fieldValueAsNumber(form.maxNumColors), maxNumColors: inputFieldValueAsNumber(form.maxNumColors),
dither: fieldValueAsNumber(form.dither), dither: inputFieldValueAsNumber(form.dither),
}; };
this.props.onChange(options); this.props.onChange(options);
} }

View File

@@ -0,0 +1,15 @@
import { QuantizeOptions, defaultOptions as quantizerDefaultOptions } from './imagequant/quantizer';
interface Enableable {
enabled: boolean;
}
export interface PreprocessorState {
quantizer: Enableable & QuantizeOptions;
}
export const defaultPreprocessorState = {
quantizer: {
enabled: false,
...quantizerDefaultOptions,
},
};

View File

@@ -1,5 +1,5 @@
import { h, Component } from 'preact'; import { h, Component } from 'preact';
import { bind } from '../../lib/util'; import { bind, inputFieldCheckedAsNumber, inputFieldValueAsNumber } from '../../lib/util';
import { EncodeOptions, WebPImageHint } from './encoder'; import { EncodeOptions, WebPImageHint } from './encoder';
import * as styles from './styles.scss'; import * as styles from './styles.scss';
@@ -24,25 +24,11 @@ function determineLosslessQuality(quality: number): number {
return losslessPresetDefault; return losslessPresetDefault;
} }
/**
* @param field An HTMLInputElement, but the casting is done here to tidy up onChange.
*/
function fieldCheckedAsNumber(field: any): number {
return Number((field as HTMLInputElement).checked);
}
/**
* @param field An HTMLInputElement, but the casting is done here to tidy up onChange.
*/
function fieldValueAsNumber(field: any): number {
return Number((field as HTMLInputElement).value);
}
export default class WebPEncoderOptions extends Component<Props, {}> { export default class WebPEncoderOptions extends Component<Props, {}> {
@bind @bind
onChange(event: Event) { onChange(event: Event) {
const form = (event.currentTarget as HTMLInputElement).closest('form') as HTMLFormElement; const form = (event.currentTarget as HTMLInputElement).closest('form') as HTMLFormElement;
const lossless = fieldCheckedAsNumber(form.lossless); const lossless = inputFieldCheckedAsNumber(form.lossless);
const losslessPresetInput = (form.lossless_preset as HTMLInputElement); const losslessPresetInput = (form.lossless_preset as HTMLInputElement);
const options: EncodeOptions = { const options: EncodeOptions = {
@@ -54,31 +40,31 @@ export default class WebPEncoderOptions extends Component<Props, {}> {
// In lossless mode, the quality is derived from the preset. // In lossless mode, the quality is derived from the preset.
quality: lossless ? quality: lossless ?
losslessPresets[Number(losslessPresetInput.value)][1] : losslessPresets[Number(losslessPresetInput.value)][1] :
fieldValueAsNumber(form.quality), inputFieldValueAsNumber(form.quality),
// In lossless mode, the method is derived from the preset. // In lossless mode, the method is derived from the preset.
method: lossless ? method: lossless ?
losslessPresets[Number(losslessPresetInput.value)][0] : losslessPresets[Number(losslessPresetInput.value)][0] :
fieldValueAsNumber(form.method_input), inputFieldValueAsNumber(form.method_input),
image_hint: (form.image_hint as HTMLInputElement).checked ? image_hint: (form.image_hint as HTMLInputElement).checked ?
WebPImageHint.WEBP_HINT_GRAPH : WebPImageHint.WEBP_HINT_GRAPH :
WebPImageHint.WEBP_HINT_DEFAULT, WebPImageHint.WEBP_HINT_DEFAULT,
// .checked // .checked
exact: fieldCheckedAsNumber(form.exact), exact: inputFieldCheckedAsNumber(form.exact),
alpha_compression: fieldCheckedAsNumber(form.alpha_compression), alpha_compression: inputFieldCheckedAsNumber(form.alpha_compression),
autofilter: fieldCheckedAsNumber(form.autofilter), autofilter: inputFieldCheckedAsNumber(form.autofilter),
filter_type: fieldCheckedAsNumber(form.filter_type), filter_type: inputFieldCheckedAsNumber(form.filter_type),
use_sharp_yuv: fieldCheckedAsNumber(form.use_sharp_yuv), use_sharp_yuv: inputFieldCheckedAsNumber(form.use_sharp_yuv),
// .value // .value
near_lossless: fieldValueAsNumber(form.near_lossless), near_lossless: inputFieldValueAsNumber(form.near_lossless),
alpha_quality: fieldValueAsNumber(form.alpha_quality), alpha_quality: inputFieldValueAsNumber(form.alpha_quality),
alpha_filtering: fieldValueAsNumber(form.alpha_filtering), alpha_filtering: inputFieldValueAsNumber(form.alpha_filtering),
sns_strength: fieldValueAsNumber(form.sns_strength), sns_strength: inputFieldValueAsNumber(form.sns_strength),
filter_strength: fieldValueAsNumber(form.filter_strength), filter_strength: inputFieldValueAsNumber(form.filter_strength),
filter_sharpness: fieldValueAsNumber(form.filter_sharpness), filter_sharpness: inputFieldValueAsNumber(form.filter_sharpness),
pass: fieldValueAsNumber(form.pass), pass: inputFieldValueAsNumber(form.pass),
preprocessing: fieldValueAsNumber(form.preprocessing), preprocessing: inputFieldValueAsNumber(form.preprocessing),
segments: fieldValueAsNumber(form.segments), segments: inputFieldValueAsNumber(form.segments),
partitions: fieldValueAsNumber(form.partitions), partitions: inputFieldValueAsNumber(form.partitions),
}; };
this.props.onChange(options); this.props.onChange(options);
} }

View File

@@ -25,9 +25,13 @@ import {
EncoderType, EncoderType,
EncoderOptions, EncoderOptions,
encoderMap, encoderMap,
PreprocessorState,
} from '../../codecs/encoders'; } from '../../codecs/encoders';
import {
PreprocessorState,
defaultPreprocessorState,
} from '../../codecs/preprocessors';
import { decodeImage } from '../../codecs/decoders'; import { decodeImage } from '../../codecs/decoders';
interface SourceImage { interface SourceImage {
@@ -112,24 +116,14 @@ export default class App extends Component<Props, State> {
loading: false, loading: false,
images: [ images: [
{ {
preprocessorState: { preprocessorState: defaultPreprocessorState,
quantizer: {
enabled: false,
...quantizer.defaultOptions,
},
},
encoderState: { type: identity.type, options: identity.defaultOptions }, encoderState: { type: identity.type, options: identity.defaultOptions },
loadingCounter: 0, loadingCounter: 0,
loadedCounter: 0, loadedCounter: 0,
loading: false, loading: false,
}, },
{ {
preprocessorState: { preprocessorState: defaultPreprocessorState,
quantizer: {
enabled: false,
...quantizer.defaultOptions,
},
},
encoderState: { type: mozJPEG.type, options: mozJPEG.defaultOptions }, encoderState: { type: mozJPEG.type, options: mozJPEG.defaultOptions },
loadingCounter: 0, loadingCounter: 0,
loadedCounter: 0, loadedCounter: 0,

View File

@@ -26,10 +26,11 @@ import {
encoders, encoders,
encodersSupported, encodersSupported,
EncoderSupportMap, EncoderSupportMap,
PreprocessorState,
} from '../../codecs/encoders'; } from '../../codecs/encoders';
import { QuantizeOptions } from '../../codecs/imagequant/quantizer'; import { QuantizeOptions } from '../../codecs/imagequant/quantizer';
import { PreprocessorState } from '../../codecs/preprocessors';
const encoderOptionsComponentMap = { const encoderOptionsComponentMap = {
[identity.type]: undefined, [identity.type]: undefined,
[mozJPEG.type]: MozJpegEncoderOptions, [mozJPEG.type]: MozJpegEncoderOptions,

View File

@@ -145,3 +145,17 @@ export async function sniffMimeType(blob: Blob): Promise<string> {
export function createImageBitmapPolyfill(blob: Blob): Promise<ImageBitmap> { export function createImageBitmapPolyfill(blob: Blob): Promise<ImageBitmap> {
return createImageBitmap(blob); return createImageBitmap(blob);
} }
/**
* @param field An HTMLInputElement, but the casting is done here to tidy up onChange.
*/
export function inputFieldValueAsNumber(field: any): number {
return Number((field as HTMLInputElement).value);
}
/**
* @param field An HTMLInputElement, but the casting is done here to tidy up onChange.
*/
export function inputFieldCheckedAsNumber(field: any): number {
return Number((field as HTMLInputElement).checked);
}