从数据转储中提取JPEG / PNG / GIF图像

时间:2017-03-04 14:29:28

标签: java png jpeg gif

我从磁盘提供二进制/十六进制数据转储。我被赋予了从中提取图像的任务。它是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提取图像?

2 个答案:

答案 0 :(得分:0)

我建议你:

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

答案 1 :(得分:0)

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

并更新outputSuffix

private void setDefaultArguments()的值