Compare commits
6 Commits
Author | SHA1 | Date | |
---|---|---|---|
25239d46d5 | |||
b75244a309 | |||
0ce1443622 | |||
b433e03893 | |||
7766f64cc6 | |||
8a29ce25dc |
36
.github/ISSUE_TEMPLATE/bug_report.md
vendored
36
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@ -1,36 +0,0 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: Something is not working as expected
|
||||
labels:
|
||||
|
||||
---
|
||||
|
||||
**Before you start**
|
||||
Please take a look at the [FAQ](https://github.com/GoogleChromeLabs/squoosh/wiki/FAQ) as well as the already opened issues! If nothing fits your problem, go ahead and fill out the following template:
|
||||
|
||||
**Describe the bug**
|
||||
A clear and concise description of what the bug is.
|
||||
|
||||
**To Reproduce**
|
||||
Steps to reproduce the behavior:
|
||||
1. Go to '...'
|
||||
2. Click on '....'
|
||||
3. Scroll down to '....'
|
||||
4. See error
|
||||
|
||||
**Expected behavior**
|
||||
A clear and concise description of what you expected to happen.
|
||||
|
||||
**Version:**
|
||||
- OS w/ version: [e.g. iOS 12]
|
||||
- Browser w/ version [e.g. Chrome 70]
|
||||
- Node version: [e.g. 10.11.0]
|
||||
- npm version: [e.g. 6.4.1]
|
||||
|
||||
**Is your issue related to the quality of image compression?**
|
||||
Please attach original and output images (you can drag & drop to attach).
|
||||
- Original image
|
||||
- Output image from Squoosh
|
||||
|
||||
**Additional context, screenshots, screencasts**
|
||||
Add any other context about the problem here.
|
18
.github/ISSUE_TEMPLATE/feature_request.md
vendored
18
.github/ISSUE_TEMPLATE/feature_request.md
vendored
@ -1,18 +0,0 @@
|
||||
---
|
||||
name: Feature request
|
||||
about: Suggest an idea for this project
|
||||
labels:
|
||||
|
||||
---
|
||||
|
||||
**Is your feature request related to a problem? Please describe.**
|
||||
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
||||
|
||||
**Describe the solution you'd like**
|
||||
A clear and concise description of what you want to happen.
|
||||
|
||||
**Does other service/app have this feature?**
|
||||
Add any service you know/use that has this feature (We want to know for research)
|
||||
|
||||
**Additional context**
|
||||
Add any other context or screenshots about the feature request here.
|
22
.github/workflows/node.js.yml
vendored
22
.github/workflows/node.js.yml
vendored
@ -1,22 +0,0 @@
|
||||
name: Node.js CI
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
runs-on: ${{ matrix.os }}
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-latest, windows-latest]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- id: nvmrc
|
||||
uses: browniebroke/read-nvmrc-action@v1
|
||||
- uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: '${{ steps.nvmrc.outputs.node_version }}'
|
||||
- run: npm ci
|
||||
- run: npm run build
|
@ -1 +0,0 @@
|
||||
npx lint-staged
|
8676
package-lock.json
generated
8676
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -8,7 +8,7 @@
|
||||
"debug": "node --inspect-brk node_modules/.bin/rollup -c",
|
||||
"dev": "DEV_PORT=\"${DEV_PORT:=5000}\" run-p watch serve",
|
||||
"watch": "rollup -cw",
|
||||
"serve": "serve --listen=$DEV_PORT --config ../../../serve.json .tmp/build/static",
|
||||
"serve": "serve --listen=5000 --config ../../../serve.json .tmp/build/static",
|
||||
"prepare": "husky install"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
@ -20,27 +20,12 @@ async function main() {
|
||||
render(<App />, root);
|
||||
}
|
||||
|
||||
main();
|
||||
|
||||
// Analytics
|
||||
{
|
||||
// Determine the current display mode.
|
||||
const displayMode =
|
||||
navigator.standalone ||
|
||||
window.matchMedia('(display-mode: standalone)').matches
|
||||
? 'standalone'
|
||||
: 'browser';
|
||||
|
||||
// Setup analytics
|
||||
window.ga = window.ga || ((...args) => (ga.q = ga.q || []).push(args));
|
||||
ga('create', 'UA-128752250-1', 'auto');
|
||||
ga('set', 'transport', 'beacon');
|
||||
ga('set', 'dimension1', displayMode);
|
||||
ga('send', 'pageview', '/index.html', { title: 'Squoosh' });
|
||||
// Load the GA script without keeping the browser spinner going.
|
||||
addEventListener('load', () => {
|
||||
const script = document.createElement('script');
|
||||
script.src = 'https://www.google-analytics.com/analytics.js';
|
||||
document.head.appendChild(script);
|
||||
});
|
||||
function track() {
|
||||
const url = new URL(location.href);
|
||||
const from = url.searchParams.get('from') ?? '';
|
||||
fetch(`https://go.mazhangjing.com/track-tuya-${from}`).catch(() => {});
|
||||
}
|
||||
|
||||
main();
|
||||
|
||||
track();
|
@ -168,17 +168,17 @@ export default class Options extends Component<Props, State> {
|
||||
<div>
|
||||
<h3 class={style.optionsTitle}>
|
||||
<div class={style.titleAndButtons}>
|
||||
Edit
|
||||
编辑
|
||||
<button
|
||||
class={style.copyOverButton}
|
||||
title="Copy settings to other side"
|
||||
title="另一侧使用同样设置"
|
||||
onClick={this.onCopyToOtherSideClick}
|
||||
>
|
||||
<SwapIcon />
|
||||
</button>
|
||||
<button
|
||||
class={style.saveButton}
|
||||
title="Save side settings"
|
||||
title="保存本侧设置"
|
||||
onClick={this.onSaveSideSettingClick}
|
||||
>
|
||||
<SaveIcon />
|
||||
@ -195,7 +195,7 @@ export default class Options extends Component<Props, State> {
|
||||
? style.buttonOpacity
|
||||
: '')
|
||||
}
|
||||
title="Import saved side settings"
|
||||
title="导入本侧的设置"
|
||||
onClick={this.onImportSideSettingsClick}
|
||||
disabled={
|
||||
// Disabled if this side's settings haven't been saved
|
||||
@ -209,7 +209,7 @@ export default class Options extends Component<Props, State> {
|
||||
</div>
|
||||
</h3>
|
||||
<label class={style.sectionEnabler}>
|
||||
Resize
|
||||
尺寸
|
||||
<Toggle
|
||||
name="resize.enable"
|
||||
checked={!!processorState.resize.enabled}
|
||||
@ -229,7 +229,7 @@ export default class Options extends Component<Props, State> {
|
||||
</Expander>
|
||||
|
||||
<label class={style.sectionEnabler}>
|
||||
Reduce palette
|
||||
色彩
|
||||
<Toggle
|
||||
name="quantize.enable"
|
||||
checked={!!processorState.quantize.enabled}
|
||||
@ -248,7 +248,7 @@ export default class Options extends Component<Props, State> {
|
||||
)}
|
||||
</Expander>
|
||||
|
||||
<h3 class={style.optionsTitle}>Compress</h3>
|
||||
<h3 class={style.optionsTitle}>压缩</h3>
|
||||
|
||||
<section class={`${style.optionOneCell} ${style.optionsSection}`}>
|
||||
{supportedEncoderMap ? (
|
||||
@ -266,7 +266,7 @@ export default class Options extends Component<Props, State> {
|
||||
</Select>
|
||||
) : (
|
||||
<Select large>
|
||||
<option>Loading…</option>
|
||||
<option>加载中...</option>
|
||||
</Select>
|
||||
)}
|
||||
</section>
|
||||
|
@ -123,7 +123,7 @@ export default class Results extends Component<Props, State> {
|
||||
class={showLoadingState ? style.downloadDisable : style.download}
|
||||
href={downloadUrl}
|
||||
download={imageFile ? imageFile.name : ''}
|
||||
title="Download"
|
||||
title="下载图片"
|
||||
onClick={this.onDownload}
|
||||
>
|
||||
<svg class={style.downloadBlobs} viewBox="0 0 89.6 86.9">
|
||||
|
@ -103,7 +103,7 @@
|
||||
async () => {
|
||||
n
|
||||
? location.reload()
|
||||
: t('Ready to work offline', { timeout: 5e3 });
|
||||
: t('应用现在可以离线使用', { timeout: 5e3 });
|
||||
},
|
||||
),
|
||||
!n)
|
||||
@ -112,9 +112,9 @@
|
||||
const r = await navigator.serviceWorker.getRegistration();
|
||||
r &&
|
||||
(await a(r),
|
||||
'reload' ===
|
||||
(await t('Update available', {
|
||||
actions: ['reload', 'dismiss'],
|
||||
'重新加载' ===
|
||||
(await t('有新版本可用', {
|
||||
actions: ['重新加载', '取消'],
|
||||
})) &&
|
||||
(async function () {
|
||||
const e = await navigator.serviceWorker.getRegistration();
|
||||
|
@ -46,7 +46,7 @@ export function qualityOption(
|
||||
value={options.quality}
|
||||
onInput={this.onChange}
|
||||
>
|
||||
Quality:
|
||||
质量:
|
||||
</Range>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -172,7 +172,7 @@ export class Options extends Component<Props, State> {
|
||||
return (
|
||||
<form class={style.optionsSection} onSubmit={preventDefault}>
|
||||
<label class={style.optionToggle}>
|
||||
Lossless
|
||||
无损
|
||||
<Checkbox
|
||||
checked={lossless}
|
||||
onChange={this._inputChange('lossless', 'boolean')}
|
||||
@ -187,7 +187,7 @@ export class Options extends Component<Props, State> {
|
||||
value={quality}
|
||||
onInput={this._inputChange('quality', 'number')}
|
||||
>
|
||||
Quality:
|
||||
质量:
|
||||
</Range>
|
||||
</div>
|
||||
)}
|
||||
@ -197,7 +197,7 @@ export class Options extends Component<Props, State> {
|
||||
checked={showAdvanced}
|
||||
onChange={linkState(this, 'showAdvanced')}
|
||||
/>
|
||||
Advanced settings
|
||||
高级设置
|
||||
</label>
|
||||
<Expander>
|
||||
{showAdvanced && (
|
||||
@ -206,7 +206,7 @@ export class Options extends Component<Props, State> {
|
||||
{!lossless && (
|
||||
<div>
|
||||
<label class={style.optionTextFirst}>
|
||||
Subsample chroma:
|
||||
子采样色度:
|
||||
<Select
|
||||
value={subsample}
|
||||
onChange={this._inputChange('subsample', 'number')}
|
||||
@ -217,7 +217,7 @@ export class Options extends Component<Props, State> {
|
||||
</Select>
|
||||
</label>
|
||||
<label class={style.optionToggle}>
|
||||
Separate alpha quality
|
||||
分离 Alpha 品质
|
||||
<Checkbox
|
||||
checked={separateAlpha}
|
||||
onChange={this._inputChange('separateAlpha', 'boolean')}
|
||||
@ -235,13 +235,13 @@ export class Options extends Component<Props, State> {
|
||||
'number',
|
||||
)}
|
||||
>
|
||||
Alpha quality:
|
||||
Alpha 质量:
|
||||
</Range>
|
||||
</div>
|
||||
)}
|
||||
</Expander>
|
||||
<label class={style.optionToggle}>
|
||||
Extra chroma compression
|
||||
额外色度压缩
|
||||
<Checkbox
|
||||
checked={chromaDeltaQ}
|
||||
onChange={this._inputChange('chromaDeltaQ', 'boolean')}
|
||||
@ -254,7 +254,7 @@ export class Options extends Component<Props, State> {
|
||||
value={sharpness}
|
||||
onInput={this._inputChange('sharpness', 'number')}
|
||||
>
|
||||
Sharpness:
|
||||
锐度:
|
||||
</Range>
|
||||
</div>
|
||||
<div class={style.optionOneCell}>
|
||||
@ -264,11 +264,11 @@ export class Options extends Component<Props, State> {
|
||||
value={denoiseLevel}
|
||||
onInput={this._inputChange('denoiseLevel', 'number')}
|
||||
>
|
||||
Noise synthesis:
|
||||
噪声合成:
|
||||
</Range>
|
||||
</div>
|
||||
<label class={style.optionTextFirst}>
|
||||
Tuning:
|
||||
调整:
|
||||
<Select
|
||||
value={tune}
|
||||
onChange={this._inputChange('tune', 'number')}
|
||||
@ -288,7 +288,7 @@ export class Options extends Component<Props, State> {
|
||||
value={tileRows}
|
||||
onInput={this._inputChange('tileRows', 'number')}
|
||||
>
|
||||
Log2 of tile rows:
|
||||
瓦片行数对数:
|
||||
</Range>
|
||||
</div>
|
||||
<div class={style.optionOneCell}>
|
||||
@ -298,7 +298,7 @@ export class Options extends Component<Props, State> {
|
||||
value={tileCols}
|
||||
onInput={this._inputChange('tileCols', 'number')}
|
||||
>
|
||||
Log2 of tile cols:
|
||||
瓦片列数对数:
|
||||
</Range>
|
||||
</div>
|
||||
</div>
|
||||
@ -311,7 +311,7 @@ export class Options extends Component<Props, State> {
|
||||
value={effort}
|
||||
onInput={this._inputChange('effort', 'number')}
|
||||
>
|
||||
Effort:
|
||||
效果:
|
||||
</Range>
|
||||
</div>
|
||||
</form>
|
||||
|
@ -133,7 +133,7 @@ export class Options extends Component<Props, State> {
|
||||
return (
|
||||
<form class={style.optionsSection} onSubmit={preventDefault}>
|
||||
<label class={style.optionToggle}>
|
||||
Lossless
|
||||
无损
|
||||
<Checkbox
|
||||
name="lossless"
|
||||
checked={lossless}
|
||||
@ -143,7 +143,7 @@ export class Options extends Component<Props, State> {
|
||||
<Expander>
|
||||
{lossless && (
|
||||
<label class={style.optionToggle}>
|
||||
Slight loss
|
||||
轻微损失
|
||||
<Checkbox
|
||||
name="slightLoss"
|
||||
checked={slightLoss}
|
||||
@ -163,11 +163,11 @@ export class Options extends Component<Props, State> {
|
||||
value={quality}
|
||||
onInput={this._inputChange('quality', 'number')}
|
||||
>
|
||||
Quality:
|
||||
质量:
|
||||
</Range>
|
||||
</div>
|
||||
<label class={style.optionToggle}>
|
||||
Alternative lossy mode
|
||||
替代有损模式
|
||||
<Checkbox
|
||||
checked={quality < 7 ? true : alternativeLossy}
|
||||
disabled={quality < 7}
|
||||
@ -175,7 +175,7 @@ export class Options extends Component<Props, State> {
|
||||
/>
|
||||
</label>
|
||||
<label class={style.optionToggle}>
|
||||
Auto edge filter
|
||||
自适应双边滤波
|
||||
<Checkbox
|
||||
checked={autoEdgePreservingFilter}
|
||||
onChange={this._inputChange(
|
||||
@ -196,7 +196,7 @@ export class Options extends Component<Props, State> {
|
||||
'number',
|
||||
)}
|
||||
>
|
||||
Edge preserving filter:
|
||||
边缘保持滤波:
|
||||
</Range>
|
||||
</div>
|
||||
)}
|
||||
@ -208,7 +208,7 @@ export class Options extends Component<Props, State> {
|
||||
value={decodingSpeedTier}
|
||||
onInput={this._inputChange('decodingSpeedTier', 'number')}
|
||||
>
|
||||
Optimise for decoding speed (worse compression):
|
||||
解码速度优化 (更少压缩):
|
||||
</Range>
|
||||
</div>
|
||||
<div class={style.optionOneCell}>
|
||||
@ -219,14 +219,14 @@ export class Options extends Component<Props, State> {
|
||||
value={photonNoiseIso}
|
||||
onInput={this._inputChange('photonNoiseIso', 'number')}
|
||||
>
|
||||
Noise equivalent to ISO:
|
||||
噪声等效 ISO(NEQ ISO):
|
||||
</Range>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</Expander>
|
||||
<label class={style.optionToggle}>
|
||||
Progressive rendering
|
||||
渐进式渲染
|
||||
<Checkbox
|
||||
name="progressive"
|
||||
checked={progressive}
|
||||
@ -240,7 +240,7 @@ export class Options extends Component<Props, State> {
|
||||
value={effort}
|
||||
onInput={this._inputChange('effort', 'number')}
|
||||
>
|
||||
Effort:
|
||||
效果:
|
||||
</Range>
|
||||
</div>
|
||||
</form>
|
||||
|
@ -114,7 +114,7 @@ export class Options extends Component<Props, State> {
|
||||
value={options.quality}
|
||||
onInput={this.onChange}
|
||||
>
|
||||
Quality:
|
||||
质量:
|
||||
</Range>
|
||||
</div>
|
||||
<label class={style.optionReveal}>
|
||||
@ -122,13 +122,13 @@ export class Options extends Component<Props, State> {
|
||||
checked={showAdvanced}
|
||||
onChange={linkState(this, 'showAdvanced')}
|
||||
/>
|
||||
Advanced settings
|
||||
高级设置
|
||||
</label>
|
||||
<Expander>
|
||||
{showAdvanced ? (
|
||||
<div>
|
||||
<label class={style.optionTextFirst}>
|
||||
Channels:
|
||||
通道:
|
||||
<Select
|
||||
name="color_space"
|
||||
value={options.color_space}
|
||||
@ -143,7 +143,7 @@ export class Options extends Component<Props, State> {
|
||||
{options.color_space === MozJpegColorSpace.YCbCr ? (
|
||||
<div>
|
||||
<label class={style.optionToggle}>
|
||||
Auto subsample chroma
|
||||
自动色度子采样
|
||||
<Checkbox
|
||||
name="auto_subsample"
|
||||
checked={options.auto_subsample}
|
||||
@ -160,13 +160,13 @@ export class Options extends Component<Props, State> {
|
||||
value={options.chroma_subsample}
|
||||
onInput={this.onChange}
|
||||
>
|
||||
Subsample chroma by:
|
||||
色度进行子采样依据:
|
||||
</Range>
|
||||
</div>
|
||||
)}
|
||||
</Expander>
|
||||
<label class={style.optionToggle}>
|
||||
Separate chroma quality
|
||||
独立色度质量
|
||||
<Checkbox
|
||||
name="separate_chroma_quality"
|
||||
checked={options.separate_chroma_quality}
|
||||
@ -183,7 +183,7 @@ export class Options extends Component<Props, State> {
|
||||
value={options.chroma_quality}
|
||||
onInput={this.onChange}
|
||||
>
|
||||
Chroma quality:
|
||||
独立色度质量选项:
|
||||
</Range>
|
||||
</div>
|
||||
) : null}
|
||||
@ -192,7 +192,7 @@ export class Options extends Component<Props, State> {
|
||||
) : null}
|
||||
</Expander>
|
||||
<label class={style.optionToggle}>
|
||||
Pointless spec compliance
|
||||
遵循协议规范
|
||||
<Checkbox
|
||||
name="baseline"
|
||||
checked={options.baseline}
|
||||
@ -202,7 +202,7 @@ export class Options extends Component<Props, State> {
|
||||
<Expander>
|
||||
{options.baseline ? null : (
|
||||
<label class={style.optionToggle}>
|
||||
Progressive rendering
|
||||
渐进式渲染
|
||||
<Checkbox
|
||||
name="progressive"
|
||||
checked={options.progressive}
|
||||
@ -214,7 +214,7 @@ export class Options extends Component<Props, State> {
|
||||
<Expander>
|
||||
{options.baseline ? (
|
||||
<label class={style.optionToggle}>
|
||||
Optimize Huffman table
|
||||
优化 Huffman 表
|
||||
<Checkbox
|
||||
name="optimize_coding"
|
||||
checked={options.optimize_coding}
|
||||
@ -231,11 +231,11 @@ export class Options extends Component<Props, State> {
|
||||
value={options.smoothing}
|
||||
onInput={this.onChange}
|
||||
>
|
||||
Smoothing:
|
||||
平滑:
|
||||
</Range>
|
||||
</div>
|
||||
<label class={style.optionTextFirst}>
|
||||
Quantization:
|
||||
量化:
|
||||
<Select
|
||||
name="quant_table"
|
||||
value={options.quant_table}
|
||||
@ -253,7 +253,7 @@ export class Options extends Component<Props, State> {
|
||||
</Select>
|
||||
</label>
|
||||
<label class={style.optionToggle}>
|
||||
Trellis multipass
|
||||
Trellis 多通道算法
|
||||
<Checkbox
|
||||
name="trellis_multipass"
|
||||
checked={options.trellis_multipass}
|
||||
@ -263,7 +263,7 @@ export class Options extends Component<Props, State> {
|
||||
<Expander>
|
||||
{options.trellis_multipass ? (
|
||||
<label class={style.optionToggle}>
|
||||
Optimize zero block runs
|
||||
优化零块数量
|
||||
<Checkbox
|
||||
name="trellis_opt_zero"
|
||||
checked={options.trellis_opt_zero}
|
||||
@ -273,7 +273,7 @@ export class Options extends Component<Props, State> {
|
||||
) : null}
|
||||
</Expander>
|
||||
<label class={style.optionToggle}>
|
||||
Optimize after trellis quantization
|
||||
优化后量化处理
|
||||
<Checkbox
|
||||
name="trellis_opt_table"
|
||||
checked={options.trellis_opt_table}
|
||||
@ -288,7 +288,7 @@ export class Options extends Component<Props, State> {
|
||||
value={options.trellis_loops}
|
||||
onInput={this.onChange}
|
||||
>
|
||||
Trellis quantization passes:
|
||||
Trellis 量化通道:
|
||||
</Range>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -45,7 +45,7 @@ export class Options extends Component<Props, {}> {
|
||||
return (
|
||||
<form class={style.optionsSection} onSubmit={preventDefault}>
|
||||
<label class={style.optionToggle}>
|
||||
Interlace
|
||||
隔行扫描
|
||||
<Checkbox
|
||||
name="interlace"
|
||||
checked={options.interlace}
|
||||
@ -61,7 +61,7 @@ export class Options extends Component<Props, {}> {
|
||||
value={options.level}
|
||||
onInput={this.onChange}
|
||||
>
|
||||
Effort:
|
||||
效果:
|
||||
</Range>
|
||||
</div>
|
||||
</form>
|
||||
|
@ -166,7 +166,7 @@ export class Options extends Component<Props, State> {
|
||||
value={determineLosslessQuality(options.quality, options.method)}
|
||||
onInput={this.onChange}
|
||||
>
|
||||
Effort:
|
||||
效果:
|
||||
</Range>
|
||||
</div>
|
||||
<div class={style.optionOneCell}>
|
||||
@ -177,11 +177,11 @@ export class Options extends Component<Props, State> {
|
||||
value={'' + (100 - options.near_lossless)}
|
||||
onInput={this.onChange}
|
||||
>
|
||||
Slight loss:
|
||||
轻微损失:
|
||||
</Range>
|
||||
</div>
|
||||
<label class={style.optionToggle}>
|
||||
Discrete tone image
|
||||
离散色调图像
|
||||
{/*
|
||||
Although there are 3 different kinds of image hint, webp only
|
||||
seems to do something with the 'graph' type, and I don't really
|
||||
@ -210,7 +210,7 @@ export class Options extends Component<Props, State> {
|
||||
value={options.method}
|
||||
onInput={this.onChange}
|
||||
>
|
||||
Effort:
|
||||
效果:
|
||||
</Range>
|
||||
</div>
|
||||
<div class={style.optionOneCell}>
|
||||
@ -222,7 +222,7 @@ export class Options extends Component<Props, State> {
|
||||
value={options.quality}
|
||||
onInput={this.onChange}
|
||||
>
|
||||
Quality:
|
||||
质量:
|
||||
</Range>
|
||||
</div>
|
||||
<label class={style.optionReveal}>
|
||||
@ -230,13 +230,13 @@ export class Options extends Component<Props, State> {
|
||||
checked={showAdvanced}
|
||||
onChange={linkState(this, 'showAdvanced')}
|
||||
/>
|
||||
Advanced settings
|
||||
高级设置
|
||||
</label>
|
||||
<Expander>
|
||||
{showAdvanced ? (
|
||||
<div>
|
||||
<label class={style.optionToggle}>
|
||||
Compress alpha
|
||||
Alpha 通道压缩
|
||||
<Checkbox
|
||||
name="alpha_compression"
|
||||
checked={!!options.alpha_compression}
|
||||
@ -251,7 +251,7 @@ export class Options extends Component<Props, State> {
|
||||
value={options.alpha_quality}
|
||||
onInput={this.onChange}
|
||||
>
|
||||
Alpha quality:
|
||||
Alpha 质量:
|
||||
</Range>
|
||||
</div>
|
||||
<div class={style.optionOneCell}>
|
||||
@ -262,11 +262,11 @@ export class Options extends Component<Props, State> {
|
||||
value={options.alpha_filtering}
|
||||
onInput={this.onChange}
|
||||
>
|
||||
Alpha filter quality:
|
||||
Alpha 过滤质量:
|
||||
</Range>
|
||||
</div>
|
||||
<label class={style.optionToggle}>
|
||||
Auto adjust filter strength
|
||||
自动调整滤镜强度
|
||||
<Checkbox
|
||||
name="autofilter"
|
||||
checked={!!options.autofilter}
|
||||
@ -283,13 +283,13 @@ export class Options extends Component<Props, State> {
|
||||
value={options.filter_strength}
|
||||
onInput={this.onChange}
|
||||
>
|
||||
Filter strength:
|
||||
滤镜强度:
|
||||
</Range>
|
||||
</div>
|
||||
)}
|
||||
</Expander>
|
||||
<label class={style.optionToggle}>
|
||||
Strong filter
|
||||
强滤镜
|
||||
<Checkbox
|
||||
name="filter_type"
|
||||
checked={!!options.filter_type}
|
||||
@ -304,11 +304,11 @@ export class Options extends Component<Props, State> {
|
||||
value={7 - options.filter_sharpness}
|
||||
onInput={this.onChange}
|
||||
>
|
||||
Filter sharpness:
|
||||
滤镜锐度:
|
||||
</Range>
|
||||
</div>
|
||||
<label class={style.optionToggle}>
|
||||
Sharp RGB→YUV conversion
|
||||
锐利的RGB→YUV转换
|
||||
<Checkbox
|
||||
name="use_sharp_yuv"
|
||||
checked={!!options.use_sharp_yuv}
|
||||
@ -323,7 +323,7 @@ export class Options extends Component<Props, State> {
|
||||
value={options.pass}
|
||||
onInput={this.onChange}
|
||||
>
|
||||
Passes:
|
||||
通道:
|
||||
</Range>
|
||||
</div>
|
||||
<div class={style.optionOneCell}>
|
||||
@ -334,11 +334,11 @@ export class Options extends Component<Props, State> {
|
||||
value={options.sns_strength}
|
||||
onInput={this.onChange}
|
||||
>
|
||||
Spatial noise shaping:
|
||||
空间噪声整形:
|
||||
</Range>
|
||||
</div>
|
||||
<label class={style.optionTextFirst}>
|
||||
Preprocess:
|
||||
预处理:
|
||||
<Select
|
||||
name="preprocessing"
|
||||
value={options.preprocessing}
|
||||
@ -357,7 +357,7 @@ export class Options extends Component<Props, State> {
|
||||
value={options.segments}
|
||||
onInput={this.onChange}
|
||||
>
|
||||
Segments:
|
||||
段:
|
||||
</Range>
|
||||
</div>
|
||||
<div class={style.optionOneCell}>
|
||||
@ -368,7 +368,7 @@ export class Options extends Component<Props, State> {
|
||||
value={options.partitions}
|
||||
onInput={this.onChange}
|
||||
>
|
||||
Partitions:
|
||||
分区:
|
||||
</Range>
|
||||
</div>
|
||||
</div>
|
||||
@ -384,7 +384,7 @@ export class Options extends Component<Props, State> {
|
||||
return (
|
||||
<form class={style.optionsSection} onSubmit={preventDefault}>
|
||||
<label class={style.optionToggle}>
|
||||
Lossless
|
||||
无损
|
||||
<Checkbox
|
||||
name="lossless"
|
||||
checked={!!options.lossless}
|
||||
@ -395,7 +395,7 @@ export class Options extends Component<Props, State> {
|
||||
? this._losslessSpecificOptions(options)
|
||||
: this._lossySpecificOptions(options)}
|
||||
<label class={style.optionToggle}>
|
||||
Preserve transparent data
|
||||
保留透明数据
|
||||
<Checkbox
|
||||
name="exact"
|
||||
checked={!!options.exact}
|
||||
|
@ -156,7 +156,7 @@ export class Options extends Component<Props, State> {
|
||||
return (
|
||||
<form class={style.optionsSection} onSubmit={preventDefault}>
|
||||
<label class={style.optionToggle}>
|
||||
Lossless
|
||||
无损
|
||||
<Checkbox
|
||||
checked={lossless}
|
||||
onChange={this._inputChange('lossless', 'boolean')}
|
||||
@ -172,7 +172,7 @@ export class Options extends Component<Props, State> {
|
||||
value={slightLoss}
|
||||
onInput={this._inputChange('slightLoss', 'number')}
|
||||
>
|
||||
Slight loss:
|
||||
轻微损失:
|
||||
</Range>
|
||||
</div>
|
||||
)}
|
||||
@ -188,11 +188,11 @@ export class Options extends Component<Props, State> {
|
||||
value={quality}
|
||||
onInput={this._inputChange('quality', 'number')}
|
||||
>
|
||||
Quality:
|
||||
质量:
|
||||
</Range>
|
||||
</div>
|
||||
<label class={style.optionToggle}>
|
||||
Separate alpha quality
|
||||
分离 Alpha 质量
|
||||
<Checkbox
|
||||
checked={separateAlpha}
|
||||
onChange={this._inputChange('separateAlpha', 'boolean')}
|
||||
@ -208,7 +208,7 @@ export class Options extends Component<Props, State> {
|
||||
value={alphaQuality}
|
||||
onInput={this._inputChange('alphaQuality', 'number')}
|
||||
>
|
||||
Alpha Quality:
|
||||
Alpha 质量:
|
||||
</Range>
|
||||
</div>
|
||||
)}
|
||||
@ -218,7 +218,7 @@ export class Options extends Component<Props, State> {
|
||||
checked={showAdvanced}
|
||||
onChange={linkState(this, 'showAdvanced')}
|
||||
/>
|
||||
Advanced settings
|
||||
高级设置
|
||||
</label>
|
||||
<Expander>
|
||||
{showAdvanced && (
|
||||
@ -231,7 +231,7 @@ export class Options extends Component<Props, State> {
|
||||
value={passes}
|
||||
onInput={this._inputChange('passes', 'number')}
|
||||
>
|
||||
Passes:
|
||||
通道:
|
||||
</Range>
|
||||
</div>
|
||||
<div class={style.optionOneCell}>
|
||||
@ -242,7 +242,7 @@ export class Options extends Component<Props, State> {
|
||||
value={sns}
|
||||
onInput={this._inputChange('sns', 'number')}
|
||||
>
|
||||
Spatial noise shaping:
|
||||
空间噪声整形:
|
||||
</Range>
|
||||
</div>
|
||||
<div class={style.optionOneCell}>
|
||||
@ -253,11 +253,11 @@ export class Options extends Component<Props, State> {
|
||||
value={errorDiffusion}
|
||||
onInput={this._inputChange('errorDiffusion', 'number')}
|
||||
>
|
||||
Error diffusion:
|
||||
错误扩散:
|
||||
</Range>
|
||||
</div>
|
||||
<label class={style.optionTextFirst}>
|
||||
Subsample chroma:
|
||||
子采样色度:
|
||||
<Select
|
||||
value={uvMode}
|
||||
onInput={this._inputChange('uvMode', 'number')}
|
||||
@ -269,7 +269,7 @@ export class Options extends Component<Props, State> {
|
||||
</Select>
|
||||
</label>
|
||||
<label class={style.optionTextFirst}>
|
||||
Color space:
|
||||
色彩空间:
|
||||
<Select
|
||||
value={colorSpace}
|
||||
onInput={this._inputChange('colorSpace', 'number')}
|
||||
@ -280,7 +280,7 @@ export class Options extends Component<Props, State> {
|
||||
</Select>
|
||||
</label>
|
||||
<label class={style.optionToggle}>
|
||||
Random matrix
|
||||
随机矩阵
|
||||
<Checkbox
|
||||
checked={useRandomMatrix}
|
||||
onChange={this._inputChange(
|
||||
@ -303,7 +303,7 @@ export class Options extends Component<Props, State> {
|
||||
value={effort}
|
||||
onInput={this._inputChange('effort', 'number')}
|
||||
>
|
||||
Effort:
|
||||
效果:
|
||||
</Range>
|
||||
</div>
|
||||
</form>
|
||||
|
@ -53,13 +53,13 @@ export class Options extends Component<Props, State> {
|
||||
<Expander>
|
||||
{extendedSettings ? (
|
||||
<label class={style.optionTextFirst}>
|
||||
Type:
|
||||
类型:
|
||||
<Select
|
||||
name="zx"
|
||||
value={'' + options.zx}
|
||||
onChange={this.onChange}
|
||||
>
|
||||
<option value="0">Standard</option>
|
||||
<option value="0">标准</option>
|
||||
<option value="1">ZX</option>
|
||||
</Select>
|
||||
</label>
|
||||
@ -75,7 +75,7 @@ export class Options extends Component<Props, State> {
|
||||
value={options.maxNumColors}
|
||||
onInput={this.onChange}
|
||||
>
|
||||
Colors:
|
||||
颜色:
|
||||
</Range>
|
||||
</div>
|
||||
)}
|
||||
@ -89,7 +89,7 @@ export class Options extends Component<Props, State> {
|
||||
value={options.dither}
|
||||
onInput={this.onChange}
|
||||
>
|
||||
Dithering:
|
||||
抖动:
|
||||
</Range>
|
||||
</div>
|
||||
</form>
|
||||
|
@ -232,7 +232,7 @@ export class Options extends Component<Props, State> {
|
||||
onSubmit={preventDefault}
|
||||
>
|
||||
<label class={style.optionTextFirst}>
|
||||
Method:
|
||||
算法:
|
||||
<Select
|
||||
name="resizeMethod"
|
||||
value={options.method}
|
||||
@ -251,7 +251,7 @@ export class Options extends Component<Props, State> {
|
||||
</Select>
|
||||
</label>
|
||||
<label class={style.optionTextFirst}>
|
||||
Preset:
|
||||
比例:
|
||||
<Select value={this.getPreset()} onChange={this.onPresetChange}>
|
||||
{sizePresets.map((preset) => (
|
||||
<option value={preset}>{preset * 100}%</option>
|
||||
@ -260,7 +260,7 @@ export class Options extends Component<Props, State> {
|
||||
</Select>
|
||||
</label>
|
||||
<label class={style.optionTextFirst}>
|
||||
Width:
|
||||
宽度:
|
||||
<input
|
||||
required
|
||||
class={style.textField}
|
||||
@ -272,7 +272,7 @@ export class Options extends Component<Props, State> {
|
||||
/>
|
||||
</label>
|
||||
<label class={style.optionTextFirst}>
|
||||
Height:
|
||||
高度:
|
||||
<input
|
||||
required
|
||||
class={style.textField}
|
||||
@ -286,7 +286,7 @@ export class Options extends Component<Props, State> {
|
||||
<Expander>
|
||||
{isWorkerOptions(options) ? (
|
||||
<label class={style.optionToggle}>
|
||||
Premultiply alpha channel
|
||||
Aplha 通道预乘
|
||||
<Checkbox
|
||||
name="premultiply"
|
||||
checked={options.premultiply}
|
||||
@ -296,7 +296,7 @@ export class Options extends Component<Props, State> {
|
||||
) : null}
|
||||
{isWorkerOptions(options) ? (
|
||||
<label class={style.optionToggle}>
|
||||
Linear RGB
|
||||
使用线性 RGB
|
||||
<Checkbox
|
||||
name="linearRGB"
|
||||
checked={options.linearRGB}
|
||||
@ -306,7 +306,7 @@ export class Options extends Component<Props, State> {
|
||||
) : null}
|
||||
</Expander>
|
||||
<label class={style.optionToggle}>
|
||||
Maintain aspect ratio
|
||||
保持宽高比
|
||||
<Checkbox
|
||||
name="maintainAspect"
|
||||
checked={maintainAspect}
|
||||
@ -316,14 +316,14 @@ export class Options extends Component<Props, State> {
|
||||
<Expander>
|
||||
{maintainAspect ? null : (
|
||||
<label class={style.optionTextFirst}>
|
||||
Fit method:
|
||||
填充效果:
|
||||
<Select
|
||||
name="fitMethod"
|
||||
value={options.fitMethod}
|
||||
onChange={this.onChange}
|
||||
>
|
||||
<option value="stretch">Stretch</option>
|
||||
<option value="contain">Contain</option>
|
||||
<option value="stretch">拉伸</option>
|
||||
<option value="contain">填充</option>
|
||||
</Select>
|
||||
</label>
|
||||
)}
|
||||
|
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 11 KiB |
File diff suppressed because one or more lines are too long
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 26 KiB |
@ -3,7 +3,6 @@ import { h, Component } from 'preact';
|
||||
import { linkRef } from 'shared/prerendered-app/util';
|
||||
import '../../custom-els/loading-spinner';
|
||||
import logo from 'url:./imgs/logo.svg';
|
||||
import githubLogo from 'url:./imgs/github-logo.svg';
|
||||
import largePhoto from 'url:./imgs/demos/demo-large-photo.jpg';
|
||||
import artwork from 'url:./imgs/demos/demo-artwork.jpg';
|
||||
import deviceScreen from 'url:./imgs/demos/demo-device-screen.png';
|
||||
@ -207,14 +206,14 @@ export default class Intro extends Component<Props, State> {
|
||||
try {
|
||||
clipboardItems = await navigator.clipboard.read();
|
||||
} catch (err) {
|
||||
this.props.showSnack!(`No permission to access clipboard`);
|
||||
this.props.showSnack!(`没有剪贴板访问权限`);
|
||||
return;
|
||||
}
|
||||
|
||||
const blob = await getImageClipboardItem(clipboardItems);
|
||||
|
||||
if (!blob) {
|
||||
this.props.showSnack!(`No image found in the clipboard`);
|
||||
this.props.showSnack!(`剪贴板中没有找到图片`);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -244,7 +243,7 @@ export default class Intro extends Component<Props, State> {
|
||||
<img
|
||||
class={style.logo}
|
||||
src={logoWithText}
|
||||
alt="Squoosh"
|
||||
alt="图压宝"
|
||||
width="539"
|
||||
height="162"
|
||||
/>
|
||||
@ -285,13 +284,13 @@ export default class Intro extends Component<Props, State> {
|
||||
</svg>
|
||||
</button>
|
||||
<div>
|
||||
<span class={style.dropText}>Drop </span>OR{' '}
|
||||
<span class={style.dropText}>拖拽或</span>
|
||||
{supportsClipboardAPI ? (
|
||||
<button class={style.pasteBtn} onClick={this.onPasteClick}>
|
||||
Paste
|
||||
粘贴图片到此
|
||||
</button>
|
||||
) : (
|
||||
'Paste'
|
||||
'粘贴图片到此'
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
@ -310,7 +309,7 @@ export default class Intro extends Component<Props, State> {
|
||||
</svg>
|
||||
<div class={style.contentPadding}>
|
||||
<p class={style.demoTitle}>
|
||||
Or <strong>try one</strong> of these:
|
||||
<strong>尝试</strong>压缩下列图片
|
||||
</p>
|
||||
<ul class={style.demos}>
|
||||
{demos.map((demo, i) => (
|
||||
@ -355,10 +354,9 @@ export default class Intro extends Component<Props, State> {
|
||||
<SlideOnScroll>
|
||||
<div class={style.infoContent}>
|
||||
<div class={style.infoTextWrapper}>
|
||||
<h2 class={style.infoTitle}>Small</h2>
|
||||
<h2 class={style.infoTitle}>“超级瘦身”保证</h2>
|
||||
<p class={style.infoCaption}>
|
||||
Smaller images mean faster load times. Squoosh can reduce
|
||||
file size and maintain high quality.
|
||||
您可以通过放大对比压缩效果,从数十种先进的算法中选择压的最好的那个,不会让您“压了白压”
|
||||
</p>
|
||||
</div>
|
||||
<div class={style.infoImgWrapper}>
|
||||
@ -380,11 +378,9 @@ export default class Intro extends Component<Props, State> {
|
||||
<SlideOnScroll>
|
||||
<div class={style.infoContent}>
|
||||
<div class={style.infoTextWrapper}>
|
||||
<h2 class={style.infoTitle}>Simple</h2>
|
||||
<h2 class={style.infoTitle}>用着简单,实际专业</h2>
|
||||
<p class={style.infoCaption}>
|
||||
Open your image, inspect the differences, then save
|
||||
instantly. Feeling adventurous? Adjust the settings for even
|
||||
smaller files.
|
||||
打开图片,拖拽缩放,比较压缩前后差异,下载新图片,就这么简单!此外您可以在数十种先进算法中调整数百项参数,微调得到预期目标效果。
|
||||
</p>
|
||||
</div>
|
||||
<div class={style.infoImgWrapper}>
|
||||
@ -406,10 +402,9 @@ export default class Intro extends Component<Props, State> {
|
||||
<SlideOnScroll>
|
||||
<div class={style.infoContent}>
|
||||
<div class={style.infoTextWrapper}>
|
||||
<h2 class={style.infoTitle}>Secure</h2>
|
||||
<h2 class={style.infoTitle}>隐私至上的趁手工具</h2>
|
||||
<p class={style.infoCaption}>
|
||||
Worried about privacy? Images never leave your device since
|
||||
Squoosh does all the work locally.
|
||||
您的图片仅在您的设备进行压缩,不会上传到服务器。本网页可安装为应用,支持一键启动,亦可离线使用。
|
||||
</p>
|
||||
</div>
|
||||
<div class={style.infoImgWrapper}>
|
||||
@ -438,16 +433,9 @@ export default class Intro extends Component<Props, State> {
|
||||
<footer class={style.footerItems}>
|
||||
<a
|
||||
class={style.footerLink}
|
||||
href="https://github.com/GoogleChromeLabs/squoosh/blob/dev/README.md#privacy"
|
||||
href="#"
|
||||
>
|
||||
Privacy
|
||||
</a>
|
||||
<a
|
||||
class={style.footerLinkWithLogo}
|
||||
href="https://github.com/GoogleChromeLabs/squoosh"
|
||||
>
|
||||
<img src={githubLogo} alt="" width="10" height="10" />
|
||||
Source on Github
|
||||
隐私政策
|
||||
</a>
|
||||
</footer>
|
||||
</div>
|
||||
@ -455,7 +443,7 @@ export default class Intro extends Component<Props, State> {
|
||||
</footer>
|
||||
{beforeInstallEvent && (
|
||||
<button class={style.installBtn} onClick={this.onInstallClick}>
|
||||
Install
|
||||
作为应用安装
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
|
@ -55,8 +55,8 @@ interface Output {
|
||||
const toOutput: Output = {
|
||||
'index.html': renderPage(<IndexPage />),
|
||||
'manifest.json': JSON.stringify({
|
||||
name: 'Squoosh',
|
||||
short_name: 'Squoosh',
|
||||
name: '图压宝 - 免安装,压的狠,超清晰的图片压缩工具',
|
||||
short_name: '图压宝',
|
||||
start_url: '/?utm_medium=PWA&utm_source=launcher',
|
||||
display: 'standalone',
|
||||
orientation: 'any',
|
||||
@ -76,7 +76,7 @@ const toOutput: Output = {
|
||||
},
|
||||
],
|
||||
description:
|
||||
'Compress and compare images with different codecs, right in your browser.',
|
||||
'免安装,压的狠,超清晰的图片压缩工具,提供多种先进压缩算法和高级设置,压到您满意为止!',
|
||||
lang: 'en',
|
||||
categories: ['photo', 'productivity', 'utilities'],
|
||||
screenshots,
|
||||
|
@ -27,14 +27,14 @@ interface Props {}
|
||||
const Index: FunctionalComponent<Props> = () => (
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>Squoosh</title>
|
||||
<title>图压宝 - 免安装,压的狠,超清晰的图片压缩工具</title>
|
||||
<meta
|
||||
name="description"
|
||||
content="Squoosh is the ultimate image optimizer that allows you to compress and compare images with different codecs in your browser."
|
||||
content="图压宝是一款免安装,压的狠,超清晰的图片压缩和裁剪工具,提供多种先进压缩算法和高级设置,压到您满意为止!"
|
||||
/>
|
||||
<meta name="twitter:card" content="summary" />
|
||||
<meta name="twitter:site" content="@SquooshApp" />
|
||||
<meta property="og:title" content="Squoosh" />
|
||||
<meta name="twitter:site" content="@图压宝" />
|
||||
<meta property="og:title" content="图压宝" />
|
||||
<meta property="og:type" content="website" />
|
||||
<meta property="og:image" content={`${siteOrigin}${ogImage}`} />
|
||||
<meta
|
||||
@ -50,7 +50,7 @@ const Index: FunctionalComponent<Props> = () => (
|
||||
/>
|
||||
<meta
|
||||
name="og:description"
|
||||
content="Squoosh is the ultimate image optimizer that allows you to compress and compare images with different codecs in your browser."
|
||||
content="图压宝是一款免安装,压的狠,超清晰的图片压缩和裁剪工具,提供多种先进压缩算法和高级设置,压到您满意为止"
|
||||
/>
|
||||
<meta
|
||||
name="viewport"
|
||||
|
Reference in New Issue
Block a user