【问题标题】:How to read .img format image?如何读取 .img 格式的图像?
【发布时间】:2020-07-30 00:52:34
【问题描述】:

我有一张 .img 格式的图片。图像尺寸为 1920x1200 像素。这是一个 8 位深度的 RGB 图像。我正在使用以下 python 代码来恢复此图像。但是,错误可以显示图像但图像内容不正确。我不知道我哪里做错了。有人可以帮忙吗?

w, h = 1920, 1200   # img image size in px

# read img files and save them to png
with open(file_add, 'rb') as f:
    # Seek backwards from end of file by 3 bytes per pixel
    f.seek(-w*h*3, 2)
    img = np.fromfile(f, dtype=np.uint8).reshape((h, w, 3))

# Save as PNG, and retain 8-bit resolution
PIL.Image.fromarray(img).save('result.png')

我想上传 img 文件,但是它超过了 2Mb 的限制。

【问题讨论】:

  • 您是否尝试过直接使用 PIL 加载它,例如 PIL.Image.open(file_add)
  • "我想上传 img 文件,但是它超过了 2Mb 的限制。"你能制作一个导致同样问题的更小的文件吗? “可是,无法正确恢复。”这意味着什么?当你运行代码时会发生什么,这与应该发生的有什么不同?例如,如果它运行成功但result.png 看起来有问题,那么它有什么问题?
  • .img 并没有真正告诉您文件格式。例如,通道的顺序可以变化;或者不是将每个像素的数据存储在一起,它可以存储单独的颜色平面。文件来源中是否有一些可用的文档?
  • files with an .img extension 有几种不同的类型,但它们都不是用于图形图像本身的——这似乎是您所期望的。请edit您的问题并指定这些文件中数据的格式。
  • 感谢您的所有建议。是的,用我贴的代码可以打开img文件,但是图片不正确。 @KarlKnechtel,我没有来自文件源的文档。我也尝试只读取一个颜色平面,但它仍然给我一个错误的图像。 img 文件已上传到那里。任何人都可以帮助正确恢复它吗?谢谢

标签: python image numpy python-imaging-library


【解决方案1】:

你的文件是微软设计的某种可怕的“复合文件二进制格式”,描述为here。我不运行 Windows,所以我无法解压缩它。显然有可用的工具,但我不能保证其中任何一个:

https://openrpmsgfile.com/cfbf.html

http://fileformats.archiveteam.org/wiki/Microsoft_Compound_File

似乎有一个名为olefile 的Python 模块可以读取这些内容。我安装了它并能够测试您的文件并在其中找到您的图像,如下所示:

#!/usr/bin/env python3

import olefile
import numpy as np
from PIL import Image

# Open file
ole = olefile.OleFileIO('image.img')

# Get a directory listing
ole.dumpdirectory()                                                                        

# Open image stream within file and read
stream = ole.openstream('image/__102/DataObject')
data   = stream.read()

# Define image width, height and bytes per pixel
w, h, bpp = 1920, 1200, 3
imsize    = w * h * bpp

# Check data size and image size
print(f'Data size: {len(data)}, Image size: {imsize}')

# There are 192 bytes difference, assume it is a header and take our bytes from the tail of the file
data = data[-imsize:]

# Make into Numpy array
na = np.frombuffer(data, dtype=np.uint8).reshape((h*3,w))

# Convert from interleaved by line to interleaved by plane
R = na[0::3]
G = na[1::3]
B = na[2::3]
na = np.dstack((R,G,B))

# Make into PIL Image and save, but you could equally use OpenCV or scikit-image here
Image.fromarray(na).save('result.jpg')


运行脚本的示例输出:

'Root Entry' (root) 192 bytes 
  'NonDataObjects' (stream) 26 bytes 
  'Signature' (stream) 12 bytes 
  'image' (storage) 
    '__102' (storage) 
      'DataObject' (stream) 6912192 bytes 
      'DataObjectChilds' (stream) 4 bytes 
      'DataObjectStub' (stream) 6760 bytes 
Data size: 6912192, Image size: 6912000

我发现它是来自以下的 CFBF 文件。首先,如果你运行 Linux/Unix file 命令来确定文件的类型,你会得到:

file image.img
image.img: Composite Document File V2 Document, Cannot read section info

其次,如果您使用 xxd 转储文件,您将看到上面链接中提到的 CFBF 签名字节:

xxd image.img
00000000: d0cf 11e0 a1b1 1ae1 0000 0000 0000 0000  ................

关键字:OLE 文件、CFBF、Composite Document File V2 Document、IMG 格式、d0cf11e0a1b1

【讨论】:

    【解决方案2】:

    This 帖子似乎正在完成您正在寻找的内容。它改为使用 matplotlib 读取数据,但它仍然应该能够执行您想要的操作。

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多