Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

下载下来的动态图的zip压缩包,如何将里面图片还原或制作成动图,并且将画质损耗降到最低呢 #13

Open
MROrangeFanta opened this issue May 27, 2019 · 18 comments

Comments

@MROrangeFanta
Copy link

commented May 27, 2019

我应该用什么程序制作呢,目前我能够操作的软件只能做到30帧甚至不到,或者画质变的很差,而且都是转化成gif格式,怎么才能做成用PixivAnimatDownloader下载的html那样高品质的格式呢?

@Tsuk1ko

This comment has been minimized.

Copy link
Owner

commented May 29, 2019

貌似 PixivAnimatDownloader 没有开源,无法得知其使用了什么方法

不过 pixiv plus 脚本使用了 gif.js,你可以看一下它的转换效果如何

这个功能可以在后续版本中加入

@Tsuk1ko Tsuk1ko added the enhancement label May 29, 2019

@Tsuk1ko

This comment has been minimized.

Copy link
Owner

commented May 29, 2019

不过 gif 格式动图本来的体积就很大,十分大,这也是为什么从p站下载到的动图是分成每一帧的,p站实际上是将这些 jpg 图片放在 canvas 中按设定好的帧率切换而已

一个十几 MB 的 gif,如果拆分成 jpg 或者使用 mp4 之类的视频格式储存,可能就 1MB 不到

如果一定要减小 gif 体积,必定要牺牲像素数、帧数、色彩数等

@MROrangeFanta

This comment has been minimized.

Copy link
Author

commented May 29, 2019

效果是不错,下载的动图体积不到2倍,色彩也没有太大的丢失,缺点是帧数轻微变低,导致动画时长略微变长。

增加这个功能的话应该不错,对于科学上网网速捉鸡的人(我)可以先下载后预览一下,再决定是否去下载原图,而且gif图也能更方便的在移动端上分享(至少我的手机打不开html文件)

目前的话,相比 pixiv plus,还是PixivAnimatDownloader更加适合用来下载p站动图。(不用一直开着该动图的网页)

