新增图像处理工具

tools
PJ568 2 years ago
parent e1e6453775
commit bdd850dcc0

@ -35,10 +35,40 @@
"type":"图像处理"
},
{
"name":"思维导图",
"name":"在线思维导图编辑器",
"url":"/lib/tools/mind-map/",
"type":"图像处理"
},
{
"name":"多功能图像处理工具",
"url":"/lib/tools/webp2jpg-online/",
"type":"图像处理"
},
{
"name":"在线图片格式转换",
"url":"/lib/tools/webp2jpg-online/",
"type":"图像处理"
},
{
"name":"在线图片批量添加水印工具",
"url":"/lib/tools/webp2jpg-online/",
"type":"图像处理"
},
{
"name":"在线批量重命名图片工具",
"url":"/lib/tools/webp2jpg-online/",
"type":"图像处理"
},
{
"name":"在线图片裁剪",
"url":"/lib/tools/webp2jpg-online/",
"type":"图像处理"
},
{
"name":"在线拼接视频字幕截图",
"url":"/lib/tools/webp2jpg-online/splicing.html#/splicing",
"type":"图像处理"
},
{
"name":"本站后台管理页面",
"url":"/management/",

@ -31,15 +31,46 @@ var classify = [{
"id": 2,
"name": "图像处理",
"list": [{
"name": "思维导图",
"name": "在线思维导图编辑器",
"url": "/incert/?link=/lib/tools/mind-map/",
"hot": 1,
"img": ""
}, {
"name": "在线图片裁剪",
"url": "/lib/tools/webp2jpg-online/",
"hot": 1,
"img": ""
}, {
"name": "多功能图片处理工具",
"url": "/lib/tools/webp2jpg-online/",
"hot": 1,
"img": ""
}, {
"name": "在线图片格式转换",
"url": "/lib/tools/webp2jpg-online/",
"hot": 1,
"img": ""
}, {
"name": "在线图片批量添加水印工具",
"url": "/lib/tools/webp2jpg-online/",
"hot": 1,
"img": ""
}, {
"name": "在线批量重命名图片工具",
"url": "/lib/tools/webp2jpg-online/",
"hot": 0,
"img": ""
}, {
"name": "在线拼接视频字幕截图",
"url": "/incert/?link=/lib/tools/webp2jpg-online/splicing.html#/splicing",
"hot": 0,
"img": ""
}, {
"name": "字符生成图片",
"url": "/lib/tools/geopattern/",
"hot": 0,
"img": ""
}, {
}]
}, {
"id": 3,

@ -0,0 +1,23 @@
.DS_Store
node_modules
/dist
/psd
超多图片处理测试包
# local env files
.env.local
.env.*.local
-=
# Log files
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# Editor directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw*

@ -0,0 +1,55 @@
## 更新日志
### v3.0 -2021.07.24
强化-[处理速度]-🚀优化1000张以上图片数量的处理速度(针对jpg、webp、png)、优化内存管理和cpu占用率, 页面崩溃概率大范围减少
强化-[gif/webp动画]- 比原来更稳定一点点
新增-[输入格式]-psd、psb、hdr、heic、heif、tiff、tif、bmp、tga、xcf、miff、dcm、xpm、pcx、fits、ppm、pgm、pfm、mng、dds、otb
新增-[输出png压缩]-png-tiny(压缩png效果参考tinypng.com)
新增-[输出svg压缩]
新增-[输出ico]
新增-[尺寸]-按高度、按比例
新增-[变换]-旋转、翻转
新增-[水印]-图片水印、文字水印
新增-[水印]-快速定位、平铺模式、比例模式、透明度、选择、边距、缩放、水印预览、隐藏开关、文字样式细节修改...
新增-[修剪]-按像素数、按图片比例
新增-[重命名]
全新UI-暗色/亮色主题、三栏布局让使用流程更清晰、语言选择增至21种、更易用的选项框和滑块
其他-[格式识别]-识别图片的真实格式, 当后缀名与实际不符时给出提示
其他-[设置]-png转jpg时的背景色、另存所有参数、声音提示、进程数
其他-[效果对比]-类似squoosh.app的图片前后对比测试做好了没加上实在没力气了下次再搞
### v2.2 -2020.10.09
新增格式-mozjpeg,压缩率更高/画质更好的jpg
新增格式-avif,逆天的压缩率
修复-对比模式
### v2.1 2020-08-17
新增功能-输出指定大小
新增功能-颜色数量选项(gif、png-8)
新增功能-自动宽度输出
新增格式-8位png
新增格式-base64
修复-选项删除功能
修复-多文件下载遗漏
修复-压缩包文件非英数乱码
修复-大写后缀不识别
修复-强调提示不支持文件格式
删除-ico格式输出(假的ico实际还是png)
### v2.0 2020-06-26
使用vue重构
支持gif动图转webp动图
尺寸和画质可自定义
选项数据持久化
可开启图片追加模式
可开启转换效果对比
优化了UI
支持多语言
页面文件也变大了,初次打开会比较慢,第二次之后就快了
### [v1.0](https://github.com/renzhezhilu/webp2jpg-online/tree/v1.0) 2020-01-14
项目建立
支持jpeg、webp、png互转
可选输出宽度
可选输出画质
可批量处理

@ -0,0 +1,201 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

@ -0,0 +1,98 @@
English | [简体中文](./README_CN.md) | [日本語](./README_JP.md)
<center>
<!-- <img width="300" src="./doc/images/3.png" /> -->
<h1>Webp2jpg-online</h1>
<!-- from shields.io/ -->
![title](https://cdn.jsdelivr.net/gh/renzhezhilu/webp2jpg-online/cdn/badges/01.svg)
![title](https://cdn.jsdelivr.net/gh/renzhezhilu/webp2jpg-online/cdn/badges/02.svg)
![title](https://cdn.jsdelivr.net/gh/renzhezhilu/webp2jpg-online/cdn/badges/03.svg)
</center>
This toolbox includes image conversion and image stitching, pure front-end implementation, fast speed, privacy protection, and offline use,20 languages supported.
Q: Why is it named webp2jpg?
A: Because it was originally to convert webp to jpg, I have been using it all the time.
<!-- <img width="300" src="https://api.star-history.com/svg?repos=renzhezhilu/webp2jpg-online&type=Date" /> -->
## Online address
[Image conversion](https://imagestool.com/webp2jpg-online/)
| [Image splicing](https://imagestool.com/webp2jpg-online/splicing.html)
<h2>
<img width="20" src="./doc/images/1.png" />
Multifunctional Image Converter
</h2>
<img width="600" src="./cdn/webp2jpg_v3_ui.jpg" />
- [x] Support for `psd`, `psb`, `hdr`, `heic`, `heif`, `tiff`, `jpg`, `gif`, `png`, `svg`, `bmp`, Convert `tga` to `jpg`, `webp`, `png`, `gif`, `avif`
- [x] support `jpg` compression (choose jpg-tiny)
- [x] support `png` compression (png-tiny)
- [x] support `svg` compression (svg-tiny)
- [x] Support adding image watermark, text watermark
- [x] support modifying size by width, height, ratio
- [x] Support `webp` and `gif` to convert between animations (webp-animation and gif-animation)
- [x] Support GIF watermark
- [x] Others: base64 output, persistent option data, dark/light UI switching, rotating and flipping images, batch processing (within 1000 images), importing by pressing Ctrl+V after taking a screenshot
<br/>
<br/>
<h2>
<img width="20" src="./doc/images/2.png" />
Video subtitle stitching tool
</h2>
<img width="600" src="./cdn/splicing/ui.jpg" />
Splicing the subtitles of the video into a picture has everyone seen it~ This tool can easily create all forms of such pictures.
### work process:
- 1. Screen recording
- 2. Generate video
- 3. Take a screenshot while playing the video
- 4. Adjust the picture
- 5. Done
### Function:
- [x] Support screen recording
- [x] support importing `mp4` files
- [x] After recording or importing, you can take screenshots with shortcut keys
- [x] Supports cropping and drag sorting of imported images
- [x] Support mobile phone vertical screen
- [x] Support other conventional splicing functions (single column/single row, multiple rows and multiple columns)
- [x] support adjusting margins and border styles
- [x] Lossless output, no blurry pictures
- [x] support to choose export format (`jpg`, `png`, `webp`)
### Tips
- `jpg` maximum size is `65525`
- `webp` size limit `16522`
- `png` size limit is `65525`
## ❤ thanks
[科技爱好者周刊(第 114 期U 盘化生存和 Uber-job](http://www.ruanyifeng.com/blog/2020/07/weekly-issue-114.html)
[Multi-Functional Image Converter: An Online Tool to Batch Convert Images to Various Formats ](https://frontendfoc.us/issues/511)
#### [webp2jpg-online-demo](https://github.com/renzhezhilu/webp2jpg-online-demo)
## Developer
This repository is the production environment version(3.0) and can be used arbitrarily.
<img width="600" src="https://api.star-history.com/svg?repos=renzhezhilu/webp2jpg-online&type=Date" />

@ -0,0 +1,101 @@
[English](./README.md) | 简体中文| [日本語](./README_JP.md)
<center>
<!-- <img width="300" src="./doc/images/3.png" /> -->
<h1>Webp2jpg-online</h1>
<!-- from shields.io/ -->
![title](https://cdn.jsdelivr.net/gh/renzhezhilu/webp2jpg-online/cdn/badges/01.svg)
![title](https://cdn.jsdelivr.net/gh/renzhezhilu/webp2jpg-online/cdn/badges/02.svg)
![title](https://cdn.jsdelivr.net/gh/renzhezhilu/webp2jpg-online/cdn/badges/03.svg)
</center>
此工具箱包含图片转换和图片拼接,纯前端实现、速度快、保护隐私,支持离线使用,
支持20种语言。
Q:为什么会命名webp2jpg
A:因为最开始是为了把webp转成jpg就一直用着了。
## 在线地址
[图片转换](https://imagestool.com/webp2jpg-online/)
| [图片拼接](https://imagestool.com/webp2jpg-online/splicing.html)
<h2>
<img width="20" src="./doc/images/1.png" />
多功能图片转换器
</h2>
<img width="600" src="./cdn/webp2jpg_v3_ui.jpg" />
- [x] 支持将`psd`、`psb`、`hdr`、`heic`、`heif`、`tiff`、`jpg`、`gif`、`png`、`svg`、`bmp`、`tga`转换成`jpg`、`webp`、`png`、`gif`、`avif`
- [x] 支持`jpg`压缩(选择jpg-tiny)
- [x] 支持`png`压缩(png-tiny)
- [x] 支持`svg`压缩(svg-tiny)
- [x] 支持添加图片水印、文字水印
- [x] 支持按宽度、高度、比例修改尺寸
- [x] 支持动图`webp`和`gif`互转(webp-animation和gif-animation)
- [x] 支持动图水印
- [x] 其他:base64输出持久化选项数据、深色/浅色UI切换、对图片进行旋转和翻转、批量处理(1000张以内)、截图后按Ctrl+V导入
<br/>
<br/>
<h2>
<img width="20" src="./doc/images/2.png" />
视频字幕拼接工具
</h2>
<img width="600" src="./cdn/splicing/ui.jpg" />
把视频的字幕拼接成长图片大家都见过吧~ 这个工具可以轻松制作所有形式的此类图片。
### 工作流程:
- 1.录屏
- 2.生成视频
- 3.一边播放视频一边截图
- 4.调整图片
- 5.完成
### 功能:
- [x] 支持录屏
- [x] 支持导入`mp4`文件
- [x] 录屏或导入后,可快捷键截图
- [x] 支持对导入后的图片进行裁切、拖动排序
- [x] 支持手机竖屏
- [x] 支持其他常规拼接功能(单列/单行、多行多列)
- [x] 支持调整边距和边框样式
- [x] 无损输出,不存在图片模糊的问题
- [x] 支持选择导出格式(`jpg`、`png`、`webp`)
### 小贴士
- `jpg`尺寸上限 `65525`
- `webp`尺寸上限 `16522`
- `png`尺寸上限 `65525`
## ❤ thanks
[科技爱好者周刊(第 114 期U 盘化生存和 Uber-job](http://www.ruanyifeng.com/blog/2020/07/weekly-issue-114.html)
[Multi-Functional Image Converter: An Online Tool to Batch Convert Images to Various Formats ](https://frontendfoc.us/issues/511)
#### [webp2jpg-online-demo](https://github.com/renzhezhilu/webp2jpg-online-demo)
## 开发者
本仓库为生产环境版本(3.0),可任意使用。
<img width="600" src="https://api.star-history.com/svg?repos=renzhezhilu/webp2jpg-online&type=Date" />
<!-- 如果你想获得源代码和技术细节分享,欢迎加入[ohPic](https://github.com/ohPic)。 -->

@ -0,0 +1,98 @@
[English](./README.md) | [简体中文](./README_CN.md) | 日本語
<center>
<!-- <img width="300" src="./doc/images/3.png" /> -->
<h1>Webp2jpg-オンライン</h1>
<!--shields.io/ から -->
![タイトル](https://cdn.jsdelivr.net/gh/renzhezhilu/webp2jpg-online/cdn/badges/01.svg)
![タイトル](https://cdn.jsdelivr.net/gh/renzhezhilu/webp2jpg-online/cdn/badges/02.svg)
![タイトル](https://cdn.jsdelivr.net/gh/renzhezhilu/webp2jpg-online/cdn/badges/03.svg)
</center>
このツールボックスには、画像変換と画像スティッチング、純粋なフロントエンド実装、高速、プライバシー保護、およびオフライン使用が含まれます, 20言語対応。
Q: なぜ webp2jpg という名前なのですか?
A: もともとwebpをjpgに変換するものだったのでずっと使っています。
<!-- <img width="300" src="https://api.star-history.com/svg?repos=renzhezhilu/webp2jpg-online&type=Date" /> -->
## オンラインアドレス
[画像変換](https://imagestool.com/webp2jpg-online/)
| [画像のつなぎ合わせ](https://imagestool.com/webp2jpg-online/splicing.html)
<h2>
<img width="20" src="./doc/images/1.png" />
多機能画像コンバーター
</h2>
<img width="600" src="./cdn/webp2jpg_v3_ui.jpg" />
- [x] `psd`、`psb`、`hdr`、`heic`、`heif`、`tiff`、`jpg`、`gif`、`png`、`svg`、`bmp` のサポート`tga` を `jpg`、`webp`、`png`、`gif`、`avif` に変換します
- [x] `jpg` 圧縮をサポート (jpg-tiny を選択)
- [x] `png` 圧縮をサポート (png-tiny)
- [x] `svg` 圧縮をサポート (svg-tiny)
- [x] 画像透かし、テキスト透かしの追加をサポート
- [x] 幅、高さ、比率によるサイズ変更をサポート
- [x] アニメーション間で変換するための `webp``gif` のサポート (webp-animation と gif-animation)
- [x] GIF透かしをサポート
- [x] その他: base64 出力、オプションデータの永続化、UI の明暗切り替え、画像の回転と反転、バッチ処理 (1000 画像以内)、スクリーンショット撮影後に Ctrl+V を押してインポート
<br/>
<br/>
<h2>
<img width="20" src="./doc/images/2.png" />
ビデオ字幕スティッチングツール
</h2>
<img width="600" src="./cdn/splicing/ui.jpg" />
動画の字幕をつなぎ合わせて絵にするのは、誰もが見たことがあるでしょう〜 このツールは、あらゆる形式の絵を簡単に作成できます。
### 作業過程:
- 1.画面収録
- 2.ビデオの生成
- 3.ビデオの再生中にスクリーンショットを撮る
- 4.画像を調整する
- 5.完了
### 関数:
- [x] 画面録画をサポート
- [x] `mp4` ファイルのインポートをサポート
- [x] 記録またはインポート後、ショートカット キーでスクリーンショットを撮ることができます
- [x] インポートした画像のトリミングとドラッグ ソートをサポート
- [x] 携帯電話の縦画面をサポート
- [x] 他の従来のスプライシング機能をサポート (1 列/1 列、複数行および複数列)
- [x] マージンと境界線スタイルの調整をサポート
- [x] ロスレス出力、ぼやけた写真なし
- [x] エクスポート形式の選択をサポート (`jpg`、`png`、`webp`)
### チップ
- `jpg` の最大サイズは `65525` です
- `webp` のサイズ制限 `16522`
- `png` のサイズ制限は `65525` です
## ❤ thanks
[科技爱好者周刊(第 114 期U 盘化生存和 Uber-job](http://www.ruanyifeng.com/blog/2020/07/weekly-issue-114.html)
[Multi-Functional Image Converter: An Online Tool to Batch Convert Images to Various Formats ](https://frontendfoc.us/issues/511)
#### [webp2jpg-online-demo](https://github.com/renzhezhilu/webp2jpg-online-demo)
## デベロッパー
このリポジトリは本番環境版であり(3.0)、任意に使用できます。
<img width="600" src="https://api.star-history.com/svg?repos=renzhezhilu/webp2jpg-online&type=Date" />

@ -0,0 +1,39 @@
<!DOCTYPE html>
<html lang=en>
<head>
<meta charset=utf-8>
<meta http-equiv=X-UA-Compatible content="IE=edge">
<meta name=viewport content="width=device-width,initial-scale=1">
<link rel=icon href='https://cdn.jsdelivr.net/gh/renzhezhilu/webp2jpg-online/cdn/batch/logo2.png'>
<title>图片批量加水印</title>
<!-- <script>
window.location.href = 'https://imagestool.com/images-watermark'
</script> -->
</head>
<body>
<script src=https://cdn.jsdelivr.net/gh/renzhezhilu/webp2jpg-online/cdn/localforage.min.js></script>
<noscript><strong>We're sorry but vue doesn't work properly without JavaScript enabled. Please enable it to
continue.</strong></noscript>
<div id=app></div>
<script src=https://cdn.jsdelivr.net/gh/renzhezhilu/webp2jpg-online/cdn/batch/batch1225_05.js></script>
<script>
// 换视频介绍图标
let icon = setInterval(() => {
if (document.querySelector('#logoDiv > ul > div')) {
document.querySelector('#logoDiv > ul > div').remove()
document.querySelector('#logoDiv > ul').insertAdjacentHTML('beforeend', `
<a href="https://cdn.jsdelivr.net/gh/renzhezhilu/webp2jpg-online/cdn/batch/video.mp4" target="_blank">
<i class="iconfont icon-youtube-play"></i>
</a>
`);
clearInterval(icon)
}
}, 300);
</script>
</body>
</html>

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.0 KiB

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="170" height="20"><linearGradient id="b" x2="0" y2="100%"><stop offset="0" stop-color="#bbb" stop-opacity=".1"/><stop offset="1" stop-opacity=".1"/></linearGradient><clipPath id="a"><rect width="170" height="20" rx="3" fill="#fff"/></clipPath><g clip-path="url(#a)"><path fill="#555" d="M0 0h115v20H0z"/><path fill="#007ec6" d="M115 0h55v20H115z"/><path fill="url(#b)" d="M0 0h170v20H0z"/></g><g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="110"> <text x="585" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="1050">No upload required</text><text x="585" y="140" transform="scale(.1)" textLength="1050">No upload required</text><text x="1415" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="450">本地转换</text><text x="1415" y="140" transform="scale(.1)" textLength="450">本地转换</text></g> </svg>

After

Width:  |  Height:  |  Size: 1000 B

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="100" height="20"><linearGradient id="b" x2="0" y2="100%"><stop offset="0" stop-color="#bbb" stop-opacity=".1"/><stop offset="1" stop-opacity=".1"/></linearGradient><clipPath id="a"><rect width="100" height="20" rx="3" fill="#fff"/></clipPath><g clip-path="url(#a)"><path fill="#555" d="M0 0h67v20H0z"/><path fill="#97ca00" d="M67 0h33v20H67z"/><path fill="url(#b)" d="M0 0h100v20H0z"/></g><g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="110"> <text x="345" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="570">Super fast</text><text x="345" y="140" transform="scale(.1)" textLength="570">Super fast</text><text x="825" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="230">超快</text><text x="825" y="140" transform="scale(.1)" textLength="230">超快</text></g> </svg>

After

Width:  |  Height:  |  Size: 965 B

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="20"><linearGradient id="b" x2="0" y2="100%"><stop offset="0" stop-color="#bbb" stop-opacity=".1"/><stop offset="1" stop-opacity=".1"/></linearGradient><clipPath id="a"><rect width="200" height="20" rx="3" fill="#fff"/></clipPath><g clip-path="url(#a)"><path fill="#555" d="M0 0h67v20H0z"/><path fill="#fe7d37" d="M67 0h133v20H67z"/><path fill="url(#b)" d="M0 0h200v20H0z"/></g><g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="110"> <text x="345" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="570">convert to</text><text x="345" y="140" transform="scale(.1)" textLength="570">convert to</text><text x="1325" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="1230">webp、jpeg、png、ico、gif</text><text x="1325" y="140" transform="scale(.1)" textLength="1230">webp、jpeg、png、ico、gif</text></g> </svg>

After

Width:  |  Height:  |  Size: 1016 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 158 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 98 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 129 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -0,0 +1,40 @@
<svg id="组_1" data-name="组 1" xmlns="http://www.w3.org/2000/svg" width="1265.34" height="294" viewBox="0 0 1265.34 294">
<metadata><?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?>
<x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 5.6-c138 79.159824, 2016/09/14-01:09:01 ">
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
<rdf:Description rdf:about=""/>
</rdf:RDF>
</x:xmpmeta>
<?xpacket end="w"?></metadata>
<defs>
<style>
.cls-1 {
fill: #2affb6;
opacity: 0.8;
}
.cls-2 {
fill: #2b71ff;
}
.cls-3, .cls-4 {
fill: #fff;
}
.cls-3, .cls-5 {
fill-rule: evenodd;
}
.cls-5 {
fill: #3c414b;
}
</style>
</defs>
<rect id="圆角矩形_1_拷贝" data-name="圆角矩形 1 拷贝" class="cls-1" width="270.375" height="261.375" rx="36" ry="36"/>
<rect id="圆角矩形_1" data-name="圆角矩形 1" class="cls-2" x="32.625" y="32.625" width="270.375" height="261.375" rx="36" ry="36"/>
<path id="形状_1" data-name="形状 1" class="cls-3" d="M110.774,153.533L74.936,254.8H140.1"/>
<circle id="椭圆_1" data-name="椭圆 1" class="cls-4" cx="105.89" cy="96.375" r="24.422"/>
<path id="形状_1_拷贝" data-name="形状 1 拷贝" class="cls-3" d="M194.018,98l-73.47,156.8H254.129"/>
<path id="webp2jpg" class="cls-5" d="M476.343,108.148L456.2,187.694l-0.416-79.546H418.189l-25.338,79.546,4.569-79.546H356.712l6.439,110.907h46.315l21.6-74.353,1.454,74.353h45.692l36.761-110.907h-38.63Zm143.306,27.623q0-14.121-11.735-22.95T575.2,103.994q-23.053,0-37.9,10.9a63.272,63.272,0,0,0-21.6,27.311,86.159,86.159,0,0,0-6.75,33.023q0,22.017,12.981,35t38.734,12.981q25.128,0,46.731-15.785L593.48,183.955a94.771,94.771,0,0,1-14.539,7.685,34.383,34.383,0,0,1-12.877,2.492q-15.372,0-16.823-14.746,29.909-2.7,50.158-12.669t20.25-30.946h0ZM550.9,156.332q2.283-11.628,7.269-19t13.085-7.373q8.1,0,8.1,7.684,0,6.027-6.023,11.839T550.9,156.332h0Zm152.651-52.338a40.826,40.826,0,0,0-15.992,3.427,38.725,38.725,0,0,0-13.5,9.242l7.892-56.284-40.707,4.154L620.478,212.824A120.346,120.346,0,0,0,669.7,223.209q37.8,0,52.857-22.742t15.058-53.481q0-20.766-8.516-31.88t-25.546-11.112h0Zm-16.823,29.492a8.417,8.417,0,0,1,7.062,3.22q2.491,3.222,2.492,12.15a85.99,85.99,0,0,1-5.4,30.946q-5.4,14.126-16.615,14.123a29.358,29.358,0,0,1-10.592-2.077l6.646-47.354q7.476-11.005,16.407-11.008h0ZM734.291,266.2l40.292-4.154,6.231-41.746q7.268,2.907,19.315,2.908,20.766,0,33.958-11.631a65.672,65.672,0,0,0,19-29.076,111.682,111.682,0,0,0,5.816-35.516q0-20.766-8.619-31.88t-25.858-11.112a39.194,39.194,0,0,0-15.888,3.739,50.934,50.934,0,0,0-16.1,11.838l-0.208-11.423H756.306Zm61.269-72.276a29.362,29.362,0,0,1-10.592-2.077l6.646-47.562q7.476-10.8,16.407-10.8a8.417,8.417,0,0,1,7.062,3.22q2.492,3.222,2.492,12.15a85.99,85.99,0,0,1-5.4,30.946q-5.4,14.126-16.615,14.123h0ZM921.627,74.5a68.93,68.93,0,0,0-29.8,6.231,79.277,79.277,0,0,0-24.2,18.069l21.185,20.354a67.162,67.162,0,0,1,12.98-10.593,23.8,23.8,0,0,1,12.15-3.323q6.023,0,9.554,3.323a11.686,11.686,0,0,1,3.531,8.931,28.81,28.81,0,0,1-4.569,15.162q-4.572,7.476-17.966,20.146T861.6,190.6l-3.531,28.454h94.915l8.516-30.738-53.585.208q26.375-18.483,39.773-32.193t17.342-23.469a53.3,53.3,0,0,0,3.946-20.146,36.348,36.348,0,0,0-5.3-19.419q-5.295-8.616-15.992-13.708T921.627,74.5h0Zm32.4,191.7q24.3-7.686,39.149-21.807t18.586-41.123l13.3-95.123h-40.3l-13.5,97.2q-1.869,13.084-8.1,20.146t-18.692,11.838Zm53.8-175.291a25.279,25.279,0,0,0,18.17-7.061,23.448,23.448,0,0,0,7.37-17.654,18.643,18.643,0,0,0-5.5-13.915q-5.5-5.4-14.64-5.4a25.279,25.279,0,0,0-18.176,7.062,23.43,23.43,0,0,0-7.373,17.654,18.635,18.635,0,0,0,5.5,13.915q5.5,5.4,14.646,5.4h0ZM1019.86,266.2l40.29-4.154,6.23-41.746q7.275,2.907,19.32,2.908,20.76,0,33.96-11.631a65.691,65.691,0,0,0,19-29.076,111.815,111.815,0,0,0,5.81-35.516q0-20.766-8.61-31.88T1110,103.994a39.2,39.2,0,0,0-15.89,3.739,50.925,50.925,0,0,0-16.1,11.838l-0.2-11.423h-35.93Zm61.27-72.276a29.368,29.368,0,0,1-10.59-2.077l6.64-47.562q7.485-10.8,16.41-10.8a8.416,8.416,0,0,1,7.06,3.22q2.49,3.222,2.49,12.15a85.969,85.969,0,0,1-5.4,30.946q-5.4,14.126-16.61,14.123h0Zm135.2-89.931q-23.25,0-38.42,11.112A63.959,63.959,0,0,0,1156,142.521a84.924,84.924,0,0,0-6.75,32.711q0,19.94,9.45,31.881t27.31,11.942q16.41,0,28.04-13.084l-1.45,8.723q-1.875,12.461-7.79,16.927t-15.27,4.465q-13.92,0-30.32-8.723l-13.09,25.754a86,86,0,0,0,21.4,9.553,77.9,77.9,0,0,0,22.22,3.531q20.145,0,32.92-6.231a45.069,45.069,0,0,0,19.94-19.107q7.155-12.88,10.07-33.854l12.67-89.93a86.612,86.612,0,0,0-23.89-9.866,103.435,103.435,0,0,0-25.13-3.219h0Zm-1.45,28.246a34.291,34.291,0,0,1,8.52,1.246l-6.65,43.616q-8.1,12.047-16.62,12.046-9.555,0-9.55-15.37a76.259,76.259,0,0,1,2.39-18.484,42.015,42.015,0,0,1,7.79-16.3,17.219,17.219,0,0,1,14.12-6.75h0Z"/>
</svg>

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 91 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 94 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 97 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.0 KiB

@ -0,0 +1,68 @@
/*!
* The buffer module from node.js, for the browser.
*
* @author Feross Aboukhadijeh <feross@feross.org> <http://feross.org>
* @license MIT
*/
/*!
* Cropper.js v1.5.12
* https://fengyuanchen.github.io/cropperjs
*
* Copyright 2015-present Chen Fengyuan
* Released under the MIT license
*
* Date: 2021-06-12T08:00:17.411Z
*/
/*!
* The buffer module from node.js, for the browser.
*
* @author Feross Aboukhadijeh <http://feross.org>
* @license MIT
*/
/*!
* Vue.js v2.6.12
* (c) 2014-2020 Evan You
* Released under the MIT License.
*/
/*!
* clipboard.js v2.0.8
* https://clipboardjs.com/
*
* Licensed MIT © Zeno Rocha
*/
/*! *****************************************************************************
Copyright (c) Microsoft Corporation.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
***************************************************************************** */
/*! Fabric.js Copyright 2008-2015, Printio (Juriy Zaytsev, Maxim Chernyak) */
/*! ieee754. BSD-3-Clause License. Feross Aboukhadijeh <https://feross.org/opensource> */
/**
* vue-class-component v7.0.1
* (c) 2015-present Evan You
* @license MIT
*/
/**!
* Sortable 1.10.2
* @author RubaXa <trash@rubaxa.org>
* @author owenm <owen23355@gmail.com>
* @license MIT
*/

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 154 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

@ -0,0 +1,92 @@
> The document uses Google Translate
<center>
![title](https://cdn.jsdelivr.net/gh/renzhezhilu/webp2jpg-online/cdn/og_image2.png)
![title](https://cdn.jsdelivr.net/gh/renzhezhilu/webp2jpg-online/cdn/badges/01.svg)
![title](https://cdn.jsdelivr.net/gh/renzhezhilu/webp2jpg-online/cdn/badges/02.svg)
![title](https://cdn.jsdelivr.net/gh/renzhezhilu/webp2jpg-online/cdn/badges/03.svg)
</center>
![title](https://cdn.jsdelivr.net/gh/renzhezhilu/webp2jpg-online/cdn/page_ui_en.jpg)
Introduction to webp2jpg-online
I often need to convert webp images to jpg format, and many of the functions provided by online conversion require uploading files, which sucks. There are non-uploads but the UI is difficult to use, Google later learned that html5 comes with a built-in interface called canvas. toBlob has the ability to convert images, so just do your own webp2jpg-online.
![title](https://cdn.jsdelivr.net/gh/renzhezhilu/webp2jpg-online/cdn/format2.png)
Online image format converter, jpeg, jpg, PNG, Gif, webp, svg, ICO, bmp files into Jpeg, PNG, webp, ICO, gif files. The conversion can be done locally without uploading the file
Online picture format converter, can convert jpeg, jpg, png, gif, webp, svg, ico, bmp files into jpeg, png, webp, ico, gif files. No need to upload files, conversion can be done locally。
## Main function
No UPLOADS, conversion using the browser itself
Batch translation outputs webp, jpeg, PNG, 8-bit PNG, gif animation, webp animation, base64
Output specified size (WEBP, jpeg)
Output number of colors (Gif, png-8)
Options can customize adding or removing a tick and persisting it
## Online address
https://renzhezhilu.github.io/webp2jpg-online/
## demo
![demo](https://cdn.jsdelivr.net/gh/renzhezhilu/webp2jpg-online/cdn/v2_demo.gif)
# plan #
[ ] Pull out the main function to make [img2img.js](https://github.com/renzhezhilu/img2img ) module (not started)
# # update the log
### v2.1 2020-08-17
New feature-output specified size
NEW FEATURE-COLOR COUNT OPTION (GIF, png-8)
New feature-automatic width output
New format-8-bit PNG
New format-base64
Fix-option delete function
Fix-multi-file download omission
Fix-compressed package file non-english garbled code
Fix-capital suffix not recognized
Fix-highlights that the prompt does not support file format
Delete the-ico output (false ICO is still PNG)
### v2.0 2020-06-26
Refactoring using vue
Support GIF GIF TO WEBP GIF
The size and picture quality can be customized
Option data persistence
Enable image append mode
Openable conversion comparison
Optimized the UI
Support for multiple languages
The page file is also bigger, which is slower to open the first time and faster after the second time
### [v1.0](https://github.com/renzhezhilu/webp2jpg-online/tree/v1.0) 2020-01-14
Project Establishment
Support for Jpeg, webp, PNG conversion
Optional output width
Optional output picture quality
Batch processing
Platform support
| | Google Chrome | Firefox | Apple Safari | Microsoft Edge | IE |
|---|-----|----|----|-----|---|
| Windows | ☑️ | ☑️ | - | ☑️ |-
|Mac OS|✔️|✔️|☑️|✔️|-|
|Iphone|☑️|☑️| ✔️ | - |-|
|Android|☑️|☑️|-| -|-|
> Something is running well? Untested
## ❤ thanks for the recommendation
[ tech enthusiast weekly (issue 114) : USB Survival and Uber-job ](http://www.ruanyifeng.com/blog/2020/07/weekly-issue-114.html )
## The core principle of image format conversion
### Canvas API
[HTMLCanvasElement.toBlob()](https://developer.mozilla.org/zh-CN/docs/Web/API/HTMLCanvasElement/toBlob)
``` javascript
canvas.toBlob(callback, type, encoderOptions);
```
### WebAssembly
[MDN:WebAssembly doc](https://developer.mozilla.org/zh-CN/docs/WebAssembly)
[wasm-im ](https://github.com/mk33mk333/wasm-im)
[ article: Web Assembly practice-using Imagemagick in a browser ](https://cloud.tencent.com/developer/article/1554176)
[(snapshot)](https://renzhezhilu.github.io/webp2jpg-online/doc/webassembly-using)

@ -0,0 +1,99 @@
> ドキュメントはGoogle翻訳を使用しています
<center>
![title](https://cdn.jsdelivr.net/gh/renzhezhilu/webp2jpg-online/cdn/og_image2.png)
![title](https://cdn.jsdelivr.net/gh/renzhezhilu/webp2jpg-online/cdn/badges/01.svg)
![title](https://cdn.jsdelivr.net/gh/renzhezhilu/webp2jpg-online/cdn/badges/02.svg)
![title](https://cdn.jsdelivr.net/gh/renzhezhilu/webp2jpg-online/cdn/badges/03.svg)
</center>
## webp2jpg-onlineの概要
![title](https://cdn.jsdelivr.net/gh/renzhezhilu/webp2jpg-online/cdn/page_ui_jp.jpg)
>私はしばしばwebp画像をjpg形式に変換する必要があり、オンライン変換によって提供される機能の多くはファイルのアップロードを必要とします。これは面倒です。アップロードはありませんが、UIは使いづらく、Googleは後でhtml5に組み込みcanvasと呼ばれるインターフェースでtoBlobは画像を変換する機能を備えているので、独自のwebp2jpg-onlineを実行するだけです。
オンライン画像形式コンバーター、jpeg、jpg、PNG、Gif、webp、svg、ICO、bmpファイルをJpeg、PNG、webp、ICO、gifファイルに変換します。ファイルをアップロードせずにローカルで変換できます
オンライン画像形式コンバーターは、jpeg、jpg、png、gif、webp、svg、ico、bmpファイルをjpeg、png、webp、ico、gifファイルに変換できます。ファイルをアップロードする必要はなく、変換はローカルで実行できます。
## 主な機能
アップロードなし、ブラウザ自体を使用した変換
バッチ変換は、webp、jpeg、PNG、8ビットPNG、gifアニメーション、webpアニメーション、base64を出力します
出力指定サイズ(WEBP、jpeg)
色の出力数(Gif、png-8)
オプションは、ティックの追加または削除と永続化をカスタマイズできます
![title](https://cdn.jsdelivr.net/gh/renzhezhilu/webp2jpg-online/cdn/format2.png)
## オンラインアドレス
https://renzhezhilu.github.io/webp2jpg-online/
## デモ
![title](https://cdn.jsdelivr.net/gh/renzhezhilu/webp2jpg-online/cdn/v2_demo.gif)
## 予定
[] main関数を引き出して[img2img.js](https://github.com/renzhezhilu/img2img)モジュールを作成します(開始されていません)
## グを更新
### v2.1 2020-08-17
新しい機能出力指定サイズ
新しい機能カラー数オプション(GIF、png-8)
新機能-自動幅出力
新しい形式の8ビットPNG
新しいformat-base64
修正オプション削除機能
複数ファイルのダウンロードの欠落を修正
修正圧縮されたパッケージファイルの英語以外の文字化けしたコード
大文字のサフィックスが認識されない
プロンプトがファイル形式をサポートしていないことを修正ハイライト
-ico出力を削除します(false ICOはPNGのままです)。
### v2.0 2020-06-26
vueを使用したリファクタリング
GIF GIFからWEBP GIFへのサポート
サイズと画質をカスタマイズできます
オプションデータの永続性
画像追加モードを有効にする
オープン可能な変換の比較
UIを最適化
複数言語のサポート
ページファイルも大きいため、最初に開くのが遅く、2回目以降は速くなります
### [v1.0](https://github.com/renzhezhilu/webp2jpg-online/tree/v1.0)2020-01-14
プロジェクト設立
Jpeg、webp、PNG変換のサポート
オプションの出力幅
オプションの出力画質
バッチ処理
プラットフォームサポート
| | Google Chrome | Firefox | Apple Safari | Microsoft Edge | IE |
| --- | ----- | ---- | ---- | ----- | --- |
| Windows|☑️|☑️|-|☑️|-
| Mac OS |✔️|✔️|☑️|✔️|-|
| iPhone |☑️|☑️|✔️|-|-|
| Android |☑️|☑️|-|-|-|
>正常に動作していますか?未テスト
##❤推奨に感謝
[技術愛好家、毎週(問題114)USBサバイバルとUberジョブ](http://www.ruanyifeng.com/blog/2020/07/weekly-issue-114.html)
##画像フォーマット変換の中核原理
### Canvas API
[HTMLCanvasElement.toBlob()](https://developer.mozilla.org/zh-CN/docs/Web/API/HTMLCanvasElement/toBlob)
`` `javascript
canvas.toBlob(callback、type、encoderOptions);
「」
### WebAssembly
[MDNWebAssembly doc](https://developer.mozilla.org/zh-CN/docs/WebAssembly)
[wasm-im](https://github.com/mk33mk333/wasm-im)
[記事Webアセンブリの実践-ブラウザーでImagemagickを使用する](https://cloud.tencent.com/developer/article/1554176)
[(スナップショット)](https://renzhezhilu.github.io/webp2jpg-online/doc/webassembly-using)

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 KiB

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -0,0 +1,16 @@
--------------------------------- 中文 --------------------------------------
https://renzhezhilu.github.io/webp2jpg-online
webp2jpg-online v3.0 离线版说明
1.请使用谷歌浏览器打开。
2.修改文件名会导致页面错误。convert.html 图片转换 & splicing.html 图片拼接)
3.第一次打开需要加载,加载完毕后无需网络也可使用。
---------------------------------- English ----------------------------------
https://renzhezhilu.github.io/webp2jpg-online
webp2jpg-online v3.0 offline version description
1. Please use Google Chrome to open.
2. Modifying the file name will cause a page fault.(convert.html & splicing.html)
3. It needs to be loaded when it is opened for the first time. After loading, it can be used without a network.

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -0,0 +1,16 @@
--------------------------------- 中文 --------------------------------------
https://renzhezhilu.github.io/webp2jpg-online
webp2jpg-online v3.0 离线版说明
1.请使用谷歌浏览器打开。
2.修改文件名会导致页面错误。convert.html 图片转换 & splicing.html 图片拼接)
3.第一次打开需要加载,加载完毕后无需网络也可使用。
---------------------------------- English ----------------------------------
https://renzhezhilu.github.io/webp2jpg-online
webp2jpg-online v3.0 offline version description
1. Please use Google Chrome to open.
2. Modifying the file name will cause a page fault.(convert.html & splicing.html)
3. It needs to be loaded when it is opened for the first time. After loading, it can be used without a network.

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 361 KiB

@ -0,0 +1,88 @@
<input type="file" id="files" accept=".jpeg,.jpg,.png,.gif,.webp,.svg,.ico,.bmp" multiple>
<canvas id="can" class="play-pause"></canvas>
<img id="imgsss" src="" alt="">
<script src="https://unpkg.com/konva@4.1.2/konva.min.js"></script>
<script src="https://unpkg.com/gifler@0.1.0/gifler.min.js"></script>
<script src="https://jnordberg.github.io/gif.js/gif.js?v=3"></script>
<script>
let input = document.getElementById("files")
let imgsss = document.getElementById("imgsss")
let _canvas = document.getElementById("can")
input.addEventListener('change', function() {
let files = [...this.files]
let b = window.URL.createObjectURL(files[0])
console.log(b)
// let img = new Image()
// img.src = b
// imgsss.src = b
// console.log(img)
// gifler(b)
// .animate('canvas.play-pause')
// .then(function(animator) {
// });
var gif = new GIF();
let CCC = 0
gifler(b).frames(_canvas, function(ctx, frame) {
CCC++
if (CCC > 10) {
gif.render();
gif.on('finished', function(blob) {
// window.open(URL.createObjectURL(blob));
funDownload(blob, `1234455.webp`)
});
return
}
// update canvas size
_canvas.width = frame.width;
_canvas.height = frame.height;
// update canvas that we are using for Konva.Image
_canvas.getContext("2d").drawImage(frame.buffer, 0, 0, this.width, this.height)
// redraw the layer
console.log(gif);
_canvas.toBlob(function(blob) {
let img = new Image()
img.src = window.URL.createObjectURL(blob)
gif.addFrame(img);
// funDownload(blob, `1234455.webp`)
console.log(blob);
}, `image/webp`, 0.1)
});
// img.onload = function() {
// _canvas.setAttribute("width", this.width)
// _canvas.setAttribute("height", this.height)
// _canvas.getContext("2d").drawImage(this, 0, 0, this.width, this.height)
// //转格式
// _canvas.toBlob(function(blob) {
// funDownload(blob, `${files[0].name}.webp`)
// }, `image/webp`, 0.1)
// }
// console.log(b)
}, false)
//下载文件
function funDownload(blob, filename = '未命名') {
let eleLink = document.createElement('a')
eleLink.download = filename
eleLink.style.display = 'none'
eleLink.href = URL.createObjectURL(blob)
// 触发点击
document.body.appendChild(eleLink)
eleLink.click()
// 然后移除
document.body.removeChild(eleLink)
// location.reload()
}
</script>

@ -0,0 +1,53 @@
# !/usr/bin/env python
import webbrowser
# import wx
import PySimpleGUI as sg
from wsgiref.simple_server import make_server
def hello_world_app(environ, start_response):
status = '200 OK' # HTTP Status
headers = [('Content-type', 'text/plain; charset=utf-8')] # HTTP Headers
start_response(status, headers)
msg = 'Hello %s\n' % environ["REMOTE_ADDR"]
return [msg.encode('utf8')]
with make_server('', 5678, hello_world_app) as httpd:
print("Serving on port 5678...")
httpd.serve_forever()
webbrowser.open('https://www.jianshu.com/p/d4eea5b503ed',
new=0, autoraise=True)
sg.theme('DarkAmber') # Add a touch of color
# All the stuff inside your window.
layout = [
[sg.Text('Some text on Row 1')],
[sg.Text('Enter something on Row 2'), sg.InputText()],
[sg.Button('Ok'), sg.Button('Cancel')]]
# Create the Window
window = sg.Window('Window Title', layout)
# Event Loop to process "events" and get the "values" of the inputs
while True:
event, values = window.read()
if event == sg.WIN_CLOSED or event == 'Cancel': # if user closes window or clicks cancel
break
print('You entered ', values[0])
window.close()
# app = wx.App(False) # Create a new app, don't redirect stdout/stderr to a window.
# frame = wx.Frame(None, wx.ID_ANY, "Hello222 World") # A Frame is a top-level window.
# frame.Show(True) # Show the frame.
# app.MainLoop()
# pyinstaller -F -D -w hello.py
# wxpython
# https://www.csdn.net/tags/MtTakg2sNTU2MTYtYmxvZwO0O0OO0O0O.html
# http://www.codebaoku.com/it-python/it-python-227355.html
# https://zhuanlan.zhihu.com/p/57674343
#

@ -0,0 +1,127 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: Helvetica,Arial, sans-serif;
}
.warnPageBox {
display: flex;
justify-content: center;
align-items: center;
width: 100vw;
height: 100vh;
position: fixed;
z-index: 9999999;
}
.warnPageBox > .bg{
position: absolute;
width: 100%;
height: 100%;
left: 0;
top: 0;
z-index: 1;
background-color: rgba(0, 0, 0, 0.3);
}
.warnPageBox > .con{
position: relative;
z-index: 10;
max-width: 600px;
width: 80%;
max-height: 100%;
overflow-y: auto;
border-radius: 30px;
background-color:seashell;
padding: 40px;
}
.warnPageBox a{
color: royalblue;
}
.warnPageBox .hr{
height: 1px;
width: 100%;
background-color: rgba(0, 0, 0, 0.3);
margin: 12px 0;
}
.warnPageBox button{
font-size: 18px;
padding: 10px 20px;
background-color:slategrey;
border: none;
color: white;
border-radius: 6px;
margin-right: 30px;
}
</style>
</head>
<body>
<div class="warnPageBox">
<div class="bg">
</div>
<div class="con">
<h1>⚠️ 不可访问预警</h1>
<br>
<p>这个图片处理工具依赖Gitee提供的Page服务我感觉以后可能有
<a href=""></a>
<a href="https://www.zhihu.com/question/535820467/answer/2520351399" target="_blank">
关闭的风险🦀️
</a>,所以在这里提供预备方案。</p>
<div class="hr"></div>
<b>方案01</b>
<p>
<a href="" target="_blank">
⬇️ 离线版Zip(17Mb)
</a>
<br>
<i>源代码html使用浏览器打开index.html和splicing.html即可使用</i>
</p>
<br>
<b>方案02 <small>其他链接</small> </b>
<p>
<a href="https://webp2jpg-online-b1u.pages.dev" target="_blank">
🔗 Cloudflare Page
</a>
|
<a href="https://webp2jpg-online-drab.vercel.app" target="_blank">
🔗 Vercel Page
</a>
|
<a href="https://renzhezhilu.github.io/webp2jpg-online/" target="_blank">
🔗 Github Page
</a>
</p>
<br>
<br>
<br>
<p>
<button>关闭</button>
</p>
</div>
</div>
</body>
</html>
<!--
https://webp2jpg-online-b1u.pages.dev/cdn/v3.0/images/logo.png
https://cdn.jsdelivr.net/gh/renzhezhilu/webp2jpg-online/cdn/v3.0/
./cdn/v3.0/
https://webp2jpg-online-drab.vercel.app/ -->

@ -0,0 +1,67 @@
<!DOCTYPE html>
<html>
<body>
<p>要使用的视频:</p>
<video id="video1" controls width="270" autoplay>
<source src="mov_bbb.mp4" type='video/mp4'>
</video>
<p>画布(每 20 毫秒,代码就会绘制视频的当前帧):</p>
<canvas id="myCanvas" width="270" height="135" style="border:1px solid #d3d3d3;">
Your browser does not support the HTML5 canvas tag.
</canvas>
<canvas id="ccccc" width="270" height="135" style="border:1px solid #d3d3d3;">
Your browser does not support the HTML5 canvas tag.
</canvas>
<img id="img" src="./g.gif" alt="">
<script>
// var v = document.getElementById("video1");
// var c = document.getElementById("myCanvas");
// ctx = c.getContext('2d');
// v.addEventListener('play', function() {
// var i = window.setInterval(function() {
// ctx.drawImage(v, 0, 0, 270, 135)
// }, 20);
// }, false);
// v.addEventListener('pause', function() {
// window.clearInterval(i);
// }, false);
// v.addEventListener('ended', function() {
// clearInterval(i);
// }, false);
// let xhr = new XMLHttpRequest();
// xhr.open('get', './g.gif');
// xhr.setRequestHeader("Content-Type", "image/gif");
// xhr.send();
// xhr.onreadystatechange = function() {
// if (xhr.readyState === 4) {
// if (xhr.status === 200) {
// console.log('response', xhr.response);
// }
// }
// }
const img = document.getElementById("img");
const ccc = document.getElementById("ccccc");
const ctx22 = ccc.getContext('2d');
render();
function render() {
ctx22.drawImage(img, 0, 0);
window.requestAnimationFrame(render);
}
</script>
</body>
</html>

@ -0,0 +1,315 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Page Title</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<script>
var Groover = (function() {
// ensure webp is supported
function canEncode() {
var canvas = document.createElement("canvas");
canvas.width = 8;
canvas.height = 8;
return canvas.toDataURL("image/webp", 0.1).indexOf("image/webp") > -1;
}
if (!canEncode()) {
return undefined;
}
var webmData = null;
var clusterTimecode = 0;
var clusterCounter = 0;
var CLUSTER_MAX_DURATION = 30000;
var frameNumber = 0;
var width;
var height;
var frameDelay;
var quality;
var name;
const videoMimeType = "video/webm"; // the only one.
const frameMimeType = 'image/webp'; // can be no other
const S = String.fromCharCode;
const dataTypes = {
object: function(data) {
return toBlob(data);
},
number: function(data) {
return stream.num(data);
},
string: function(data) {
return stream.str(data);
},
array: function(data) {
return data;
},
double2Str: function(num) {
var c = new Uint8Array((new Float64Array([num])).buffer);
return S(c[7]) + S(c[6]) + S(c[5]) + S(c[4]) + S(c[3]) + S(c[2]) + S(c[1]) + S(c[0]);
}
};
const stream = {
num: function(num) { // writes int
var parts = [];
while (num > 0) {
parts.push(num & 0xff);
num = num >> 8;
}
return new Uint8Array(parts.reverse());
},
str: function(str) { // writes string
var i, len, arr;
len = str.length;
arr = new Uint8Array(len);
for (i = 0; i < len; i++) {
arr[i] = str.charCodeAt(i);
}
return arr;
},
compInt: function(num) { // could not find full details so bit of a guess
if (num < 128) { // number is prefixed with a bit (1000 is on byte 0100 two, 0010 three and so on)
num += 0x80;
return new Uint8Array([num]);
} else
if (num < 0x4000) {
num += 0x4000;
return new Uint8Array([num >> 8, num])
} else
if (num < 0x200000) {
num += 0x200000;
return new Uint8Array([num >> 16, num >> 8, num])
} else
if (num < 0x10000000) {
num += 0x10000000;
return new Uint8Array([num >> 24, num >> 16, num >> 8, num])
}
}
}
const ids = { // header names and values
videoData: 0x1a45dfa3,
Version: 0x4286,
ReadVersion: 0x42f7,
MaxIDLength: 0x42f2,
MaxSizeLength: 0x42f3,
DocType: 0x4282,
DocTypeVersion: 0x4287,
DocTypeReadVersion: 0x4285,
Segment: 0x18538067,
Info: 0x1549a966,
TimecodeScale: 0x2ad7b1,
MuxingApp: 0x4d80,
WritingApp: 0x5741,
Duration: 0x4489,
Tracks: 0x1654ae6b,
TrackEntry: 0xae,
TrackNumber: 0xd7,
TrackUID: 0x63c5,
FlagLacing: 0x9c,
Language: 0x22b59c,
CodecID: 0x86,
CodecName: 0x258688,
TrackType: 0x83,
Video: 0xe0,
PixelWidth: 0xb0,
PixelHeight: 0xba,
Cluster: 0x1f43b675,
Timecode: 0xe7,
Frame: 0xa3,
Keyframe: 0x9d012a,
FrameBlock: 0x81,
};
const keyframeD64Header = '\x9d\x01\x2a'; //VP8 keyframe header 0x9d012a
const videoDataPos = 1; // data pos of frame data header
const defaultDelay = dataTypes.double2Str(1000 / 25);
const header = [ // structure of webM header/chunks what ever they are called.
ids.videoData, [
ids.Version, 1,
ids.ReadVersion, 1,
ids.MaxIDLength, 4,
ids.MaxSizeLength, 8,
ids.DocType, 'webm',
ids.DocTypeVersion, 2,
ids.DocTypeReadVersion, 2
],
ids.Segment, [
ids.Info, [
ids.TimecodeScale, 1000000,
ids.MuxingApp, 'Groover',
ids.WritingApp, 'Groover',
ids.Duration, 0
],
ids.Tracks, [
ids.TrackEntry, [
ids.TrackNumber, 1,
ids.TrackUID, 1,
ids.FlagLacing, 0, // always o
ids.Language, 'und', // undefined I think this means
ids.CodecID, 'V_VP8', // These I think must not change
ids.CodecName, 'VP8', // These I think must not change
ids.TrackType, 1,
ids.Video, [
ids.PixelWidth, 0,
ids.PixelHeight, 0
]
]
]
]
];
function getHeader() {
header[3][2][3] = name;
header[3][2][5] = name;
header[3][2][7] = dataTypes.double2Str(frameDelay);
header[3][3][1][15][1] = width;
header[3][3][1][15][3] = height;
function create(dat) {
var i, kv, data;
data = [];
for (i = 0; i < dat.length; i += 2) {
kv = {
i: dat[i]
};
if (Array.isArray(dat[i + 1])) {
kv.d = create(dat[i + 1]);
} else {
kv.d = dat[i + 1];
}
data.push(kv);
}
return data;
}
return create(header);
}
function addCluster() {
webmData[videoDataPos].d.push({
i: ids.Cluster,
d: [{
i: ids.Timecode,
d: Math.round(clusterTimecode)
}]
}); // Fixed bug with Round
clusterCounter = 0;
}
function addFrame(frame) {
var VP8, kfS, riff;
riff = getWebPChunks(atob(frame.toDataURL(frameMimeType, quality).slice(23)));
VP8 = riff.RIFF[0].WEBP[0];
kfS = VP8.indexOf(keyframeD64Header) + 3;
frame = {
width: ((VP8.charCodeAt(kfS + 1) << 8) | VP8.charCodeAt(kfS)) & 0x3FFF,
height: ((VP8.charCodeAt(kfS + 3) << 8) | VP8.charCodeAt(kfS + 2)) & 0x3FFF,
data: VP8,
riff: riff
};
if (clusterCounter > CLUSTER_MAX_DURATION) {
addCluster();
}
webmData[videoDataPos].d[webmData[videoDataPos].d.length - 1].d.push({
i: ids.Frame,
d: S(ids.FrameBlock) + S(Math.round(clusterCounter) >> 8) + S(Math.round(clusterCounter) & 0xff) + S(128) + frame.data.slice(4),
});
clusterCounter += frameDelay;
clusterTimecode += frameDelay;
webmData[videoDataPos].d[0].d[3].d = dataTypes.double2Str(clusterTimecode);
}
function startEncoding() {
frameNumber = clusterCounter = clusterTimecode = 0;
webmData = getHeader();
addCluster();
}
function toBlob(vidData) {
var data, i, vData, len;
vData = [];
for (i = 0; i < vidData.length; i++) {
data = dataTypes[typeof vidData[i].d](vidData[i].d);
len = data.size || data.byteLength || data.length;
vData.push(stream.num(vidData[i].i));
vData.push(stream.compInt(len));
vData.push(data)
}
return new Blob(vData, {
type: videoMimeType
});
}
function getWebPChunks(str) {
var offset, chunks, id, len, data;
offset = 0;
chunks = {};
while (offset < str.length) {
id = str.substr(offset, 4);
// value will have top bit on (bit 32) so not simply a bitwise operation
// Warning little endian (Will not work on big endian systems)
len = new Uint32Array(
new Uint8Array([
str.charCodeAt(offset + 7),
str.charCodeAt(offset + 6),
str.charCodeAt(offset + 5),
str.charCodeAt(offset + 4)
]).buffer)[0];
id = str.substr(offset, 4);
chunks[id] = chunks[id] === undefined ? [] : chunks[id];
if (id === 'RIFF' || id === 'LIST') {
chunks[id].push(getWebPChunks(str.substr(offset + 8, len)));
offset += 8 + len;
} else if (id === 'WEBP') {
chunks[id].push(str.substr(offset + 8));
break;
} else {
chunks[id].push(str.substr(offset + 4));
break;
}
}
return chunks;
}
function Encoder(fps, _quality = 0.8, _name = "Groover") {
this.fps = fps;
this.quality = quality = _quality;
this.frameDelay = frameDelay = 1000 / fps;
this.frame = 0;
this.width = width = null;
this.timecode = 0;
this.name = name = _name;
}
Encoder.prototype = {
addFrame: function(frame) {
if ('canvas' in frame) {
frame = frame.canvas;
}
if (width === null) {
this.width = width = frame.width,
this.height = height = frame.height
startEncoding();
} else
if (width !== frame.width || height !== frame.height) {
throw RangeError("Frame size error. Frames must be the same size.");
}
addFrame(frame);
this.frame += 1;
this.timecode = clusterTimecode;
},
toBlob: function() {
return toBlob(webmData);
}
}
return {
Video: Encoder,
}
})()
</script>
</body>
</html>

@ -0,0 +1,82 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<img id="testImg" src="js_gif.gif" width="224" height="126">
<p><input type="button" id="testBtn" value="停止"></p>
<script>
if ('getContext' in document.createElement('canvas')) {
HTMLImageElement.prototype.play = function() {
if (this.storeCanvas) {
// 移除存储的canvas
this.storeCanvas.parentElement.removeChild(this.storeCanvas);
this.storeCanvas = null;
// 透明度还原
image.style.opacity = '';
}
if (this.storeUrl) {
this.src = this.storeUrl;
}
};
HTMLImageElement.prototype.stop = function() {
var canvas = document.createElement('canvas');
// 尺寸
var width = this.width,
height = this.height;
if (width && height) {
// 存储之前的地址
if (!this.storeUrl) {
this.storeUrl = this.src;
}
// canvas大小
canvas.width = width;
canvas.height = height;
// 绘制图片帧(第一帧)
canvas.getContext('2d').drawImage(this, 0, 0, width, height);
// 重置当前图片
try {
this.src = canvas.toDataURL("image/gif");
} catch (e) {
// 跨域
this.removeAttribute('src');
// 载入canvas元素
canvas.style.position = 'absolute';
// 前面插入图片
this.parentElement.insertBefore(canvas, this);
// 隐藏原图
this.style.opacity = '0';
// 存储canvas
this.storeCanvas = canvas;
}
}
};
}
var image = document.getElementById("testImg"),
button = document.getElementById("testBtn");
if (image && button) {
button.onclick = function() {
if (this.value == '停止') {
image.stop();
this.value = '播放';
} else {
image.play();
this.value = '停止';
}
};
}
</script>
</body>
</html>

@ -0,0 +1,130 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Page Title</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<input id="files" type="file" multiple />
<h4 id="t1"></h4>
<img id="img01" src="" alt="">
<canvas id="can"></canvas>
<h4 id="t2"></h4>
<img id="img02" src="" alt="">
<script>
/*
直接设置输出质量+-0.1来预测输出合适的size太死板了
尝试这样的算法
01.判断现有图片已经被压缩的比例
size /widhth * height
172112 / (500 * 500) = 0.688448
02.需要压缩的比例
size /widhth * height
60000 / (500 * 500) = 0.24
图片尺寸
*/
let input = document.getElementById("files")
let img01 = document.getElementById("img01")
let img02 = document.getElementById("img02")
input.addEventListener('change', function() {
console.log(this.files[0]);
let files = this.files
let img = new Image()
img.src = URL.createObjectURL(this.files[0])
img.onload = function() {
console.log(this);
// document.body.appendChild(this);
let _canvas = document.getElementById("can")
//处理缩放
let w = this.width
let h = this.height
// console.log(new Blob(img,'image/jpg'));
_canvas.setAttribute("width", w)
_canvas.setAttribute("height", h)
_canvas.getContext("2d").drawImage(this, 0, 0, w, h)
//转格式
console.log(_canvas);
// let base64_ok = _canvas.toDataURL(`image/${type}`, quality)
let s = 70000
let z1 = files[0].size / (this.width * this.height)
let z2 = s / (this.width * this.height)
let i = s / files[0].size
if (i > 1) i = 1
if (i < 0) i = 0.01
// let i = this.files[0].size / (this.width*this.height)
// setSizeFun(s, i)
setSizeFun(s, 1)
function setSizeFun(setSize, q) {
//本来的图片就很小了
if (files[0].size < setSize) {
// let b = new Blob([files[0]], {
// type: files[0].type
// })
// _canvas.toBlob(function(blob) {
// console.log( blob,'原样输出');
// }, `image/jpeg`, 1)
// return
}
let qu = q
let sizeAfter
_canvas.toBlob(function(blob) {
img02.src = URL.createObjectURL(blob)
sizeAfter = blob.size
console.log(blob, `setSize:`, setSize, `q:`, q);
//合格
if (setSize > sizeAfter && setSize * 0.9 < sizeAfter) {
console.log(blob, '✅✅✅✅');
} else {
// if (setSize < sizeAfter) qu = qu -0.005
// else qu = qu +0.005
// let yuan = Math.abs((qu * setSize / sizeAfter)-qu)
// let di = 0
// if (yuan<0.002) {
// di = 0.002
// }
qu = qu * setSize / sizeAfter
// if (qu < 0) {
// console.warn('没有合适的');
// return
// }
// if (qu > 1 && setSize > sizeAfter && setSize * 0.9 < sizeAfter) {
// console.log(blob, '最大输出质量✅✅✅✅');
// return
// }
if (qu > 1 || qu < 0) {
if (setSize > sizeAfter) {
console.log(blob, '最大输出质量✅✅✅✅');
} else {
console.warn('没有合适的');
}
return
}
console.log('继续');
setSizeFun(setSize, qu)
}
}, `image/jpeg`, q)
}
}
}, false)
</script>
</body>
</html>

@ -0,0 +1,102 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Page Title</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<input id="files" type="file" multiple />
<h4 id="t1"></h4>
<img id="img01" src="" alt="">
<canvas id="can"></canvas>
<h4 id="t2"></h4>
<img id="img02" src="" alt="">
<script>
let input = document.getElementById("files")
let img01 = document.getElementById("img01")
let img02 = document.getElementById("img02")
input.addEventListener('change', function() {
console.log(this.files[0]);
let files = this.files
let img = new Image()
let count = 0
img.src = URL.createObjectURL(this.files[0])
img.onload = function() {
console.log(this);
let _canvas = document.getElementById("can")
//处理缩放
let w = this.width
let h = this.height
_canvas.setAttribute("width", w)
_canvas.setAttribute("height", h)
_canvas.getContext("2d").drawImage(this, 0, 0, w, h)
//转格式
console.log(_canvas);
//输出100%质量
_canvas.toBlob(function(blob) {
console.log(blob, '完成0.81');
let size = 1024 * 100 //预设值
size = size - 4000 //默认簇
let skip = 0.01 //变化幅度
let maxSize = blob.size //1压缩
//先预判图片压缩后的大小再微调
let yu = size > maxSize ? 0.81 * 0.81 : 0.81
let startQu = size / maxSize * yu
if (startQu >= 1) startQu = 0.99
if (startQu <= 0) startQu = 0.01
setSizeFun(size, startQu.toFixed(2) - 0)
function setSizeFun(setSize, qu) {
_canvas.toBlob(function(blob22) {
console.log('count:', count++);
// let isLess = blob22.size < setSize
console.log(blob22, qu, '继续');
img02.src = URL.createObjectURL(blob22)
let bSize = blob22.size
//符合条件区间
if (bSize > setSize * 0.9 && bSize < setSize) {
console.log(blob22, URL.createObjectURL(blob22), qu, '完成✅✅✅');
return
}
//原图太小,
if (qu >= 0.95 && bSize < setSize) {
console.warn(blob22, qu, URL.createObjectURL(blob22), '最大输出✅');
return
}
//压缩不到制定的大小
if (qu < 0.0001 && bSize > setSize) {
console.error(blob22, qu, URL.createObjectURL(blob22), '没有符合的🙅');
return
}
if (qu < 0.0001 && bSize < setSize) {
console.warn(blob22, qu, URL.createObjectURL(blob22), '最小输出✅');
return
}
//微调
if (bSize < setSize) {
qu = qu + skip
} else {
qu = qu - skip
}
setSizeFun(setSize, qu.toFixed(2) - 0)
}, `image/webp`, qu)
}
}, `image/webp`, 0.81)
}
}, false)
</script>
</body>
</html>

@ -0,0 +1,139 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Page Title</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<input id="files" type="file" multiple />
<h4 id="t1"></h4>
<img id="img01" src="" alt="">
<canvas id="can"></canvas>
<h4 id="t2"></h4>
<img id="img02" src="" alt="">
<script>
let input = document.getElementById("files")
let img01 = document.getElementById("img01")
let img02 = document.getElementById("img02")
input.addEventListener('change', function() {
console.log(this.files[0]);
let files = this.files
let img = new Image()
img.src = URL.createObjectURL(this.files[0])
img.onload = async function() {
console.log(this);
let jg = await funMaxSize({
defWidth:this.width,
defHeight:this.height,
setWidth:400,
setHeight:null,
imageData:this,
setSize:88
})
// let b= new Blob(this)
// URL.createObjectURL(b)
console.log('😊 结果:',jg,JSON.stringify(this),);
}
}, false)
function funMaxSize({
defWidth,
defHeight,
setWidth,
setHeight,
imageData,
setSize=100 //kb
}) {
return new Promise((res, rej) => {
let arg = arguments[0]
let count = 0
let _canvas = document.getElementById("can")
//处理缩放
let w = arg.setWidth || arg.defWidth
let h = arg.setHeight || (arg.setWidth/arg.defWidth) * arg.defHeight
_canvas.setAttribute("width", w)
_canvas.setAttribute("height", h)
_canvas.getContext("2d").drawImage(arg.imageData, 0, 0, w, h)
//转格式
console.log(_canvas);
//输出100%质量
_canvas.toBlob(function(blob) {
console.log(blob, '完成0.81');
// let size = 1024 * 100 //预设值
let size = arg.setSize * 1000 //预设值
size = size - 4000 //默认簇
let skip = 0.01 //变化幅度
let maxSize = blob.size //1压缩
//先预判图片压缩后的大小再微调
let yu = size > maxSize ? 0.81 * 0.81 : 0.81
let startQu = size / maxSize * yu
if (startQu >= 1) startQu = 0.99
if (startQu <= 0) startQu = 0.01
setSizeFun(size, startQu.toFixed(2) - 0)
function setSizeFun(setSize, qu) {
_canvas.toBlob(function(blob22) {
console.log('count:', count++);
// let isLess = blob22.size < setSize
console.log(blob22, qu, '继续');
img02.src = URL.createObjectURL(blob22)
let bSize = blob22.size
//符合条件区间
if (bSize > setSize * 0.9 && bSize < setSize) {
console.log(blob22, URL.createObjectURL(blob22), qu, '完成✅✅✅');
res(URL.createObjectURL(blob22))
return
}
//原图太小,
if (qu >= 0.95 && bSize < setSize) {
console.warn(blob22, qu, URL.createObjectURL(blob22), '最大输出✅');
res(URL.createObjectURL(blob22))
return
}
//压缩不到制定的大小
if (qu < 0.0001 && bSize > setSize) {
console.error(blob22, qu, URL.createObjectURL(blob22), '没有符合的🙅');
rej(URL.createObjectURL(blob22))
return
}
if (qu < 0.0001 && bSize < setSize) {
console.warn(blob22, qu, URL.createObjectURL(blob22), '最小输出✅');
res(URL.createObjectURL(blob22))
return
}
//微调
if (bSize < setSize) {
qu = qu + skip
} else {
qu = qu - skip
}
setSizeFun(setSize, qu.toFixed(2) - 0)
}, `image/webp`, qu)
}
}, `image/webp`, 0.81)
})
}
</script>
</body>
</html>

@ -0,0 +1,217 @@
<!DOCTYPE html>
<html lang=en>
<head>
<meta charset=utf-8>
<title>webp2jpg-online-在线图片格式转化器(无需上传)-web2jpg-Online image format converter (no upload
required)-web2jpg-オンライン画像形式コンバーター(アップロード不要)-web2jpg-Convertidor de formato de imagen en línea (no requiere
carga)</title>
<meta http-equiv=X-UA-Compatible content="IE=edge,chrome=1">
<meta name=viewport content="width=device-width,initial-scale=1">
<meta name=description
content="在线图片格式转化器,可将jpeg、jpg、png、gif、webp、svg、ico、bmp文件转化为jpeg、png、webp、ico文件。无需上传文件本地即可完成转换。Online picture format converter, can convert jpeg, jpg, png, gif, webp, svg, ico, bmp files into jpeg, png, webp, ico files. No need to upload files, conversion can be done locally。オンライン画像形式コンバータは、jpeg、jpg、png、gif、webp、svg、ico、bmpファイルをjpeg、png、webp、icoファイルに変換できます。 ファイルをアップロードする必要はありません。変換はローカルで実行できます。Convertidor de formato de imagen en línea, puede convertir archivos jpeg, jpg, png, gif, webp, svg, ico, bmp en archivos jpeg, png, webp, ico. No es necesario cargar archivos, la conversión se puede hacer localmente">
<meta name=author content=renzhezhilu,https://github.com/renzhezhilu/webp2jpg-online>
<meta name=keywords
content="webp2jpg,png2jpg,gif2jpg,svg2jpg,ico2jpg,bmp2jpg,jpg2webp,jpg2webp,png2webp,gif2webp,svg2webp,ico2webp,bmp2webp,jpg2png,webp2png,gif2png,svg2png,ico2png,bmp2png,webp to jpg,png to jpg,gif to jpg,svg to jpg,ico to jpg,bmp to jpg,jpg to webp,jpg to webp,png to webp,gif to webp,svg to webp,ico to webp,bmp to webp,jpg to png,webp to png,gif to png,svg to png,ico to png,bmp to png,webp 转 jpg,png 转 jpg,gif 转 jpg,svg 转 jpg,ico 转 jpg,bmp 转 jpg,jpg 转 webp,jpg 转 webp,png 转 webp,gif 转 webp,svg 转 webp,ico 转 webp,bmp 转 webp,jpg 转 png,webp 转 png,gif 转 png,svg 转 png,ico 转 png,bmp 转 png,html图片转换,图片本地转换,图片格式转换,,转化至jpg、webp、png、ico,Convert to JPG,Convert to webp,Convert to png,Convert to ico">
<meta name=robots
content="webp2jpg,png2jpg,gif2jpg,svg2jpg,ico2jpg,bmp2jpg,jpg2webp,jpg2webp,png2webp,gif2webp,svg2webp,ico2webp,bmp2webp,jpg2png,webp2png,gif2png,svg2png,ico2png,bmp2png,webp to jpg,png to jpg,gif to jpg,svg to jpg,ico to jpg,bmp to jpg,jpg to webp,jpg to webp,png to webp,gif to webp,svg to webp,ico to webp,bmp to webp,jpg to png,webp to png,gif to png,svg to png,ico to png,bmp to png,webp 转 jpg,png 转 jpg,gif 转 jpg,svg 转 jpg,ico 转 jpg,bmp 转 jpg,jpg 转 webp,jpg 转 webp,png 转 webp,gif 转 webp,svg 转 webp,ico 转 webp,bmp 转 webp,jpg 转 png,webp 转 png,gif 转 png,svg 转 png,ico 转 png,bmp 转 png,html图片转换,图片本地转换,图片格式转换,,转化至jpg、webp、png、ico,Convert to JPG,Convert to webp,Convert to png,Convert to ico">
<meta name=google
content="webp2jpg,png2jpg,gif2jpg,svg2jpg,ico2jpg,bmp2jpg,jpg2webp,jpg2webp,png2webp,gif2webp,svg2webp,ico2webp,bmp2webp,jpg2png,webp2png,gif2png,svg2png,ico2png,bmp2png,webp to jpg,png to jpg,gif to jpg,svg to jpg,ico to jpg,bmp to jpg,jpg to webp,jpg to webp,png to webp,gif to webp,svg to webp,ico to webp,bmp to webp,jpg to png,webp to png,gif to png,svg to png,ico to png,bmp to png,webp 转 jpg,png 转 jpg,gif 转 jpg,svg 转 jpg,ico 转 jpg,bmp 转 jpg,jpg 转 webp,jpg 转 webp,png 转 webp,gif 转 webp,svg 转 webp,ico 转 webp,bmp 转 webp,jpg 转 png,webp 转 png,gif 转 png,svg 转 png,ico 转 png,bmp 转 png,html图片转换,图片本地转换,图片格式转换,,转化至jpg、webp、png、ico,Convert to JPG,Convert to webp,Convert to png,Convert to ico">
<meta name=googlebot
content="webp2jpg,png2jpg,gif2jpg,svg2jpg,ico2jpg,bmp2jpg,jpg2webp,jpg2webp,png2webp,gif2webp,svg2webp,ico2webp,bmp2webp,jpg2png,webp2png,gif2png,svg2png,ico2png,bmp2png,webp to jpg,png to jpg,gif to jpg,svg to jpg,ico to jpg,bmp to jpg,jpg to webp,jpg to webp,png to webp,gif to webp,svg to webp,ico to webp,bmp to webp,jpg to png,webp to png,gif to png,svg to png,ico to png,bmp to png,webp 转 jpg,png 转 jpg,gif 转 jpg,svg 转 jpg,ico 转 jpg,bmp 转 jpg,jpg 转 webp,jpg 转 webp,png 转 webp,gif 转 webp,svg 转 webp,ico 转 webp,bmp 转 webp,jpg 转 png,webp 转 png,gif 转 png,svg 转 png,ico 转 png,bmp 转 png,html图片转换,图片本地转换,图片格式转换,,转化至jpg、webp、png、ico,Convert to JPG,Convert to webp,Convert to png,Convert to ico">
<meta name=baidu
content="webp2jpg,png2jpg,gif2jpg,svg2jpg,ico2jpg,bmp2jpg,jpg2webp,jpg2webp,png2webp,gif2webp,svg2webp,ico2webp,bmp2webp,jpg2png,webp2png,gif2png,svg2png,ico2png,bmp2png,webp to jpg,png to jpg,gif to jpg,svg to jpg,ico to jpg,bmp to jpg,jpg to webp,jpg to webp,png to webp,gif to webp,svg to webp,ico to webp,bmp to webp,jpg to png,webp to png,gif to png,svg to png,ico to png,bmp to png,webp 转 jpg,png 转 jpg,gif 转 jpg,svg 转 jpg,ico 转 jpg,bmp 转 jpg,jpg 转 webp,jpg 转 webp,png 转 webp,gif 转 webp,svg 转 webp,ico 转 webp,bmp 转 webp,jpg 转 png,webp 转 png,gif 转 png,svg 转 png,ico 转 png,bmp 转 png,html图片转换,图片本地转换,图片格式转换,,转化至jpg、webp、png、ico,Convert to JPG,Convert to webp,Convert to png,Convert to ico">
<meta name=verify
content="webp2jpg,png2jpg,gif2jpg,svg2jpg,ico2jpg,bmp2jpg,jpg2webp,jpg2webp,png2webp,gif2webp,svg2webp,ico2webp,bmp2webp,jpg2png,webp2png,gif2png,svg2png,ico2png,bmp2png,webp to jpg,png to jpg,gif to jpg,svg to jpg,ico to jpg,bmp to jpg,jpg to webp,jpg to webp,png to webp,gif to webp,svg to webp,ico to webp,bmp to webp,jpg to png,webp to png,gif to png,svg to png,ico to png,bmp to png,webp 转 jpg,png 转 jpg,gif 转 jpg,svg 转 jpg,ico 转 jpg,bmp 转 jpg,jpg 转 webp,jpg 转 webp,png 转 webp,gif 转 webp,svg 转 webp,ico 转 webp,bmp 转 webp,jpg 转 png,webp 转 png,gif 转 png,svg 转 png,ico 转 png,bmp 转 png,html图片转换,图片本地转换,图片格式转换,,转化至jpg、webp、png、ico,Convert to JPG,Convert to webp,Convert to png,Convert to ico">
<meta name=apple-mobile-web-app-capable content=yes>
<meta name=apple-mobile-web-app-status-bar-style content=black-translucent>
<meta name=format-detection content="telephone=no, email=no">
<meta name=HandheldFriendly content=true>
<meta name=MobileOptimized content=320>
<meta property=og:site_name content="webp2jpg-online-Picture converter">
<meta property=og:title
content="webp2jpg-online-在线图片格式转化器(无需上传)-web2jpg-Online image format converter (no upload required)">
<meta property=og:description
content="在线图片格式转化器,可将jpeg、jpg、png、gif、webp、svg、ico、bmp文件转化为jpeg、png、webp、ico文件。无需上传文件本地即可完成转换。Online picture format converter, can convert jpeg, jpg, png, gif, webp, svg, ico, bmp files into jpeg, png, webp, ico files. No need to upload files, conversion can be done locally。オンライン画像形式コンバータは、jpeg、jpg、png、gif、webp、svg、ico、bmpファイルをjpeg、png、webp、icoファイルに変換できます。 ファイルをアップロードする必要はありません。変換はローカルで実行できます。Convertidor de formato de imagen en línea, puede convertir archivos jpeg, jpg, png, gif, webp, svg, ico, bmp en archivos jpeg, png, webp, ico. No es necesario cargar archivos, la conversión se puede hacer localmente">
<meta property=og:image content=https://cdn.jsdelivr.net/gh/renzhezhilu/webp2jpg-online/cdn/og_image.png>
<meta property=og:url content=https://renzhezhilu.github.io/webp2jpg-online />
<meta property=og:type content=article>
<link rel=apple-touch-icon href=https://cdn.jsdelivr.net/gh/renzhezhilu/webp2jpg-online/cdn/apple-touch-iphone.png>
<link rel="shortcut icon" href=https://cdn.jsdelivr.net/gh/renzhezhilu/webp2jpg-online/cdn/favicon.ico>
<style>
#page_loading {
position: fixed;
z-index: 10000;
width: 100%;
height: 100%;
background-color: #fff;
display: flex;
justify-content: center;
align-items: center;
font-size: 26px;
line-height: 26px;
font-weight: 100;
font-family: Avenir, "微软雅黑", Helvetica, Arial, sans-serif;
}
#page_loading,
#page_loading * {
list-style: none;
box-sizing: border-box;
padding: 0;
margin: 0;
}
</style>
</head>
<body>
<style>
#banner1 {
position: fixed;
bottom: 0;
right: 0;
z-index: 99999;
}
</style>
<a id="banner1" href="./batch.html" target="_blank"><img
src="https://cdn.jsdelivr.net/gh/renzhezhilu/webp2jpg-online/cdn/batch/banner.png" alt="">
</a>
<div id=page_loading>
<div>
<div><span id=page_loading_num style="font-size:80px;line-height: 80px;">0</span> %</div>
<p>loading...</p>
</div>
</div><noscript><strong>We're sorry but v.2.0.0 doesn't work properly without JavaScript enabled. Please enable it
to continue.</strong></noscript>
<div id=app></div>
<script src=https://cdn.jsdelivr.net/gh/renzhezhilu/webp2jpg-online/cdn/localforage.min.js> </script>
<script>
var Module = {}
var lastVer = 'v2.2.61'
var squooshWasm = {}
</script>
<script>
!async function () {
let nowVer = await localforage.getItem('version')
if (nowVer !== lastVer) {
await localforage.clear()
console.log('版本更新');
setTimeout(() => {
GO()
}, 100);
} else {
GO()
}
}()
function creatScript(src, name) {
let body = document.querySelector('body')
let script = document.createElement('script')
script.src = src
script.className = name
body.appendChild(script)
}
async function fileSaveLocal(fileUrl, name) {
try {
const isHave = await localforage.getItem(name);
if (isHave) {
console.log('本地已存在');
let val = await localforage.getItem(name)
console.log(val);
return {
url: URL.createObjectURL(val),
local: true,
name: name
}
} else {
console.log('本地不存在,重新请求');
let blob = await fetch(fileUrl)
.then(d => d.blob())
await localforage.setItem(name, blob)
let val = await localforage.getItem(name)
console.log(val);
return {
url: URL.createObjectURL(val),
local: false,
name: name
}
}
} catch (err) {
console.log(err);
}
}
async function GO() {
let loading = document.getElementById('page_loading')
let num = document.getElementById('page_loading_num')
let wasmjs_dom = document.getElementById('wasmjs')
let get = [{
url: 'https://cdn.jsdelivr.net/gh/renzhezhilu/webp2jpg-online/cdn/wasm-im.wasm',
name: 'webp2jpg_wasm-im.wasm'
},
{
url: 'https://cdn.jsdelivr.net/gh/renzhezhilu/webp2jpg-online/cdn/wasm-im.js',
name: 'webp2jpg_wasm-im.js'
},
{
url: 'https://cdn.jsdelivr.net/gh/renzhezhilu/webp2jpg-online/cdn/squoosh/avif_enc.wasm',
name: 'webp2jpg_avif_enc.wasm'
},
{
url: 'https://cdn.jsdelivr.net/gh/renzhezhilu/webp2jpg-online/cdn/squoosh/mozjpeg_enc.wasm',
name: 'webp2jpg_mozjpeg_enc.wasm'
},
{
url: 'https://cdn.jsdelivr.net/gh/renzhezhilu/webp2jpg-online/cdn/dist_js/webp2jpg_app20201225_____.js',
name: 'webp2jpg_app20201225.js'
},
]
let ok = []
get.map((m, index) => {
fileSaveLocal(m.url, m.name)
.then(async (d) => {
ok.push(d)
get = get.map(m => {
ok.map(a => {
if (a.name === m.name) m.url = a.url
})
return m
})
num.textContent = ((index / get.length * 100).toFixed(0) - 0)
if (ok.length === get.length) {
if (ok.every(e => e.local)) {
console.log('完成。。。。', ok);
Module.locateFile = _ => get.filter(m => m.name ===
'webp2jpg_wasm-im.wasm')[0].url
let s1 = get.filter(m => m.name === 'webp2jpg_wasm-im.js')[0]
creatScript(s1.url, s1.name)
let s2 = get.filter(m => m.name === 'webp2jpg_avif_enc.wasm')[0]
squooshWasm.avif_enc = s2.url
let s3 = get.filter(m => m.name === 'webp2jpg_mozjpeg_enc.wasm')[0]
squooshWasm.mozjpeg_enc = s3.url
let s4 = get.filter(m => m.name === 'webp2jpg_app20201225.js')[0]
creatScript(s4.url, s4.name)
loading.style.display = 'none'
} else {
await localforage.setItem('version', lastVer)
location.reload()
}
}
})
})
}
</script>
</body>
</html>

@ -0,0 +1,44 @@
<p align="center">
![title](./images/og_image.png)
<!-- from shields.io/ -->
![title](./images/badges/01.svg)
![title](./images/badges/02.svg)
![title](./images/badges/03.svg)
</p>
## webp2jpg-online 介绍
我常常需要把webp图片转成jpg格式很多在线转化提供的功能都需要上传文件不爽。有非上传的但是ui很难用谷歌一番后了解到html5自带接口的canvas.toBlob有转换图片格式的功能索性就自己搞这个webp2jpg-online。
> ⚠️ 目前只测试通过Chrome其他浏览器不保证正常。
![title](./images/og_image02.png)
在线图片格式转化器, 可将jpeg、jpg、png、gif、webp、svg、ico、bmp文件转化为jpeg、png、webp、ico文件。无需上传文件本地即可完成转换
Online picture format converter, can convert jpeg, jpg, png, gif, webp, svg, ico, bmp files into jpeg, png, webp, ico files. No need to upload files, conversion can be done locally。
## 在线地址
https://renzhezhilu.github.io/webp2jpg-online/
## demo
![demo](./images/demo.gif)
## 🔧待解决
1.gif转webp时只能转第一帧(2020-2-15)
## 核心原理
[HTMLCanvasElement.toBlob()](https://developer.mozilla.org/zh-CN/docs/Web/API/HTMLCanvasElement/toBlob)
<!-- https://codepen.io/random233/pen/PowBBaa?editors=1000 -->
``` javascript
canvas.toBlob(callback, type, encoderOptions);
```

@ -0,0 +1,545 @@
/* 格式化 */
html,
body {
margin: 0;
padding: 0;
font-family: "微软雅黑";
font-size: 12px;
color: #000;
width: 100%;
height: 100%;
}
h1,
h2,
h3,
h4,
h5,
h6,
span,
p,
ul,
li,
table,
tr,
td,
input,
a,
dl,
dt,
dd {
margin: 0;
padding: 0;
text-decoration: none;
list-style: none;
text-shadow: rgba(0, 0, 0, 0.08) 0px 1px 2px;
}
img {
vertical-align: top;
border: none
}
#jg {
font-size: 16px;
line-height: 30px;
text-align: center;
}
.drag {
width: 90%;
padding: 30px 0;
background-color: rgb(255, 255, 255);
border: 8px dashed rgb(0, 0, 0, .3);
border-radius: 50px;
margin: 0 auto;
display: flex;
justify-content: center;
align-items: center;
text-align: center;
flex-direction: column;
}
.img_box {
display: flex;
flex-wrap: wrap;
justify-content: center;
}
.img_box img {
max-width: 180px;
max-height: 180px;
min-width: 80px;
}
.img_one {
position: relative;
display: flex;
align-items: center;
justify-content: center;
margin: 2px;
min-width: 80px;
}
.img_one .type {
position: absolute;
z-index: 1;
top: 0;
left: 0;
border-radius: 0 0 20px 0;
display: inline;
min-width: 20px;
padding: 0 10px;
text-align: center;
backdrop-filter: saturate(180%) blur(3px);
background-color: rgba(255, 255, 255, 0.6);
font-weight: 900;
}
.img_one .type.jpeg,
.img_one .type.jpg {
color: rgb(77, 77, 255);
}
.img_one .type.gif {
color: rgb(77, 208, 255);
}
.img_one .type.png {
color: rgb(77, 255, 148);
}
.img_one .type.webp {
color: rgb(160, 255, 77);
}
.img_one .type.svg {
color: rgb(246, 255, 77);
}
.img_one .type.ico {
color: rgb(255, 130, 77);
}
.img_one .type.bmp {
color: rgb(255, 89, 77);
}
.img_one .size {
position: absolute;
z-index: 1;
width: 100%;
backdrop-filter: saturate(180%) blur(10px);
background-color: rgba(0, 0, 0, 0.38);
color: #fff;
bottom: 0;
left: 0
}
.download_but {
width: 90%;
padding: 14px;
margin: 20px auto;
background-color: rgb(55, 78, 255);
color: #fff;
font-weight: bold;
font-size: 18px;
border-radius: 100px;
text-align: center;
cursor: pointer;
}
.download_but:hover {
opacity: .9;
}
.drag:hover {
opacity: .8;
}
.con {}
.p1 {
font-size: 100px;
line-height: 100px;
height: 100px;
font-weight: 900;
opacity: .3;
}
.p2 {
font-size: 30px;
line-height: 38px;
padding: 25px 0;
text-align: center;
font-weight: 900;
}
.p2 h1, .p2 h2{
font-size: 30px;
line-height: 38px;
}
.p2 label {
font-size: 14px;
}
#files {
display: none;
visibility: hidden;
}
@keyframes ggg {
100% {
background-position: 100%;
}
}
body.ondragover .ready {
display: flex
}
.ready {
position: fixed;
top: 0;
left: 0;
z-index: 100;
width: 100vw;
height: 100vh;
backdrop-filter: saturate(180%) blur(10px);
color: #fff;
font-size: 22px;
display: flex;
justify-content: center;
align-items: center;
border: 10px solid transparent;
box-sizing: border-box;
background:
linear-gradient(rgb(55, 78, 255),
rgba(55, 78, 255, 1)) padding-box,
repeating-linear-gradient(-45deg,
black 0, rgba(55, 78, 255, .8) 25%,
white 0, white 50%) 0/1em 1em;
animation: ggg 12s linear infinite;
opacity: .8;
display: none;
}
.ready p {
font-size: 80px;
text-align: center;
line-height: 100px;
}
#can {
display: none;
}
/* --------------------------------------------- */
#loading {
display: none;
zoom: 6;
}
select {
height: 30px;
font-size: 15px;
background-color: #fff;
border: 2px solid rgb(55, 78, 255);
border-left: 5px solid rgb(55, 78, 255);
padding: 0 10px;
}
[type=checkbox] {
zoom:2;
position: relative;
top: 2px;
}
.viewInGithub {
position: fixed;
right: 0;
bottom: 0;
z-index: 100;
}
/* --------------------------------------------- */
/* 烟花 - from https://codepen.io/yshlin/pen/ylDEk */
.pyro>.before,
.pyro>.after {
position: absolute;
width: 8px;
height: 8px;
border-radius: 4px;
box-shadow: 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff;
animation: 1s bang ease-out 3 backwards, 1s gravity ease-in 3 backwards, 5s position linear 3 backwards;
/* animation: 1s bang ease-out infinite backwards, 1s gravity ease-in infinite backwards, 5s position linear infinite backwards; */
}
.pyro>.after {
-moz-animation-delay: 1.25s, 1.25s, 1.25s;
-webkit-animation-delay: 1.25s, 1.25s, 1.25s;
-o-animation-delay: 1.25s, 1.25s, 1.25s;
-ms-animation-delay: 1.25s, 1.25s, 1.25s;
animation-delay: 1.25s, 1.25s, 1.25s;
-moz-animation-duration: 1.25s, 1.25s, 6.25s;
-webkit-animation-duration: 1.25s, 1.25s, 6.25s;
-o-animation-duration: 1.25s, 1.25s, 6.25s;
-ms-animation-duration: 1.25s, 1.25s, 6.25s;
animation-duration: 1.25s, 1.25s, 6.25s;
}
@-webkit-keyframes bang {
to {
box-shadow: -234px -283.6666666667px #ff0900, 21px -260.6666666667px #5eff00, -203px -141.6666666667px #ff00bf, 120px -228.6666666667px #ff00b7, 103px 11.3333333333px #ff9900, -14px -414.6666666667px #ff009d, -186px -1.6666666667px #00eaff, 217px -114.6666666667px #ff0095, 111px -407.6666666667px #bf00ff, 71px 42.3333333333px #d5ff00, -189px 37.3333333333px #ff00e1, 185px -301.6666666667px #1eff00, 141px -400.6666666667px #ff8400, 129px -290.6666666667px #ffc800, 92px 45.3333333333px #ff0077, -137px -72.6666666667px #fff700, 171px -383.6666666667px #e6ff00, -238px -1.6666666667px #00ffaa, -8px -99.6666666667px #4dff00, -37px -329.6666666667px #ff6f00, 208px -221.6666666667px #00fffb, -75px -209.6666666667px #007bff, -140px -45.6666666667px #09ff00, 85px -125.6666666667px #0d00ff, 234px -238.6666666667px #09ff00, 104px -156.6666666667px #ff00d5, 213px -225.6666666667px #ff0055, -8px -360.6666666667px #00ffbf, -71px 75.3333333333px #ff0062, -129px -124.6666666667px #ff0033, 212px 47.3333333333px #d000ff, 19px -248.6666666667px #ff00ae, 72px -293.6666666667px #ff0080, -91px -28.6666666667px #00ffb3, 132px -258.6666666667px #0044ff, 7px -72.6666666667px #00ffe6, -179px -346.6666666667px #4800ff, 200px -351.6666666667px #4d00ff, -183px -228.6666666667px #aa00ff, -80px -211.6666666667px #ff9900, 70px -91.6666666667px #006aff, -243px -163.6666666667px #ff00a6, 76px -135.6666666667px #ff0084, -212px -297.6666666667px #00ffbb, 128px 46.3333333333px #95ff00, -113px 79.3333333333px #00ffbb, -157px -34.6666666667px #ff00c8, -160px -74.6666666667px #9500ff, 228px 48.3333333333px #00ff62, -235px -57.6666666667px #ff00b3, 185px -149.6666666667px #b300ff;
}
}
@-moz-keyframes bang {
to {
box-shadow: -234px -283.6666666667px #ff0900, 21px -260.6666666667px #5eff00, -203px -141.6666666667px #ff00bf, 120px -228.6666666667px #ff00b7, 103px 11.3333333333px #ff9900, -14px -414.6666666667px #ff009d, -186px -1.6666666667px #00eaff, 217px -114.6666666667px #ff0095, 111px -407.6666666667px #bf00ff, 71px 42.3333333333px #d5ff00, -189px 37.3333333333px #ff00e1, 185px -301.6666666667px #1eff00, 141px -400.6666666667px #ff8400, 129px -290.6666666667px #ffc800, 92px 45.3333333333px #ff0077, -137px -72.6666666667px #fff700, 171px -383.6666666667px #e6ff00, -238px -1.6666666667px #00ffaa, -8px -99.6666666667px #4dff00, -37px -329.6666666667px #ff6f00, 208px -221.6666666667px #00fffb, -75px -209.6666666667px #007bff, -140px -45.6666666667px #09ff00, 85px -125.6666666667px #0d00ff, 234px -238.6666666667px #09ff00, 104px -156.6666666667px #ff00d5, 213px -225.6666666667px #ff0055, -8px -360.6666666667px #00ffbf, -71px 75.3333333333px #ff0062, -129px -124.6666666667px #ff0033, 212px 47.3333333333px #d000ff, 19px -248.6666666667px #ff00ae, 72px -293.6666666667px #ff0080, -91px -28.6666666667px #00ffb3, 132px -258.6666666667px #0044ff, 7px -72.6666666667px #00ffe6, -179px -346.6666666667px #4800ff, 200px -351.6666666667px #4d00ff, -183px -228.6666666667px #aa00ff, -80px -211.6666666667px #ff9900, 70px -91.6666666667px #006aff, -243px -163.6666666667px #ff00a6, 76px -135.6666666667px #ff0084, -212px -297.6666666667px #00ffbb, 128px 46.3333333333px #95ff00, -113px 79.3333333333px #00ffbb, -157px -34.6666666667px #ff00c8, -160px -74.6666666667px #9500ff, 228px 48.3333333333px #00ff62, -235px -57.6666666667px #ff00b3, 185px -149.6666666667px #b300ff;
}
}
@-o-keyframes bang {
to {
box-shadow: -234px -283.6666666667px #ff0900, 21px -260.6666666667px #5eff00, -203px -141.6666666667px #ff00bf, 120px -228.6666666667px #ff00b7, 103px 11.3333333333px #ff9900, -14px -414.6666666667px #ff009d, -186px -1.6666666667px #00eaff, 217px -114.6666666667px #ff0095, 111px -407.6666666667px #bf00ff, 71px 42.3333333333px #d5ff00, -189px 37.3333333333px #ff00e1, 185px -301.6666666667px #1eff00, 141px -400.6666666667px #ff8400, 129px -290.6666666667px #ffc800, 92px 45.3333333333px #ff0077, -137px -72.6666666667px #fff700, 171px -383.6666666667px #e6ff00, -238px -1.6666666667px #00ffaa, -8px -99.6666666667px #4dff00, -37px -329.6666666667px #ff6f00, 208px -221.6666666667px #00fffb, -75px -209.6666666667px #007bff, -140px -45.6666666667px #09ff00, 85px -125.6666666667px #0d00ff, 234px -238.6666666667px #09ff00, 104px -156.6666666667px #ff00d5, 213px -225.6666666667px #ff0055, -8px -360.6666666667px #00ffbf, -71px 75.3333333333px #ff0062, -129px -124.6666666667px #ff0033, 212px 47.3333333333px #d000ff, 19px -248.6666666667px #ff00ae, 72px -293.6666666667px #ff0080, -91px -28.6666666667px #00ffb3, 132px -258.6666666667px #0044ff, 7px -72.6666666667px #00ffe6, -179px -346.6666666667px #4800ff, 200px -351.6666666667px #4d00ff, -183px -228.6666666667px #aa00ff, -80px -211.6666666667px #ff9900, 70px -91.6666666667px #006aff, -243px -163.6666666667px #ff00a6, 76px -135.6666666667px #ff0084, -212px -297.6666666667px #00ffbb, 128px 46.3333333333px #95ff00, -113px 79.3333333333px #00ffbb, -157px -34.6666666667px #ff00c8, -160px -74.6666666667px #9500ff, 228px 48.3333333333px #00ff62, -235px -57.6666666667px #ff00b3, 185px -149.6666666667px #b300ff;
}
}
@-ms-keyframes bang {
to {
box-shadow: -234px -283.6666666667px #ff0900, 21px -260.6666666667px #5eff00, -203px -141.6666666667px #ff00bf, 120px -228.6666666667px #ff00b7, 103px 11.3333333333px #ff9900, -14px -414.6666666667px #ff009d, -186px -1.6666666667px #00eaff, 217px -114.6666666667px #ff0095, 111px -407.6666666667px #bf00ff, 71px 42.3333333333px #d5ff00, -189px 37.3333333333px #ff00e1, 185px -301.6666666667px #1eff00, 141px -400.6666666667px #ff8400, 129px -290.6666666667px #ffc800, 92px 45.3333333333px #ff0077, -137px -72.6666666667px #fff700, 171px -383.6666666667px #e6ff00, -238px -1.6666666667px #00ffaa, -8px -99.6666666667px #4dff00, -37px -329.6666666667px #ff6f00, 208px -221.6666666667px #00fffb, -75px -209.6666666667px #007bff, -140px -45.6666666667px #09ff00, 85px -125.6666666667px #0d00ff, 234px -238.6666666667px #09ff00, 104px -156.6666666667px #ff00d5, 213px -225.6666666667px #ff0055, -8px -360.6666666667px #00ffbf, -71px 75.3333333333px #ff0062, -129px -124.6666666667px #ff0033, 212px 47.3333333333px #d000ff, 19px -248.6666666667px #ff00ae, 72px -293.6666666667px #ff0080, -91px -28.6666666667px #00ffb3, 132px -258.6666666667px #0044ff, 7px -72.6666666667px #00ffe6, -179px -346.6666666667px #4800ff, 200px -351.6666666667px #4d00ff, -183px -228.6666666667px #aa00ff, -80px -211.6666666667px #ff9900, 70px -91.6666666667px #006aff, -243px -163.6666666667px #ff00a6, 76px -135.6666666667px #ff0084, -212px -297.6666666667px #00ffbb, 128px 46.3333333333px #95ff00, -113px 79.3333333333px #00ffbb, -157px -34.6666666667px #ff00c8, -160px -74.6666666667px #9500ff, 228px 48.3333333333px #00ff62, -235px -57.6666666667px #ff00b3, 185px -149.6666666667px #b300ff;
}
}
@keyframes bang {
to {
box-shadow: -234px -283.6666666667px #ff0900, 21px -260.6666666667px #5eff00, -203px -141.6666666667px #ff00bf, 120px -228.6666666667px #ff00b7, 103px 11.3333333333px #ff9900, -14px -414.6666666667px #ff009d, -186px -1.6666666667px #00eaff, 217px -114.6666666667px #ff0095, 111px -407.6666666667px #bf00ff, 71px 42.3333333333px #d5ff00, -189px 37.3333333333px #ff00e1, 185px -301.6666666667px #1eff00, 141px -400.6666666667px #ff8400, 129px -290.6666666667px #ffc800, 92px 45.3333333333px #ff0077, -137px -72.6666666667px #fff700, 171px -383.6666666667px #e6ff00, -238px -1.6666666667px #00ffaa, -8px -99.6666666667px #4dff00, -37px -329.6666666667px #ff6f00, 208px -221.6666666667px #00fffb, -75px -209.6666666667px #007bff, -140px -45.6666666667px #09ff00, 85px -125.6666666667px #0d00ff, 234px -238.6666666667px #09ff00, 104px -156.6666666667px #ff00d5, 213px -225.6666666667px #ff0055, -8px -360.6666666667px #00ffbf, -71px 75.3333333333px #ff0062, -129px -124.6666666667px #ff0033, 212px 47.3333333333px #d000ff, 19px -248.6666666667px #ff00ae, 72px -293.6666666667px #ff0080, -91px -28.6666666667px #00ffb3, 132px -258.6666666667px #0044ff, 7px -72.6666666667px #00ffe6, -179px -346.6666666667px #4800ff, 200px -351.6666666667px #4d00ff, -183px -228.6666666667px #aa00ff, -80px -211.6666666667px #ff9900, 70px -91.6666666667px #006aff, -243px -163.6666666667px #ff00a6, 76px -135.6666666667px #ff0084, -212px -297.6666666667px #00ffbb, 128px 46.3333333333px #95ff00, -113px 79.3333333333px #00ffbb, -157px -34.6666666667px #ff00c8, -160px -74.6666666667px #9500ff, 228px 48.3333333333px #00ff62, -235px -57.6666666667px #ff00b3, 185px -149.6666666667px #b300ff;
}
}
@-webkit-keyframes gravity {
to {
transform: translateY(200px);
-moz-transform: translateY(200px);
-webkit-transform: translateY(200px);
-o-transform: translateY(200px);
-ms-transform: translateY(200px);
opacity: 0;
}
}
@-moz-keyframes gravity {
to {
transform: translateY(200px);
-moz-transform: translateY(200px);
-webkit-transform: translateY(200px);
-o-transform: translateY(200px);
-ms-transform: translateY(200px);
opacity: 0;
}
}
@-o-keyframes gravity {
to {
transform: translateY(200px);
-moz-transform: translateY(200px);
-webkit-transform: translateY(200px);
-o-transform: translateY(200px);
-ms-transform: translateY(200px);
opacity: 0;
}
}
@-ms-keyframes gravity {
to {
transform: translateY(200px);
-moz-transform: translateY(200px);
-webkit-transform: translateY(200px);
-o-transform: translateY(200px);
-ms-transform: translateY(200px);
opacity: 0;
}
}
@keyframes gravity {
to {
transform: translateY(200px);
-moz-transform: translateY(200px);
-webkit-transform: translateY(200px);
-o-transform: translateY(200px);
-ms-transform: translateY(200px);
opacity: 0;
}
}
@-webkit-keyframes position {
0%,
19.9% {
margin-top: 10%;
margin-left: 40%;
}
20%,
39.9% {
margin-top: 40%;
margin-left: 30%;
}
40%,
59.9% {
margin-top: 20%;
margin-left: 70%;
}
60%,
79.9% {
margin-top: 30%;
margin-left: 20%;
}
80%,
99.9% {
margin-top: 30%;
margin-left: 80%;
}
}
@-moz-keyframes position {
0%,
19.9% {
margin-top: 10%;
margin-left: 40%;
}
20%,
39.9% {
margin-top: 40%;
margin-left: 30%;
}
40%,
59.9% {
margin-top: 20%;
margin-left: 70%;
}
60%,
79.9% {
margin-top: 30%;
margin-left: 20%;
}
80%,
99.9% {
margin-top: 30%;
margin-left: 80%;
}
}
@-o-keyframes position {
0%,
19.9% {
margin-top: 10%;
margin-left: 40%;
}
20%,
39.9% {
margin-top: 40%;
margin-left: 30%;
}
40%,
59.9% {
margin-top: 20%;
margin-left: 70%;
}
60%,
79.9% {
margin-top: 30%;
margin-left: 20%;
}
80%,
99.9% {
margin-top: 30%;
margin-left: 80%;
}
}
@-ms-keyframes position {
0%,
19.9% {
margin-top: 10%;
margin-left: 40%;
}
20%,
39.9% {
margin-top: 40%;
margin-left: 30%;
}
40%,
59.9% {
margin-top: 20%;
margin-left: 70%;
}
60%,
79.9% {
margin-top: 30%;
margin-left: 20%;
}
80%,
99.9% {
margin-top: 30%;
margin-left: 80%;
}
}
@keyframes position {
0%,
19.9% {
margin-top: 10%;
margin-left: 40%;
}
20%,
39.9% {
margin-top: 40%;
margin-left: 30%;
}
40%,
59.9% {
margin-top: 20%;
margin-left: 70%;
}
60%,
79.9% {
margin-top: 30%;
margin-left: 20%;
}
80%,
99.9% {
margin-top: 30%;
margin-left: 80%;
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.0 KiB

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="170" height="20"><linearGradient id="b" x2="0" y2="100%"><stop offset="0" stop-color="#bbb" stop-opacity=".1"/><stop offset="1" stop-opacity=".1"/></linearGradient><clipPath id="a"><rect width="170" height="20" rx="3" fill="#fff"/></clipPath><g clip-path="url(#a)"><path fill="#555" d="M0 0h115v20H0z"/><path fill="#007ec6" d="M115 0h55v20H115z"/><path fill="url(#b)" d="M0 0h170v20H0z"/></g><g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="110"> <text x="585" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="1050">No upload required</text><text x="585" y="140" transform="scale(.1)" textLength="1050">No upload required</text><text x="1415" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="450">本地转换</text><text x="1415" y="140" transform="scale(.1)" textLength="450">本地转换</text></g> </svg>

After

Width:  |  Height:  |  Size: 1000 B

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="100" height="20"><linearGradient id="b" x2="0" y2="100%"><stop offset="0" stop-color="#bbb" stop-opacity=".1"/><stop offset="1" stop-opacity=".1"/></linearGradient><clipPath id="a"><rect width="100" height="20" rx="3" fill="#fff"/></clipPath><g clip-path="url(#a)"><path fill="#555" d="M0 0h67v20H0z"/><path fill="#97ca00" d="M67 0h33v20H67z"/><path fill="url(#b)" d="M0 0h100v20H0z"/></g><g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="110"> <text x="345" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="570">Super fast</text><text x="345" y="140" transform="scale(.1)" textLength="570">Super fast</text><text x="825" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="230">超快</text><text x="825" y="140" transform="scale(.1)" textLength="230">超快</text></g> </svg>

After

Width:  |  Height:  |  Size: 965 B

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="20"><linearGradient id="b" x2="0" y2="100%"><stop offset="0" stop-color="#bbb" stop-opacity=".1"/><stop offset="1" stop-opacity=".1"/></linearGradient><clipPath id="a"><rect width="200" height="20" rx="3" fill="#fff"/></clipPath><g clip-path="url(#a)"><path fill="#555" d="M0 0h67v20H0z"/><path fill="#fe7d37" d="M67 0h133v20H67z"/><path fill="url(#b)" d="M0 0h200v20H0z"/></g><g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="110"> <text x="345" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="570">convert to</text><text x="345" y="140" transform="scale(.1)" textLength="570">convert to</text><text x="1325" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="1230">webp、jpeg、png、ico</text><text x="1325" y="140" transform="scale(.1)" textLength="1230">webp、jpeg、png、ico</text></g> </svg>

After

Width:  |  Height:  |  Size: 1004 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save