mirror of
https://github.com/GoogleChromeLabs/squoosh.git
synced 2025-11-13 09:17:20 +00:00
Refactor preprocessors module
This commit is contained in:
@@ -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,
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
15
src/codecs/preprocessors.ts
Normal file
15
src/codecs/preprocessors.ts
Normal 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,
|
||||||
|
},
|
||||||
|
};
|
||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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);
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user