首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何在python中从十六进制数据创建bmp文件?

如何在python中从十六进制数据创建bmp文件?
EN

Stack Overflow用户
提问于 2016-12-29 11:38:14
回答 1查看 1.6K关注 0票数 1

十六进制数据数组只包含灰色颜色值,没有任何bmp文件信息。

但我知道分辨率(以像素为单位的宽度和高度),图像是灰色的,这意味着每个像素是8位。

是否有工具(在线或离线)或代码从数据生成bmp文件?

例如,下面的代码不起作用,结果是8*33

import matplotlib.pyplot as plt
import matplotlib.cm as cm
import numpy as np

s = "FFFFFFFF B0A7FFFF FFFFFFB3 807D8EFF FFFFFF94 707783CC FFFFFF89 7A8988A4 FFFFFFAD 929298BE FFFFFFAD 979AA8E2 FFFFFFAF 8991A9FF FFFFFF9F 808BA6FF FFFFFFAB 8694AFFF FFFFFFB2 8A96A0FF FFFFFFA8 859496FF FFFFFFB3 88809ADA FFFFFFA6 7B728DD7 FFFFFF85 6F7084D4 FFFFFF86 66647BDA FFFFFF8D 606482DD FFFFFF8B 666788DC FFFFFF7B 616282CE FFFFFF86 63657AC2 FFFFFFA1 72697FCB FFFFFF9B 75636FC6 FFFFFF88 6B596EC1 FFFFFF8B 675A80D5 FFFFFFA0 6D5E79DE FFFFFF8F 6B5C73FF FFFFD67F 605E8FFF FFFFDA7F 665B96FF FFFFD384 645A86FF FFFFFF84 6F6E86FF FFFFFFBE 979DC0FF FFFFFFFF C2CCFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFCBB9 9EB7FFFF FFBEA17C 677A99FF FFC59F66 565972C5 BACC9D70 595A76CA 9E997665 5E699EE0 977B6A6B 7F94B0FF FFBDA5A4 C4D9FFFF"

data = s.replace(" ", "").decode('hex')
plt.imsave('filename.bmp', np.array(data).reshape(8,33), cmap=cm.gray)
EN

回答 1

Stack Overflow用户

发布于 2018-07-03 08:25:18

我正在寻找一个类似问题的答案,但无法在“纯”python中找到一个“快速”可理解的解决方案。因此,我编写了一些代码来创建位图(从字符数组数据创建,在本例中转换为RGB值)。请阅读以下代码示例的麻省理工学院许可证后的评论。它们描述了从任何数据创建位图所需的信息。

我合并了来自http://blog.paphus.com/blog/2012/08/14/write-your-own-bitmaps/enter link description here的信息

我的输出是:

#!/usr/bin/python
# ----------------------- START MIT LICENSE -----------------------
# Copyright (c) 2018 Benjamin Spiegl

# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:

# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.

# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
# ----------------------- END MIT LICENSE -----------------------

# The pixel data has to be written with some minor modifications.
# First, the bottom row of the image appears first in the data.
# If you forget this step your image will be vertically flipped.
# Second, the pixes are written in BGR (blue - green - red) format, which is the opposite of the normal RGB.
# Finally, at the end of each row you must pad it with bytes till it is a multiple of 4.
# All numbers in the headers must be LITTLE-ENDIAN.
# For instance, when representing 54 as four bytes, those four bytes must be 54, 0, 0, 0.
# To represent 24 as two bytes, the two bytes must be 24, 0.

from numpy import array
from math import floor

def make_hex_list(int_val=None, force_byte_len=None, little_endian=True):
    if int_val is None:
        return []
    raw_pix_hex = hex(int_val)[2:]
    first_hex_str = ''  # is falsy
    if len(raw_pix_hex) % 2:  # odd number of hex vals
        first_hex_str = '0x0' + raw_pix_hex[0]
        raw_pix_hex = raw_pix_hex[1:]
    if first_hex_str:
        raw_pix_hex_list = [first_hex_str] + ['0x' + raw_pix_hex[lit_pair_idx * 2:lit_pair_idx * 2 + 2]
                                              for lit_pair_idx in range(int(floor(len(raw_pix_hex) / 2)))]
    else:
        raw_pix_hex_list = ['0x' + raw_pix_hex[lit_pair_idx * 2:lit_pair_idx * 2 + 2]
                            for lit_pair_idx in
                            range(int(floor(len(raw_pix_hex) / 2)))]  # max 4 bytes (32 bit) -> should be ok
    if force_byte_len and len(raw_pix_hex_list) != force_byte_len:  # force 4 bytes
        raw_pix_hex_list = ['0x00'] * (force_byte_len - len(raw_pix_hex_list)) + raw_pix_hex_list
    elif len(raw_pix_hex_list) > 4:
        raise OverflowError('base matrix too large for 32 bit bitmap.')
    if little_endian:
        return list(reversed([int(hx, 16) for hx in raw_pix_hex_list]))
    else:
        return [int(hx, 16) for hx in raw_pix_hex_list]

