从数据转储中提取 JPEG/PNG/GIF 图像
Posted
技术标签:
【中文标题】从数据转储中提取 JPEG/PNG/GIF 图像【英文标题】:Extracting JPEG/PNG/GIF Images from Data dump 【发布时间】: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?您需要什么帮助?
【参考方案1】:
我建议你:
-
以
FileInputStream
的形式打开输入文件。
扫描输入,直到找到其中一个标题。
为输出文件打开一个新的FileOutputStream
,使用正确的图像文件扩展名,并将内容复制到该文件,直到找到相应的页脚。
关闭输出流。
从第 2 步重新开始,直到到达流的末尾。
关闭输入流。完成。
【讨论】:
【参考方案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
的值
【讨论】:
以上是关于从数据转储中提取 JPEG/PNG/GIF 图像的主要内容,如果未能解决你的问题,请参考以下文章
我的训练数据集中的隐藏文件使 tensorflow 返回“未知的图像文件格式。需要 JPEG、PNG、GIF、BMP 之一。”
Tensorflow Keras 错误:未知的图像文件格式。需要 JPEG、PNG、GIF、BMP 之一
Head First HTML与CSS — 为你的页面加图像