如何实时生成缩略图?
是否有程序或脚本可以读取标准输入上的图像并将调整大小的图像写入标准输出,而无需等待标准输入上的 EOF?质量差是可以接受的;等待整个图像加载不是。
ImageMagick(convert
和 stream
类似)将读取、处理、然后输出。我想要的更像是一个实时流处理器:如果我缩小 50%,它应该为每两行输入(大致)输出一行缩略图,无论输入流的状态如何。
如果这还没有意义,想象一下您正在通过慢速网络连接加载图像。一旦可以,浏览器就会开始显示图像的上边缘。如果图像大于窗口,浏览器会将其缩小以适合窗口。它不必等待整个图像加载。
以下是我用于测试的一些工具。这在端口 8080 上提供十个切片的图像,切片之间有一秒的延迟,以模拟慢速网络连接:
IMAGE=test.jpg;切片=10;大小=$(stat -c "%s" $IMAGE); BS=$(($SIZE / $SLICES + 1)); (echo HTTP/1.0 200 OK; echo 内容类型:image/jpeg; echo; for i in $(seq 0 $(($SLICES - 1))); do dd if=$IMAGE bs=$BS Skip=$我计数=1;完成1; nc -lp8080 -q0
运行该程序并立即在浏览器中打开 localhost:8080 以查看图像缓慢加载。如果将图像切片通过管道传输到 convert
或 stream
而不是 nc
(忽略所有回显),则十秒内不会出现任何输出,然后您可以立即获得整个缩略图。
Is there a program or script that can read an image on standard input and write a resized image to standard output without waiting for EOF on standard input? Poor quality is acceptable; waiting for the whole image to load is not.
ImageMagick (convert
and stream
alike) will read, then process, then output. What I want is more like a real-time stream processor: if I'm scaling down 50%, it should output one row of thumbnail for every two rows of input (roughly), regardless of the state of the input stream.
If this doesn't make sense yet, imagine you're loading an image over a slow network connection. As soon as it can, the browser starts displaying the top edge of the image. If the image is larger than the window, the browser scales it down to fit the window. It doesn't have to wait for the whole image to load.
Here are some of the tools I've used for testing. This serves an image on port 8080 in ten slices, with a one-second delay between slices to simulate a slow network connection:
IMAGE=test.jpg; SLICES=10; SIZE=$(stat -c "%s" $IMAGE); BS=$(($SIZE / $SLICES + 1)); (echo HTTP/1.0 200 OK; echo Content-Type: image/jpeg; echo; for i in $(seq 0 $(($SLICES - 1))); do dd if=$IMAGE bs=$BS skip=$i count=1; sleep 1; done) | nc -lp8080 -q0
Run that and immediately open localhost:8080
in your browser to see the image slowly load. If you pipe the image slices to convert
or stream
instead of nc
(omitting all the echoes), no output appears for ten seconds, and then you get the whole thumbnail at once.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
根据图像格式,这很困难。例如,PNG 是分块的,并且每个块都经过 zlib 压缩,因此您必须先读取文件的大部分内容,然后才能开始渲染图像。 BMP 图像是“自下而上”存储的,从右下角到左上角呈现,因此除非您的缩略图也是 BMP,否则您将读取整个图像或向后处理文件。 JPEG 可以更轻松地做到这一点;它按顺序存储,如果它是渐进式 JPEG,您可以滥用它并仅读取前 N 个通道以获得所需的缩略图分辨率。像 DJVU 这样的小波格式也可能更简单。
我认为您不会找到执行此操作的通用工具,但您可以编写一个自定义的特定于格式的流解码器来处理它。
This is difficult depending on the image format. PNG, for example, is chunked, and each chunk zlib-compressed, so you have to read in a potentially large portion of the file before you can start rendering the image. BMP images are stored "bottom-up", where it renders from the lower right to the upper left, so unless your thumbnail will also be a BMP, you will have either read in the entire image or process the file backwards. JPEG can do this more readily; it's stored in order, and if it's a progressive JPEG you can abuse that and read in only the first N passes to get the thumbnail resolution you need. Wavelet formats like DJVU might also be more straightforward.
I don't think you'll find general-purpose tools that do this, but you could write a custom format-specific streaming decoder to handle it.