最后,pxder非常棒非常好用,比心(′▽`ʃ♡ƪ)

@Tsuk1ko

This comment has been minimized.

Copy link
Owner

commented May 29, 2019

@MROrangeFanta 谢谢😆

@LCYLYM

This comment has been minimized.

Copy link

commented Jun 19, 2019

那大佬考不考虑加个下载时自动转gif功能呢QAQ

@Tsuk1ko

This comment has been minimized.

Copy link
Owner

commented Jun 19, 2019

@LCYLYM 在计划中,当然具体更新可能要到7月多,打算重写一个 GUI 版

@LCYLYM

This comment has been minimized.

Copy link

commented Jun 20, 2019

@LCYLYM

This comment has been minimized.

Copy link

commented Jun 22, 2019

@LCYLYM 在计划中,当然具体更新可能要到7月多,打算重写一个 GUI 版

唔。。。求下载收藏时能保存下。。不要每次下载收藏都得重新收集。。。

@Tsuk1ko Tsuk1ko added the help wanted label Aug 26, 2019

@Tsuk1ko

This comment has been minimized.

Copy link
Owner

commented Aug 26, 2019

象征性的更新一下进度

因为 gif.js 只能在浏览器环境下使用,所以我又找了可以在 node 端使用的 gif-encoder,它本身也是 gif.js 的一个 fork

按理来说它们的效果应该是几乎一样的,但 gif-encoder 生成的实际上比 gif.js 生成的大了 30% 左右,唯一和质量有关的参数也是一样的,很怪

pxder/src/zip2gif.js

Lines 1 to 54 in 3e4269f

const ETL = require('etl');
const Unzipper = require('unzipper');
const getPixels = require('get-pixels');
const GifEncoder = require('gif-encoder');
const Fs = require('fs');
const Path = require('path');
async function extractZip(path) {
let promises = [];
await Fs.createReadStream(path)
.pipe(Unzipper.Parse())
.pipe(
ETL.map(entry => {
promises.push(entry.buffer());
entry.autodrain();
})
)
.promise();
return Promise.all(promises);
}
function getPixelsPromise(buffer, mime) {
return new Promise((resolve, reject) => {
getPixels(buffer, mime, (err, pixels) => {
if (err) reject(err);
else resolve(pixels);
});
});
}
async function zip2gif(zipPath, gifPath, mime, delay) {
const gifStream = Fs.createWriteStream(gifPath);
let gif;
const imgs = await extractZip(zipPath);
for (let img of imgs) {
const {
data,
shape: [width, height],
} = await getPixelsPromise(img, mime);
if (!gif) {
gif = new GifEncoder(width, height);
gif.pipe(gifStream);
gif.setDelay(delay);
// gif.setQuality(1000);
gif.setRepeat(0);
gif.writeHeader();
}
gif.addFrame(data);
gif.read();
}
gif.finish();
}
zip2gif('./test/dl/PID/(65123727)miku 吃瓜@80ms.zip', './test/test.gif', 'image/jpeg', 80);

每次看到生成这么鬼大的 gif 真是想咕咕咕,gif 已经很落后了,说到底为什么国内聊天软件还不考虑将 mp4 作为动图表情格式的一种

@LCYLYM

This comment has been minimized.

Copy link

commented Aug 27, 2019

GIF。。。。感觉还好吧。。而且现在动图还是占大部分的啊。。。mp4表情没那么快普及吧。。QAQ

@Tsuk1ko

This comment has been minimized.

Copy link
Owner

commented Aug 27, 2019

@LCYLYM 唉,等一个思想进步,学学 telegram(

@LCYLYM

This comment has been minimized.

Copy link

commented Aug 27, 2019

5)PDHOVHSFWW6P~QX2BBJ15

@LCYLYM

This comment has been minimized.

Copy link

commented Aug 27, 2019

@LCYLYM唉,等一个思想进步,学学电报(

需要挺多时间的吧。。现在大量表情都是gif。。。。。而且gif还是很多人用的-_-||

@LCYLYM

This comment has been minimized.

Copy link

commented Aug 27, 2019

象征性的更新一下进度

因为gif.js只能在浏览器环境下使用,所以我又找了可以在node端使用的gif-encoder,它本身也是gif.js的一个fork

按理来说它们的效果应该是几乎一样的,但gif-encoder生成的实际上比gif.js生成的大了30%左右,唯一和质量有关的参数也是一样的,很怪

pxder/src/zip2gif.js

Lines 1 to 54 in 3e4269f

const ETL = require('etl');
const Unzipper = require('unzipper');
const getPixels = require('get-pixels');
const GifEncoder = require('gif-encoder');
const Fs = require('fs');
const Path = require('path');
async function extractZip(path) {
let promises = [];
await Fs.createReadStream(path)
.pipe(Unzipper.Parse())
.pipe(
ETL.map(entry => {
promises.push(entry.buffer());
entry.autodrain();
})
)
.promise();
return Promise.all(promises);
}
function getPixelsPromise(buffer, mime) {
return new Promise((resolve, reject) => {
getPixels(buffer, mime, (err, pixels) => {
if (err) reject(err);
else resolve(pixels);
});
});
}
async function zip2gif(zipPath, gifPath, mime, delay) {
const gifStream = Fs.createWriteStream(gifPath);
let gif;
const imgs = await extractZip(zipPath);
for (let img of imgs) {
const {
data,
shape: [width, height],
} = await getPixelsPromise(img, mime);
if (!gif) {
gif = new GifEncoder(width, height);
gif.pipe(gifStream);
gif.setDelay(delay);
// gif.setQuality(1000);
gif.setRepeat(0);
gif.writeHeader();
}
gif.addFrame(data);
gif.read();
}
gif.finish();
}
zip2gif('./test/dl/PID/(65123727)miku 吃瓜@80ms.zip', './test/test.gif', 'image/jpeg', 80);

每次看到生成这么鬼大的gif真是想咕咕咕,gif已经很落后了,说到底为什么国内聊天软件还不考虑将mp4作为动图表情格式的一种

所以现在可以自动转gif了咩QAQ

@Tsuk1ko

This comment has been minimized.

Copy link
Owner

commented Aug 27, 2019

@LCYLYM 目前状况是这样的,就算按最好情况来算,gif.js 生成的千夜画的 Miku 吃瓜gif就有4.6MB了,毕竟原图分辨率也比较高,这种大小gif根本没办法直接拿去QQ发

如果你想缩减大小,最好的选择是降低分辨率,但这个在node上想实现非常麻烦,要用数个第三方包,而且为了处理图像这些包还要引入预构建的可执行文件,这让本来很轻巧的程序变得很庞大,但明明就只为了这一个功能而已,我觉得很不值,不如交给专门做这个工作的软件来处理

@LCYLYM

This comment has been minimized.

Copy link

commented Aug 27, 2019

@Luobogao

This comment has been minimized.

Copy link

commented Aug 29, 2019

qwq
如果想要无损的话不如尝试一下手动使用ffmpeg把压缩包里面的图片生成mp4?
我目前所使用的ffmpeg指令是 ffmpeg -r 30 -i ./%06d.jpg 1.mp4
把压缩包里面的图片解压之后cd过去运行就可以了。
其中 -r 30 指帧率为30,可以改成其他的;

ffmpeg也可以将mp4转成gif,指令是
ffmpeg -i xxx.mp4 -s 640x480 -r 15 xxx.gif

@Tsuk1ko

This comment has been minimized.

Copy link
Owner

commented Aug 30, 2019

@Luobogao 可以,有空我看看 node 有没有合适的 ffmpeg 的封装

@Tsuk1ko Tsuk1ko added this to TODO in Enhancement Aug 30, 2019

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
4 participants
You can’t perform that action at this time.