Bash 在二进制分隔符上拆分二进制文件?
我正在编写一个shell脚本,将MPO立体图3D图像转换为标准JPEG图像。MPO文件只是两个JPEG图像,连接在一起 因此,您可以通过查找第二个JPEG的幻数头(0xFFD8FFE1)的字节偏移量来拆分JPEG文件。我已经使用hextump/xxd、grep、head和tail手动完成了这项工作Bash 在二进制分隔符上拆分二进制文件?,bash,unix,shell,binary,grep,Bash,Unix,Shell,Binary,Grep,我正在编写一个shell脚本,将MPO立体图3D图像转换为标准JPEG图像。MPO文件只是两个JPEG图像,连接在一起 因此,您可以通过查找第二个JPEG的幻数头(0xFFD8FFE1)的字节偏移量来拆分JPEG文件。我已经使用hextump/xxd、grep、head和tail手动完成了这项工作 这里的问题是grep:我可以使用什么来直接搜索二进制文件中的特定幻数,并返回字节偏移量?或者我根本不应该为此使用shell脚本?谢谢。我认为非常简单的自制方法将是您的最佳选择。根据二进制文件格式的所有
这里的问题是grep:我可以使用什么来直接搜索二进制文件中的特定幻数,并返回字节偏移量?或者我根本不应该为此使用shell脚本?谢谢。我认为非常简单的自制方法将是您的最佳选择。根据二进制文件格式的所有特殊情况,执行此操作的代码将非常小
mmap
可以方便地查看内存中的文件Start
end
start
到end
的字节范围复制到新文件中bbe -b '/\xFF\xD8\xFF\xE1/:' -e 'D 2' -o first_jpeg mpo_file
对于第二个问题:
bbe -b '/\xFF\xD8\xFF\xE1/:' -e 'D 1' -o second_jpeg mpo_file
请注意,如果JPEG的幻数出现在MPO文件中的其他地方,则此操作将不起作用。我认为Bart已经解决了您最大的问题。。如果该二进制序列在该过程中重复,您将得到部分JPEG 我做了一个快速测试,连接了一些JPEG,然后用awk提取它们(请注意,我文件中的幻数以0xE0结束,而不是0xE1结束):
这对我来说似乎还可以,但上面提到的问题仍然没有得到处理,而且非常真实。FFE1不是某个jpeg“幻数”的一部分,它是APP1标记。而且不能保证它就在SOI标记FFD8之后。此外,您还应注意某些jpeg图像在EXIF块中嵌入缩略图jpeg。这很可能还包含一个APP1标记。我在下面找到了一个更好的MPO文件结构解释(以及如何正确处理它) 编辑,2019年10月: 由于博客条目现在是404s,下面是我基于它编写的脚本。我已经很多年没用了
#!/usr/bin/env bash
# Script to convert 3D MPO files, as used in the Fuji FinePix series of 3D cameras, into standard JPEG files.
# Based on work by David Glover, posted at http://www.davidglover.org/2010/09/using-the-fuji-finepix-real-3d-w3-camera-on-a-mac-or-linuxunix.html
# This script requires exiftool and ImageMagick.
FULLNAME="$1"
FILENAME="$(basename $FULLNAME)"
DIRNAME="$(dirname $FULLNAME)"
BASENAME="${FILENAME%.*}"
# Create output directories
mkdir -p "$DIRNAME"/stereoscopic-rl/
mkdir -p "$DIRNAME"/stereoscopic-mpo/
mkdir -p "$DIRNAME"/stereoscopic-anaglyph/
mkdir -p "$DIRNAME"/monoscopic-l/
mkdir -p "$DIRNAME"/monoscopic-r/
# Create separate left and right images
exiftool -trailer:all= "$FULLNAME" -o "$DIRNAME"/monoscopic-l/"$BASENAME"-left.jpg
exiftool "$FULLNAME" -mpimage2 -b > "$DIRNAME"/monoscopic-r/"$BASENAME"-right.jpg
# Move the MPO file to its new home
mv "$FULLNAME" "$DIRNAME"/stereoscopic-mpo/
# Determine parallax value and create cropped images for stereo generation
# 36 is only appropriate for 4:3 or 3:2 images
parallax=$(exiftool -b -Parallax "$DIRNAME"/monoscopic-r/"$BASENAME"-right.jpg)
parallax=$(echo "$parallax"*36+0.5 | bc | cut -d . -f 1)
# The above pipeline can't deal with a parallax of zero
# In theory, this fix doesn't cover values between zero and -1
# TODO improve the calculation
if [ ! $parallax ]; then
parallax=0
fi
echo $parallax
if [ $parallax -ge 0 ]; then
convert "$DIRNAME"/monoscopic-l/"$BASENAME"-left.jpg -crop +"$parallax"+0 "$DIRNAME"/monoscopic-l/"$BASENAME"-left-cropped.jpg
convert "$DIRNAME"/monoscopic-r/"$BASENAME"-right.jpg -crop -"$parallax"+0 "$DIRNAME"/monoscopic-r/"$BASENAME"-right-cropped.jpg
else
convert "$DIRNAME"/monoscopic-l/"$BASENAME"-left.jpg -crop -"$((-1*$parallax))"+0 "$DIRNAME"/monoscopic-l/"$BASENAME"-left-cropped.jpg
convert "$DIRNAME"/monoscopic-r/"$BASENAME"-right.jpg -crop +"$((-1*$parallax))"+0 "$DIRNAME"/monoscopic-r/"$BASENAME"-right-cropped.jpg
fi
# Create stereoscopic images for cross-eye (right-left) and anaglyph (red-cyan) viewing
convert "$DIRNAME"/monoscopic-r/"$BASENAME"-right-cropped.jpg "$DIRNAME"/monoscopic-l/"$BASENAME"-left-cropped.jpg +append "$DIRNAME"/stereoscopic-rl/"$BASENAME"-stereoscopic-rl.jpg
composite -stereo 0 "$DIRNAME"/monoscopic-r/"$BASENAME"-right-cropped.jpg "$DIRNAME"/monoscopic-l/"$BASENAME"-left-cropped.jpg "$DIRNAME"/stereoscopic-anaglyph/"$BASENAME"-stereoscopic-anaglyph.jpg
# Clean up separated parallax-corrected images
rm "$DIRNAME"/monoscopic-l/"$BASENAME"-left-cropped.jpg
rm "$DIRNAME"/monoscopic-r/"$BASENAME"-right-cropped.jpg
exit 0
我猜幻数中的0xE1表示这是序列中的第二个图像,并且您从未拥有超过2个图像。根据需要进行调整。=)我不确定这一点,因为我在文件的开头也看到了0xE1。我给你答案检查,因为awk在每个Unix系统上都可用(它提醒我需要了解更多信息:)。我的shell脚本目前正在对image03.jpg或缺少image02.jpg进行一些基本检查并中止,这有助于处理幻数问题。我还可以检查EXIF头。不幸的是,尽管维基百科声称Digikam支持MPO,但我只知道有一个程序可以本机读取这些文件——Fujifilm Windows应用程序。必须查看他们的来源和我相机的文档。就目前而言,这很好。很高兴你能成功。。表示0xFF 0xD8是JPEG幻数的开始,因此很自然,它后面的内容取决于实现。感谢您让我注意到bbe!顺便说一下,您的Sourceforge链接已断开,bbe.sf.net是另一个项目。请注意,这些文件是由Fujifilm FinePix Real 3D W3相机生成的。此外,在MPO文件中,左镜头图像似乎位于第一位。抱歉。。。错误404我在答案中添加了我在2010年写的脚本;希望它能对你有所帮助。
#!/usr/bin/env bash
# Script to convert 3D MPO files, as used in the Fuji FinePix series of 3D cameras, into standard JPEG files.
# Based on work by David Glover, posted at http://www.davidglover.org/2010/09/using-the-fuji-finepix-real-3d-w3-camera-on-a-mac-or-linuxunix.html
# This script requires exiftool and ImageMagick.
FULLNAME="$1"
FILENAME="$(basename $FULLNAME)"
DIRNAME="$(dirname $FULLNAME)"
BASENAME="${FILENAME%.*}"
# Create output directories
mkdir -p "$DIRNAME"/stereoscopic-rl/
mkdir -p "$DIRNAME"/stereoscopic-mpo/
mkdir -p "$DIRNAME"/stereoscopic-anaglyph/
mkdir -p "$DIRNAME"/monoscopic-l/
mkdir -p "$DIRNAME"/monoscopic-r/
# Create separate left and right images
exiftool -trailer:all= "$FULLNAME" -o "$DIRNAME"/monoscopic-l/"$BASENAME"-left.jpg
exiftool "$FULLNAME" -mpimage2 -b > "$DIRNAME"/monoscopic-r/"$BASENAME"-right.jpg
# Move the MPO file to its new home
mv "$FULLNAME" "$DIRNAME"/stereoscopic-mpo/
# Determine parallax value and create cropped images for stereo generation
# 36 is only appropriate for 4:3 or 3:2 images
parallax=$(exiftool -b -Parallax "$DIRNAME"/monoscopic-r/"$BASENAME"-right.jpg)
parallax=$(echo "$parallax"*36+0.5 | bc | cut -d . -f 1)
# The above pipeline can't deal with a parallax of zero
# In theory, this fix doesn't cover values between zero and -1
# TODO improve the calculation
if [ ! $parallax ]; then
parallax=0
fi
echo $parallax
if [ $parallax -ge 0 ]; then
convert "$DIRNAME"/monoscopic-l/"$BASENAME"-left.jpg -crop +"$parallax"+0 "$DIRNAME"/monoscopic-l/"$BASENAME"-left-cropped.jpg
convert "$DIRNAME"/monoscopic-r/"$BASENAME"-right.jpg -crop -"$parallax"+0 "$DIRNAME"/monoscopic-r/"$BASENAME"-right-cropped.jpg
else
convert "$DIRNAME"/monoscopic-l/"$BASENAME"-left.jpg -crop -"$((-1*$parallax))"+0 "$DIRNAME"/monoscopic-l/"$BASENAME"-left-cropped.jpg
convert "$DIRNAME"/monoscopic-r/"$BASENAME"-right.jpg -crop +"$((-1*$parallax))"+0 "$DIRNAME"/monoscopic-r/"$BASENAME"-right-cropped.jpg
fi
# Create stereoscopic images for cross-eye (right-left) and anaglyph (red-cyan) viewing
convert "$DIRNAME"/monoscopic-r/"$BASENAME"-right-cropped.jpg "$DIRNAME"/monoscopic-l/"$BASENAME"-left-cropped.jpg +append "$DIRNAME"/stereoscopic-rl/"$BASENAME"-stereoscopic-rl.jpg
composite -stereo 0 "$DIRNAME"/monoscopic-r/"$BASENAME"-right-cropped.jpg "$DIRNAME"/monoscopic-l/"$BASENAME"-left-cropped.jpg "$DIRNAME"/stereoscopic-anaglyph/"$BASENAME"-stereoscopic-anaglyph.jpg
# Clean up separated parallax-corrected images
rm "$DIRNAME"/monoscopic-l/"$BASENAME"-left-cropped.jpg
rm "$DIRNAME"/monoscopic-r/"$BASENAME"-right-cropped.jpg
exit 0