어떻게 추출할 수 있다.jpg/.png 의 구성 요소.hpi 파일입니까?

StackOverflow https://stackoverflow.com/questions/228165

  •  03-07-2019
  •  | 
  •  

문제

나는 우연히 내려 고대 사진 객체를 디스크,슬프게도 발견한 회사(헤메)지 않에 대한 지원을 제공합니다.는 이유는 무엇인가요?더미.hpi 파일이 있습니다.다행히도,내가 발견 이 정보 에서 추출 jpg,png 구성 요소의 파일입니다.

불행하게도,되지 않았을 얻을 수 있습니다.할 수 있는 사람이 어떤 잘못으로 이 코드는?나는 행복할 것으로 PHP 또는 파이썬 솔루션면 Perl 신의 일이 아니다.:)

open(I, "$name") || die;
binmode(I);
$_ = <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; };

이 hexdump 재 테스트 파일 내가 걸려 off CD,여기에 도움이 된다면 모두에서:

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
도움이 되었습니까?

해결책

그것은 보인다 regexp 은 잘못된 것입니다.그 이유는 내가 쓴 작은 C 프로그램을 위해 그것을 할 저:

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

그것은 명령행 매개변수 입력.hpi output.jpg 출력됩니다.png.오류 처리하지 않은 100%정확하지만,그것은 좋은 충분히 항상 당신에게 뭔가 잘못,그리고 대부분의 시간입니다. 대용량 파일,당신은 확대 MAX_SIZE.

여기에는 쉘 스크립트는 연락처 정보를 확인할 수 있습과*.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 이미지는 마스크로 적용되는 알파 채널이 있습니다.이 파일에 대한 것입니다 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 파일을 변환 할 수 있습니다.

여기에 Google이 도착하는 사람들을 위해 PNG 이미지에 대해서만이 문제를 해결하는 Python 스크립트를 작성했습니다.

#!/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 파일이 있습니다 복구, Linux에서 테스트했지만 다른 플랫폼과 호환 될 수 있습니다).

일부 데비안 시스템에서는 사용할 수 있습니다 apt get install recoverjpeg

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top