【问题标题】:More compressed version of ppm or bmp?更压缩的 ppm 或 bmp 版本?
【发布时间】:2020-11-24 05:27:49
【问题描述】:

我正在使用自定义绘制的图形在视频流上添加一个图层,但是当我为当前帧保存绘制的图层时,我有一个非常大的文件(~10MB)。在分析数据时,它大多是 0(代表视频的实际像素,而不是绘制的图层)。我知道 PPM 和 BMP 文件本来就是相当大的文件,但是有没有办法处理 0 的重复性?我应该检查其他文件格式吗?

【问题讨论】:

  • 使用 PNG 来最好地压缩线条图和类似的东西。将 JPEG 用于摄影图像(或更好的 JPEG2000,但没有那么广泛)。
  • 正如 Cris 所说,但 GIF 还可以压缩计算机图形和 “块状”,以及少于 250 种颜色的重复内容。
  • 虽然是“过去的爆炸”PCX 也可以使用 RLE(运行长度编码)并且可以与 Photoshop、GIMP 和 ImageMagick 配合使用 en.wikipedia.org/wiki/PCX
  • @MarkSetchell 解码 PCX 也很容易,只需几行代码 in C++in ASM 编码也很简单快捷......
  • @MarkSetchell 我也得到了 RT GIF 编码器/解码器,但是对于大分辨率来说它要大得多而且太慢了......我也得到了基于 DCT 的图像压缩工作,但是那个对于 RT 编码来说太慢了...但是可能是my optimized NTT 可能会有所作为

标签: image-processing graphics


【解决方案1】:

这是一个“块状”,1182x862 像素的计算机图形类型的叠加层。

以下是您可能想尝试的其他格式的尺寸:

-rw-r--r--@ 1 mark  staff  3056668 24 Nov 08:49 overlay.ppm
-rw-r--r--@ 1 mark  staff    23699 24 Nov 08:49 overlay.gif
-rw-r--r--  1 mark  staff   134723 24 Nov 08:49 overlay.pcx
-rw-r--r--@ 1 mark  staff    22585 24 Nov 08:48 overlay.png

请注意,它们都有一些权衡。虽然 PNG 是最小的,但它可能需要更长的时间来编写。 GIF 表现得很好,但如果颜色太多,效果会很差。 PCX 有点陈旧,但可以使用。 PPM 很大,大小与您的叠加层大小成正比。

请注意,如果您的叠加层确实非常块状,您可以考虑将它们减小到其高度和宽度的 1/4,如果您可以在放大时处理几个像素的不准确性,则将它们的体积缩小 16 倍。


您还可以考虑以矢量格式生成叠加层,其尺寸应该小很多很多倍。

直接从DrawSvg 的文档中提取,这是一个 SVG 矢量示例:

#!/usr/bin/env python3

import drawSvg as draw

d = draw.Drawing(200, 100, origin='center', displayInline=False)

# Draw an irregular polygon
d.append(draw.Lines(-80, -45,
                    70, -49,
                    95, 49,
                    -90, 40,
                    close=False,
            fill='#eeee00',
            stroke='black'))

# Draw a rectangle
r = draw.Rectangle(0,0,40,50, fill='#1248ff')
r.appendTitle("Our first rectangle")  # Add a tooltip
d.append(r)

# Draw a circle
d.append(draw.Circle(-40, -10, 30,
            fill='red', stroke_width=2, stroke='black'))

# Draw an arbitrary path (a triangle in this case)
p = draw.Path(stroke_width=2, stroke='green',
              fill='black', fill_opacity=0.5)
p.M(-30,5)  # Start path at point (-30, 5)
p.l(60,30)  # Draw line to (60, 30)
p.h(-70)    # Draw horizontal line to x=-70
p.Z()       # Draw line to start
d.append(p)

# Draw multiple circular arcs
d.append(draw.ArcLine(60,-20,20,60,270,
            stroke='red', stroke_width=5, fill='red', fill_opacity=0.2))
d.append(draw.Arc(60,-20,20,60,270,cw=False,
            stroke='green', stroke_width=3, fill='none'))
d.append(draw.Arc(60,-20,20,270,60,cw=True,
            stroke='blue', stroke_width=1, fill='black', fill_opacity=0.3))

# Draw arrows
arrow = draw.Marker(-0.1, -0.5, 0.9, 0.5, scale=4, orient='auto')
arrow.append(draw.Lines(-0.1, -0.5, -0.1, 0.5, 0.9, 0, fill='red', close=True))
p = draw.Path(stroke='red', stroke_width=2, fill='none',
              marker_end=arrow)  # Add an arrow to the end of a path
p.M(20, -40).L(20, -27).L(0, -20)  # Chain multiple path operations
d.append(p)
d.append(draw.Line(30, -20, 0, -10,
            stroke='red', stroke_width=2, fill='none',
            marker_end=arrow))  # Add an arrow to the end of a line

d.setPixelScale(2)  # Set number of pixels per geometry unit
#d.setRenderSize(400,200)  # Alternative to setPixelScale
d.saveSvg('example.svg')
d.savePng('example.png')

这相当于 14,202 字节的 PNG 或 1,348 字节的 SVG - 所以矢量图形要小 10 倍!

-rw-r--r--     1 mark  staff       1348 24 Nov 10:01 example.svg
-rw-r--r--     1 mark  staff      14202 24 Nov 10:01 example.png

这是 SVG:

<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
     width="400" height="200" viewBox="-100.0 -50.0 200 100">
<defs>
<marker markerWidth="4.0" markerHeight="4.0" viewBox="-0.1 -0.5 1.0 1.0" orient="auto" id="d0">
<path d="M-0.1,0.5 L-0.1,-0.5 L0.9,0 Z" fill="red" />
</marker>
</defs>
<path d="M-80,45 L70,49 L95,-49 L-90,-40" fill="#eeee00" stroke="black" />
<rect x="0" y="-50" width="40" height="50" fill="#1248ff">
<title>Our first rectangle</title>
</rect>
<circle cx="-40" cy="10" r="30" fill="red" stroke-width="2" stroke="black" />
<path d="M-30,-5 l60,-30 h-70 Z" stroke-width="2" stroke="green" fill="black" fill-opacity="0.5" />
<circle cx="60" cy="20" r="20" stroke-dasharray="73.30382858376184 52.35987755982988" stroke-dashoffset="-31.41592653589793" stroke="red" stroke-width="5" fill="red" fill-opacity="0.2" />
<path d="M70.0,2.679491924311229 A20,20,0,1,0,59.99999999999999,40.0" stroke="green" stroke-width="3" fill="none" />
<path d="M59.99999999999999,40.0 A20,20,0,1,1,70.0,2.679491924311229" stroke="blue" stroke-width="1" fill="black" fill-opacity="0.3" />
<path d="M20,40 L20,27 L0,20" stroke="red" stroke-width="2" fill="none" marker-end="url(#d0)" />
<path d="M30,20 L0,10" stroke="red" stroke-width="2" fill="none" marker-end="url(#d0)" />
</svg>

如果您想用您的实际数据进行试验,请在终端中尝试 ImageMagick。您可以像这样从 PPM 转换为 PNG:

magick input.ppm output.png

或从 PPM 到四分之一高度和四分之一宽度的 GIF,如下所示:

magick input.ppm -scale 25% result.gif

请注意,ImageMagick 不会将转换为 SVG - 因为它是一个光栅图形程序,甚至在它开始之前就会对所有内容进行光栅化。它会将 从 SVG 转换为光栅。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-05-10
    • 1970-01-01
    • 2017-10-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多