# A=yellow, T=red, C=green, G=blue, D=grey, N=black
bmp_BGR_colors = {'A': (0, 255, 255), 'T': (0, 0, 255), 'C': (0, 255, 0), 'G': (255, 0, 0),
                  'N': (0, 0, 0), 'D': (150, 150, 150)}

bmp_name = 'bitmap_test.bmp'
magnify = 16
mybase_arr = array([['G', 'A', 'G', 'A', 'D', 'D', 'T', 'T', 'A', 'N'],
                    ['G', 'A', 'G', 'A', 'A', 'D', 'T', 'T', 'A', 'N'],
                    ['G', 'A', 'G', 'A', 'A', 'D', 'T', 'T', 'A', 'N'],
                    ['G', 'A', 'G', 'A', 'A', 'D', 'T', 'T', 'A', 'N'],
                    ['G', 'A', 'G', 'A', 'A', 'D', 'T', 'T', 'A', 'N'],
                    ['G', 'A', 'G', 'A', 'A', 'D', 'T', 'T', 'A', 'N'],
                    ['G', 'A', 'G', 'A', 'A', 'D', 'T', 'T', 'A', 'N'],
                    ['G', 'A', 'G', 'A', 'A', 'D', 'T', 'T', 'A', 'N'],
                    ['G', 'A', 'G', 'A', 'A', 'D', 'T', 'T', 'A', 'N'],
                    ['G', 'A', 'G', 'A', 'A', 'D', 'T', 'T', 'A', 'N'],
                    ['G', 'A', 'G', 'A', 'A', 'D', 'T', 'T', 'A', 'N'],
                    ['G', 'A', 'G', 'A', 'A', 'D', 'T', 'T', 'A', 'N'],
                    ['G', 'A', 'G', 'A', 'A', 'D', 'T', 'T', 'A', 'N'],
                    ['G', 'A', 'G', 'A', 'A', 'D', 'T', 'T', 'A', 'N'],
                    ['G', 'A', 'G', 'A', 'A', 'D', 'T', 'T', 'A', 'N'],
                    ['G', 'A', 'G', 'A', 'A', 'D', 'T', 'T', 'A', 'N'],
                    ['N', 'A', 'G', 'A', 'A', 'D', 'T', 'T', 'A', 'N']])
arr_height, arr_width = mybase_arr.shape
# prepare header information
pixel_width = arr_width * magnify  # force 4 bytes
pixel_height = arr_height * magnify  # force 4 bytes
linepad = pixel_width * 3 % 4  # ensure valid row bytes (3 bytes per pixel; 1 per color channel)
total_pad = pixel_height * linepad
pix_offset = [0x36, 0x00, 0x00, 0x00]  # force 4 byte
raw_pix_data_size = pixel_width * pixel_height * 3 + total_pad
raw_pix_data_size_hex_list = make_hex_list(int_val=raw_pix_data_size, force_byte_len=4)
file_size = 0x36 + raw_pix_data_size  # force 4 byte
# create header values for byte conversion
header_vals = [0x42, 0x4d] + make_hex_list(int_val=file_size, force_byte_len=4) + [0x00]*4 + pix_offset + \
              [0x28, 0x00, 0x00, 0x00] + make_hex_list(int_val=pixel_width, force_byte_len=4) + \
              make_hex_list(int_val=pixel_height, force_byte_len=4) + \
              make_hex_list(int_val=1, force_byte_len=2) + \
              make_hex_list(int_val=24, force_byte_len=2) + make_hex_list(int_val=0, force_byte_len=4) + \
              raw_pix_data_size_hex_list + [0x13, 0x0b, 0x00, 0x00]*2 + [0x00, 0x00, 0x00, 0x00]*2
assert(len(header_vals) == pix_offset[0])
# create pixel values for byte conversion
if linepad:  # need to 0-pad lines to a multiple of 4 bytes per line
    pixel_vals = list()
    for reverse_row in list(reversed(mybase_arr)):
        for cpy in range(magnify):  # repeat line 16 times (magnify)
            pixel_vals.extend([val for pix in reverse_row for val in bmp_BGR_colors[pix] * magnify] + [0x00] * linepad)
else:  # no padding needed
    pixel_vals = [val for reverse_row in list(reversed(mybase_arr))
                  for cpy in range(magnify) for pix in reverse_row
                  for val in bmp_BGR_colors[pix]*magnify]  # last for to unpack tuples
assert(len(pixel_vals) == raw_pix_data_size)
with open(bmp_name, 'wb') as bmp_file:
    bmp_file.write(bytearray(header_vals + pixel_vals))  # convert values to bytes
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41372811

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档