【问题标题】:extract a jpeg from a SMIL file从 SMIL 文件中提取 jpeg
【发布时间】:2018-12-19 14:52:12
【问题描述】:

我需要我的 perl 脚本从 SMIL 文件中提取 jpeg。我看到的唯一方法是在 linux 中使用以下命令。

xxd -c1 -p wapenc\?T\=mavodi-6-13b-1f-4-7c-4806803 | tr "\n" " " | sed -n -e 's/.*\(ff d8 ff .*\)/\1/p' | xxd -r -p > image.jpeg

将其包装在 system() 调用中不起作用。将这样一系列命令合并到 perl 中的正确方法是什么?

【问题讨论】:

  • 到目前为止,我无法让命令正常工作。我在 -e 第 1 行的模式匹配 (m//) 中使用了未初始化的值 $_。在 /usr/share/perl/5.20/B/Deparse.pm 第 772 行的字符串 ne 中使用了未初始化的值 $/。 -e 语法分别OK。我正在使用的一个 smil 文件的副本可以在这里查看和下载:wetransfer.com/downloads/…
  • 最后一个命令没有给我错误,但创建的 thumbnail.jpeg 文件似乎不是正确的 jpeg,因为它只有 206 个字节,并且无法使用 Ristretto Image Viewer 查看。跨度>

标签: linux perl mms hexdump


【解决方案1】:

在对示例文件进行测试后,我将 oneliner 从 cmets 转换为正确的脚本。

脚本的核心是正则表达式 /(\xff\xd8\xff.*?\x{ff}\x{d9})/s,它提取 JPEG 标头的开头直到(包括)JPEG 标记 \xff\xd9 的结尾,同时仍然允许在其中包含换行符等(@987654324 @修饰符):

#!perl
use strict;
use warnings;

$/ = undef;

my( $filename ) = 'wapenc_T=mavodi-6-13b-1f-4-7c-4806803';
my( $outfilename ) = "$filename-thumbnail.jpeg";

open my $fh, '<:raw', $filename
    or die "Couldn't read '$filename': $!";
my $buffer;
{
    local $/;
    $buffer = <$fh>;
};

open my $output, '>:raw', $outfilename
    or die "Couldn't write to '$outfilename': $!";

if( $buffer =~ /(\xff\xd8\xff.*?\x{ff}\x{d9})/s ) {;
    print $output $1
};

【讨论】:

  • 太棒了!谢谢你。也许考虑把它变成一个 perl 模块。搜索时找不到任何我认为合适的东西。
  • @gatorreina 我不确定在任意文件中提取 JPEG 是否有意义,而且我一般对 SMIL 文件一无所知...
  • @gatorreina BTW,也许问题应该改名为“perl script to extract a jpeg from a SMIL file”?你可以这样做......
  • 虽然上述解决方案确实适用于某些 smil 文件,但它似乎不适用于所有文件——而原始 bash 命令可以。例如,它不会从该文件wetransfer.com/downloads/… 中提取 jpeg,并将 jpeg 截断为原始文件的 8% 左右。我怀疑这可能是由于正则表达式的不同,但我不确定。仍在使用它以尝试使其适用于所有文件。
  • 我相信这可能是因为正则表达式似乎在幻数(ff d8 ff)的每个实例之后截断,并且如果文件包含多次删除大部分的序列。我相信如果要在幻数序列的第一个实例之后保留所有内容,上述解决方案可能会起作用。对正则表达式了解不够,无法测试。
【解决方案2】:

将整个命令写入临时文件并执行。

如果您愿意,它可以让您在多个语句中构建命令,这将使其更具可读性。

或者,更好的是,在可读管道中运行第一个命令。自己解析数据,而不是在 bash 管道中将其输出到 tr sed,与 perl 相比,这两者都相当弱。然后通过可写的 popen 引导输出。

也许你甚至可以找到一个模块,让你处理xxd 正在做的事情,这样你就根本不需要它了。也许Data::HexDump::XXD

(没有仔细看,只是想快速抛出一个希望有用的线索。)

【讨论】:

  • 管道将文件转换为 hexdump,munges hexdump,然后将 hexdump 转换回文件。这在 Perl 中通过直接编辑文件(或者直接从文件中提取)更好地完成。
  • 是的。完全同意。
【解决方案3】:

根据 jpeg 标准,有一个图像开始标记和一个图像结束标记,它们分别是 OxFF OxD80xFF 0xD9

所以下面的一个班轮应该可以工作

perl -0777 -wne '/(\x{FF}\x{D8}.*?\x{FF}\x{D9})/ and print $1' input.smil > thumbnail.jpeg

【讨论】:

  • ...您是否针对 cme​​ts 中链接的文件测试了该解决方案?此外,您永远不会填充 $_,因此您也应该从评论中复制该版本。
  • 谢谢,但它给了我以下错误:在 -e 第 1 行的模式匹配 (m//) 中使用未初始化的值 $_。并创建了一个空的 jpeg 文件。
  • 如果 JPEG 文件中有任何换行符,则此答案将失败,并且从不读取数据。
猜你喜欢
  • 2012-02-03
  • 2015-10-21
  • 2012-05-08
  • 1970-01-01
  • 2018-01-12
  • 1970-01-01
  • 2021-06-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多