【问题标题】:Extracting JPEG/PNG/GIF Images from Data dump从数据转储中提取 JPEG/PNG/GIF 图像
【发布时间】:2017-07-24 15:23:37
【问题描述】:

我收到了磁盘中数据的二进制/十六进制转储。我的任务是从中提取图像。它是 JPEG、PNG 和 GIF 图像的混合转储。

你可以在link找到数据文件。

图片页眉和页脚

jpg:
 header: FF D8 FF E0 xx xx 4A 46 49 46 00, footer: FF D9
png:
 header: 89 50 4E 47 0D 0A 1A 0A, footer: 49 45 4E 44 AE 42 60 82
gif:
 header: 47 49 46 38 39 61, footer: 00 3B

在里面完好无损。如何使用 Java 提取图像?

【问题讨论】:

  • 是的,看起来寻找标题将是一个非常好的开始......现在您可以搜索方法来做到这一点。
  • 我实际上不知道如何处理这些数据......
  • 搜索:java中的二分查找
  • “不知道如何处理这些数据……” 到底是什么问题?你的意思是你不知道byteArray 是什么?或者你不能在字节内移动?或者您不能创建While 循环来搜索字节内的值?或者你甚至不能将你的十六进制转储带入 Java?您需要什么帮助?

标签: java png jpeg gif


【解决方案1】:

我建议你:

  1. FileInputStream 的形式打开输入文件。
  2. 扫描输入,直到找到其中一个标题。
  3. 为输出文件打开一个新的FileOutputStream,使用正确的图像文件扩展名,并将内容复制到该文件,直到找到相应的页脚。
  4. 关闭输出流。
  5. 从第 2 步重新开始,直到到达流的末尾。
  6. 关闭输入流。完成。

【讨论】:

    【解决方案2】:

    Download的源代码和Marco Schmidt's jpegextractor的字节码。

    这适用于 jpg。

    对于png

    copyJpeg 函数替换为

    private void copypng(InputStream in, OutputStream out) throws
        IOException
    {
        boolean notFinished = true;
        long copiedBytes = 3;
        do
        {
            int v1 = in.read();
            if (v1 == 0x89) // marker
            {
                int v2 = in.read();
                if (v2 < 0) // end of file
                {
                    out.write(0x82);
                    copiedBytes++;
                    notFinished = false;
                }
                else
                if (v2 == 0x49) // embedded png stream ended
                {
                    // copy the end of stream marker
                    out.write(0x49);
                    out.write(0x45);
                    out.write(0x4E);
                    out.write(0x44);
                    out.write(0xAE);
                    out.write(0x42);
                    out.write(0x60);
                    out.write(0x82);
                    copiedBytes += 2;
                    notFinished = false;
                }
                else
                {
                    // copy the two bytes, just a marker of the embedded png
                    out.write(0x89);
                    out.write(v2);
                    copiedBytes += 2;
                }
            }
            else
            if (v1 == -1) // unexpected end of input file
            {
                notFinished = false;
            }
            else // just copy that value
            {
                out.write(v1);
                copiedBytes++;
            }
        }
        while (notFinished);
        totalBytes += copiedBytes;
        if (!quiet)
        {
            System.out.println(" (" + copiedBytes + " bytes)");
        }
        totalOutputFiles++;
        // close output stream
        try
        {
            out.close();
        }
        catch (IOException ioe)
        {
            // ignore error when closing output stream
        }
    }
    

    并将process(InputStream in)替换为

    private void process(InputStream in) throws
        IOException
    {
        int v1;
        do
        {
            v1 = in.read();
            if (v1 == 0x89)
            {
                int v2 = in.read();
                if (v2 == 0x50)
                {
                    int v3 = in.read();
                    if (v3 == 0x4E)
                    {
                        int v4 = in.read();
                        if (v4 == 0x47)
                        {
                            int v5 = in.read();
                            if (v5 == 0x0D)
                            {
                                int v6 = in.read();
                                if (v6 == 0x0A)
                                {
                                    int v7 = in.read();
                                    if (v7 == 0x1A)
                                    {
                                        int v8 = in.read();
                                        if (v8 == 0x0A)
                                        {
                                            OutputStream out = createNextOutputStream();
                                            out.write(v1);
                                            out.write(v2);
                                            out.write(v3);
                                            out.write(v4);
                                            out.write(v5);
                                            out.write(v6);
                                            out.write(v7);
                                            out.write(v8);
                                            copypng(in, out);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
        while (v1 != -1);
    }
    

    对于 gif, 将copyJpeg 函数替换为

    private void copygif(InputStream in, OutputStream out) throws
            IOException
        {
            boolean notFinished = true;
            long copiedBytes = 3;
            do
            {
                int v1 = in.read();
                if (v1 == 0x47) // marker
                {
                    int v2 = in.read();
                    if (v2 < 0) // end of file
                    {
                        out.write(0x00);
                        copiedBytes++;
                        notFinished = false;
                    }
                    else
                    if (v2 == 0x21) // embedded png stream ended
                    {
                        // copy the end of stream marker
                        out.write(0x21);
                        out.write(0x00);
                        out.write(0x00);
                        out.write(0x3B);
                        out.write(0x00);
                        copiedBytes += 2;
                        notFinished = false;
                    }
                    else
                    {
                        // copy the two bytes, just a marker of the embedded png
                        out.write(0x47);
                        out.write(v2);
                        copiedBytes += 2;
                    }
                }
                else
                if (v1 == -1) // unexpected end of input file
                {
                    notFinished = false;
                }
                else // just copy that value
                {
                    out.write(v1);
                    copiedBytes++;
                }
            }
            while (notFinished);
            totalBytes += copiedBytes;
            if (!quiet)
            {
                System.out.println(" (" + copiedBytes + " bytes)");
            }
            totalOutputFiles++;
            // close output stream
            try
            {
                out.close();
            }
            catch (IOException ioe)
            {
                // ignore error when closing output stream
            }
        }
    

    process(InputStream in)替换为

    private void process(InputStream in) throws
        IOException
    {
        int v1;
        do
        {
            v1 = in.read();
            if (v1 == 0x47)
            {
                int v2 = in.read();
                if (v2 == 0x49)
                {
                    int v3 = in.read();
                    if (v3 == 0x46)
                    {
                        int v4 = in.read();
                        if (v4 == 0x38)
                        {
                            int v5 = in.read();
                            if (v5 == 0x39)
                            {
                                int v6 = in.read();
                                if (v6 == 0x61)
                                {
                                    OutputStream out = createNextOutputStream();
                                    out.write(v1);
                                    out.write(v2);
                                    out.write(v3);
                                    out.write(v4);
                                    out.write(v5);
                                    out.write(v6);
                                    copygif(in, out);
                                }
                            }
                        }
                    }
                }
            }
        }
        while (v1 != -1);
    }
    

    并更新private void setDefaultArguments()outputSuffix的值

    【讨论】:

      猜你喜欢
      • 2018-01-12
      • 2013-01-09
      • 2011-03-21
      • 1970-01-01
      • 2012-03-15
      • 2011-02-01
      • 2010-09-29
      • 1970-01-01
      相关资源
      最近更新 更多