从 SMIL 文件中提取 jpeg

extract a jpeg from a SMIL file

我需要我的 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 .*\)//p' | xxd -r -p > image.jpeg

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

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

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

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

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

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

根据 jpeg 标准,图像开始和图像结束标记分别为 OxFF OxD80xFF 0xD9

所以下面的一种衬垫应该可以工作

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

在针对示例文件进行测试后,我将 oneliner 从注释转换为适当的脚本。

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

#!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 
};