对imagemagick-convert的Bash脚本调用失败,但是粘贴到控制台

时间:2015-12-04 22:36:13

标签: bash xargs imagemagick-convert

好的测试内容总是难以获得,所以我经常要自己制作。

我处理的问题是隐藏式字幕/子标题没有与口语一致显示。因此,在来回的场景中,子标题似乎明显不对齐。

所以我的计划是使用毫秒级的视频"准确的"计数器,然后通过我没有来源的应用程序在视频上显示定时文本图像(PNG)。如果我的测试证明存在时序问题,那么我将能够推动供应商获取源和/或让他们解决他们的时间问题。

所以用毫秒"准确"在后台我打算显示imagemagick-convert创建的PNG,它将具有足够的嵌入文本,允许高速摄像机在解码/渲染过程中显示任何时间文本源文件中的错误对齐(Scenartist DVD SST格式) )。

我遇到的问题是我打电话给'转换'从控制台工作,但我的bash脚本不起作用。我已经在单引号和双引号周围放置了所有必要的中断字符,并且还尝试通过' xargs'并实现了同样的失败。似乎bash对字符串的解释在传递给' convert'之前得到解释。使用'设置-x'在脚本顶部启用,我看到了传递的字符串,有趣的是,如果将该字符串粘贴到控制台,它就能正常工作。只有它不能直接从脚本中工作。

请告知我的方法是否不正确和/或我是否缺少参数/选项以使其发挥作用。

以下是SST文件的几行供参考:

1613    02:29:08:20 02:29:09:14 NightAtTheMuseum_Th_16x9_EnS_DYN_B5-01608_FOX1595.png
1614    02:29:56:10 02:29:57:15 NightAtTheMuseum_Th_16x9_EnS_DYN_B5-01608_FOX1596.png
1615    02:29:57:20 02:29:59:05 NightAtTheMuseum_Th_16x9_EnS_DYN_B5-01608_FOX1597.png

格式:枚举,显示 - 开始时间hh:mm:ss:帧显示 - 停止时间hh:mm:ss:frame和图像文件名。

注意:对于那些熟悉格式的人,我手动删除SST文件标题并暂时只保留定时文本信息。

击脚本:

#! /bin/sh
set -x

echo "SST File name passed in <$1>"  

COUNT=0
GFX_FILENAME="test"

while IFS= read -r LINE; do
    COUNT=`expr $COUNT + 1`; # Debug not needed
    echo "Converting entry <$COUNT>... " # Debug not needed

    echo "Line read is <$LINE>" # Debug not needed

    GFX_FILENAME=$(printf "%s" "$LINE" | cut -f4 -d'    ') # works
    GFX_INLINE_TEXT=$(printf "%s" "$LINE" | tr \\t ' ') # works

    GFX_FILENAME="gfx_filename_here.png" # debug, put in place to isolate any issue introduced from parsed value
    GFX_INLINE_TEXT="gfx text here" # debug, put in place to isolate any issue introduced from parsed value

    echo "Filename parsed from line is <$GFX_FILENAME>" # debug to check value before calling convert

    # Method 1, call convert directly:    
    convert -size 720x480 xc:transparent -font Palatino-Bold -pointsize 72 -fill black -draw \"text 20,55 \'$GFX_INLINE_TEXT\'\" $GFX_FILENAME

    # Method 2, echo arguments to xargs then call convert (same result) commented out for now.  Note:  xargs hides 'convert's error output.
#   echo -size 720x480 xc:transparent -font Palatino-Bold -pointsize 72 -fill black -draw \"text 20,55 \'$GFX_INLINE_TEXT\'\" $GFX_FILENAME | xargs

    echo "Converted an image..." # debug, when i find this in console output from script execution I know what's above (from run with set -x enabled) is what I can paste to the console to double-check my syntax

done < $1 # method used to pass file to while loop

echo "Done!!!" # not true, since it doesn't work

输出:

