我偶然发现了相当古老的照片对象磁盘,遗憾地发现公司(hemera)不再提供支持了。这给我留下了一大堆.hpi文件。幸运的是,我发现这个信息有关提取jpg和png组件的信息。文件。

不幸的是,我无法让它发挥作用。谁能弄清楚这段代码有什么问题?如果Perl不是您的话,我会对PHP或Python解决方案感到满意。 :)

open(I, "$name") || die;
binmode(I);

我偶然发现了相当古老的照片对象磁盘,遗憾地发现公司(hemera)不再提供支持了。这给我留下了一大堆.hpi文件。幸运的是,我发现这个信息有关提取jpg和png组件的信息。文件。

不幸的是,我无法让它发挥作用。谁能弄清楚这段代码有什么问题?如果Perl不是您的话,我会对PHP或Python解决方案感到满意。 :)

0000000 89 48 50 49 0d 0a 1a 0a 64 00 00 00 20 00 00 00
0000010 45 89 00 00 65 89 00 00 0a 21 00 00 00 d0 d0 00

如果它有用的话,我从CD中取出的当前测试文件的hexdump就在这里:

<*> = <I>; close(I); my ($j, $p) = m|^.{32}(.*)(\211PNG.*)$|s; open(J, ">$name.jpg") && do { binmode(J); print J $j; close J; }; open(P, ">$name.png") && do { binmode(P); print P $p; close P; };

如果它有用的话,我从CD中取出的当前测试文件的hexdump就在这里:

<*>
有帮助吗?

解决方案

似乎正则表达式是错误的。这就是为什么我写了一个小程序来为我做这个:

#include <stdio.h>
#include <stdlib.h>

#define MAX_SIZE 1048576

char stuff[MAX_SIZE];

int main (int argc, char **argv)
{
    unsigned int j_off, j_len, p_off, p_len;
    FILE *fp, *jp, *pp;
    fp = fopen (argv[1], "r");
    if (!fp)    goto error;
    if (fseek (fp, 12, SEEK_SET))   goto error;
    if (!fread (&j_off, 4, 1, fp))  goto error;
    if (!fread (&j_len, 4, 1, fp))  goto error;
    if (!fread (&p_off, 4, 1, fp))  goto error;
    if (!fread (&p_len, 4, 1, fp))  goto error;
    fprintf (stderr, "INFO %s \t%d %d %d %d\n",
        argv[1], j_off, j_len, p_off, p_len);
    if (j_len > MAX_SIZE || p_len > MAX_SIZE) {
        fprintf (stderr, "%s: Chunk size too big!\n", argv[1]);
        return EXIT_FAILURE;
    }

    jp = fopen (argv[2], "w");
    if (!jp)    goto error;
    if (fseek (fp, j_off, SEEK_SET))    goto error;
    if (!fread (stuff, j_len, 1, fp))   goto error;
    if (!fwrite (stuff, j_len, 1, jp))  goto error;
    fclose (jp);

    pp = fopen (argv[3], "w");
    if (!pp)    goto error;
    if (fseek (fp, p_off, SEEK_SET))    goto error;
    if (!fread (stuff, p_len, 1, fp))   goto error;
    if (!fwrite (stuff, p_len, 1, pp))  goto error;
    fclose (pp);
    fclose (fp);
    return EXIT_SUCCESS;

error:
    perror (argv[1]);
    return EXIT_FAILURE;
}

它适用于命令行参数input.hpi output.jpg output.png。 错误处理不是100%正确,但它足以让你总是告诉你是否有问题,而且大多数情况都是错误的。 对于大型文件,您必须放大MAX_SIZE。

这是一个shell脚本,您可以使用* .hpi调用:

#!/bin/bash

dest=<destination-folder>

for arg in "$@"
do
  base=`echo $arg | cut -d'.' -f1`
  <executable> $arg $dest/original/$base.jpg $dest/mask/$base.png 2>>$dest/log
  #composite -compose CopyOpacity $dest/mask/$base.png $dest/original/$base.jpg $dest/rgba/$base.png
done

可选的复合命令(ImageMagick附带)将创建一个新的PNG图像,其掩码应用为alpha通道。请注意,此文件大约是原始文件的5倍。

请注意,某些HPI文件没有掩码。在这种情况下,我的程序仍然可以工作,但是给出一个空的PNG文件。

其他提示

我在从MS Word文档中提取图像时遇到了类似的问题。这是我为此写的程序。但它只提取PNG:

#!/usr/bin/perl
use strict;

my $HEADER = "\211PNG";
my $FOOTER = "IEND\xAEB`\x82";

foreach my $file ( @ARGV )
     {
     print "Extracting $file\n";
     (my $image_base = $file) =~ s/(.*)\..*/$1/;

     my $data = do { local $/; open my( $fh ), $file; <$fh> };

     my $count = 0;

     while( $data =~ m/($HEADER.*?$FOOTER)/sg )
        {
        my $image      = $1;
        $count++;
        my $image_name = "$image_base.$count.png";
        open my $fh, "> $image_name" or warn "$image_name: $!", next;
        print "Writing $image_name: ", length($image), " bytes\n";
        print $fh $image;
        close $fh;
        }

    }


__END__

不是程序自己的解决方案,而是应用程序,免费软件供个人使用,声明它可以转换hpi文件。

对于谷歌来这里的人,我写了一个Python脚本,只解决了PNG图像的这个问题:

#!/usr/bin/python
# -*- coding: utf-8 -*-
import re, sys

def main():
  if len(sys.argv) < 2:
    print """Usage:
  {0} BINARY_FILE PNG_PATH_TEMPLATE
Example:
  {0} bin/program 'imgs/image.{{0:03d}}.png'""".format(__file__)
    return
  binfile, pngpath_tpl = sys.argv[1:3]

  rx = re.compile("\x89PNG.+?IEND\xAEB`\x82", re.S)
  bintext = open(binfile, "rb").read()
  PNGs = rx.findall(bintext)

  for i, PNG in enumerate(PNGs):
    f = open(pngpath_tpl.format(i), "wb") # Simple string format.
    f.write(PNG)
    f.close()

if __name__ == "__main__":
  main()

对于 .jpeg .mov 文件, recoverjpeg ,我在linux上测试过(但可能与其他平台兼容)。

在某些debian系统上,可通过 apt get install recoverjpeg

获取
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top