./sst_to_png.sh NightAtTheMuseum_Th_16x9_EnS_DYN_B5-01608_v05.sst
+ echo File name passed in is <NightAtTheMuseum_Th_16x9_EnS_DYN_B5-01608_v05.sst>
File name passed in is <NightAtTheMuseum_Th_16x9_EnS_DYN_B5-01608_v05.sst>
+ COUNT=0
+ GFX_FILENAME=test
+ IFS= read -r LINE
+ expr 0 + 1
+ COUNT=1
+ echo Converting entry <1>... 
Converting entry <1>... 
> echo Line read is <0003   01:01:11:22 01:01:14:25 NightAtTheMuseum_Th_16x9_EnS_DYN_B5-01608_FOX0000.png
>ine read is <0003  01:01:11:22 01:01:14:25 NightAtTheMuseum_Th_16x9_EnS_DYN_B5-01608_FOX0000.png
+ printf %s 0003    01:01:11:22 01:01:14:25 NightAtTheMuseum_Th_16x9_EnS_DYN_B5-01608_FOX0000.png
+ cut -f4 -d    
+ GFX_FILENAME=NightAtTheMuseum_Th_16x9_EnS_DYN_B5-01608_FOX0000.png
+ printf %s 0003    01:01:11:22 01:01:14:25 NightAtTheMuseum_Th_16x9_EnS_DYN_B5-01608_FOX0000.png
+ tr \t  
+ GFX_INLINE_TEXT=0003 01:01:11:22 01:01:14:25 NightAtTheMuseum_Th_16x9_EnS_DYN_B5-01608_FOX0000.png
+ GFX_FILENAME=gfx_filename_here.png
+ GFX_INLINE_TEXT=gfx text here
+ echo Filename parsed from line is <gfx_filename_here.png>
Filename parsed from line is <gfx_filename_here.png>
+ convert -size 720x480 xc:transparent -font Palatino-Bold -pointsize 72 -fill black -draw "text 20,55 'gfx text here'" gfx_filename_here.png
convert.im6: non-conforming drawing primitive definition `text' @ error/draw.c/DrawImage/3158.
convert.im6: unable to open image `20,55': No such file or directory @ error/blob.c/OpenBlob/2638.
convert.im6: no decode delegate for this image format `20,55' @ error/constitute.c/ReadImage/544.
convert.im6: unable to open image `'gfx': No such file or directory @ error/blob.c/OpenBlob/2638.
convert.im6: no decode delegate for this image format `'gfx' @ error/constitute.c/ReadImage/544.
convert.im6: unable to open image `text': No such file or directory @ error/blob.c/OpenBlob/2638.
convert.im6: no decode delegate for this image format `text' @ error/constitute.c/ReadImage/544.
convert.im6: unable to open image `here'"': No such file or directory @ error/blob.c/OpenBlob/2638.
convert.im6: no decode delegate for this image format `here'"' @ error/constitute.c/ReadImage/544.
convert.im6: non-conforming drawing primitive definition `text' @ error/draw.c/DrawImage/3158.
+ echo Converted an image...
Converted an image...

然后我粘贴:

convert -size 720x480 xc:transparent -font Palatino-Bold -pointsize 72 -fill black -draw "text 20,55 'gfx text here'" gfx_filename_here.png

到控制台,从脚本的输出中复制并运行。

提前致谢,希望&#39;转换&#39;错误对某人意味着什么。对我来说奇怪的是,在脚本顶部启用了set -x的详细输出产生了一些在粘贴到控制台时有效但在从脚本直接执行时无效。

2 个答案:

答案 0 :(得分:1)

脚本中的正确行是:

convert -size 720x480 xc:transparent -font Palatino-Bold -pointsize 72 -fill black -draw "text 20,55 '$GFX_INLINE_TEXT'" "$GFX_FILENAME"

我在$GFX_FILENAME周围添加引号,以防文件名包含奇怪的字符。

您无法在控制台命令行中转义引号。为什么你需要在脚本中这样做?

答案 1 :(得分:0)

根本原因答案:

在尝试通过转换使用脏变量之前需要清理它们。所有在引号上使用中断字符的尝试都是徒劳的。变量尾随\ r \ n使引号消失。中断将它们放回去,但导致转换为语法报告了大量错误。最终&#34;清洁&#34;将变量作为参数传递时需要变量,尤其是当字符串中有其他后续参数时。

我尝试了以下语法:

How to remove carriage return from a string in Bash

但我无法得到:

echo "${GFX_INLINE_TEXT//[$'\t\r\n ']}"

./ sst_to_png.sh:36:./sst_to_png.sh:错误替换

为我工作。

所以我选择了:

GFX_INLINE_TEXT=$(printf "%s" "$LINE" | tr \\t ' ' | tr -d '\n' | tr -d '\r')

这允许我交换空格的制表符,然后从变量中删除尾随的\ r \ n(返回)实例,然后将其作为转换参数传递。