You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Python中使用UTF-16编码正确读写BCRF文件?

读取并保存SPIP生成的BCRF文件时图像错位问题

我尝试读取SPIP工具生成的*.bcrf文件,再将内容原样保存回*.bcrf文件,但结果不理想,生成的新图像出现错位。

以下是我使用的代码:

import struct

def read_bcrf_file(filename):
    header_size = 2048
    data_size = 900 * 900 * 4  # Assuming 32-bit floating point data (bcrf format)

    with open(filename, 'rb') as file:
        # Read the header
        header = file.read(header_size)

        # Parse the header values
        header_dict = {}
        decoded_header = header.decode('utf-16').replace('\x00', '')
        for line in decoded_header.split('\n'):
            if '=' in line:
                key, value = line.strip().split('=')
                header_dict[key.strip()] = value.strip()

        # Read the data
        data = file.read(data_size)

    return header_dict, data


def convert_data_to_float(data):
    float_data = struct.unpack('<' + 'f' * (len(data) // 4), data)
    return float_data


def write_bcr_file(filename, header_dict, data):
    header_size = 2048

    # Create the header string
    header = ""
    for key, value in header_dict.items():
        header += key + " = " + value + "\n"

    # Pad the header to the required size
    header = header.ljust(header_size, '\x00')

    with open(filename, 'wb') as file:
        # Write the header
        file.write(header.encode('utf-16')[2:])

        # Write the data
        data_bytes = struct.pack('<' + 'f' * len(data), *data)
        file.write(data_bytes)


# Example usage
header, binary_data = read_bcrf_file('test_file.bcrf')
data = convert_data_to_float(binary_data)
write_bcr_file('new.bcrf', header_dict=header, data=data)
# Process the data as needed

运行后生成的新BCRF文件打开时图像错位。


问题原因及修正方案

  1. 硬编码数据尺寸:原代码固定假设图像为900×900,但实际应从header中读取Width和Height字段,非该尺寸的文件会因读取错误长度的数据导致错位。

  2. Header编码与填充错误:

    • BCRF的header是UTF-16LE编码(带BOM),原代码写入时用utf-16编码后去掉前2字节(BOM),且填充单字节\x00,导致header总字节数不足2048,数据偏移。
    • 解析header时,应按UTF-16的换行符\r\n分割,而非\n,避免解析出无效内容。
  3. 数据读写冗余转换:读取时直接保留二进制数据即可,无需先转成float再打包,减少不必要的转换步骤,避免潜在格式错误。


修正后的代码

import struct

def read_bcrf_file(filename):
    header_size = 2048

    with open(filename, 'rb') as file:
        # 读取header二进制数据
        header_bytes = file.read(header_size)
        # 按UTF-16(带BOM)解析header
        decoded_header = header_bytes.decode('utf-16')
        header_dict = {}
        # 按\r\n分割行并过滤空行
        for line in decoded_header.split('\r\n'):
            line = line.strip()
            if '=' in line:
                key, value = line.split('=', 1)
                header_dict[key.strip()] = value.strip()
        
        # 从header获取实际宽高,兼容默认值
        width = int(header_dict.get('Width', 900))
        height = int(header_dict.get('Height', 900))
        data_size = width * height * 4
        # 读取原始数据字节
        data_bytes = file.read(data_size)

    return header_dict, data_bytes, width, height


def write_bcr_file(filename, header_dict, data_bytes, width, height):
    header_size = 2048

    # 重构header字符串,保留原始\r\n换行格式
    header_lines = [f"{key} = {value}" for key, value in header_dict.items()]
    header_str = '\r\n'.join(header_lines) + '\r\n'  # 末尾补充换行

    # 编码为UTF-16(带BOM)
    header_encoded = header_str.encode('utf-16')
    # 计算需要填充的双字节空字符数量
    padding_len = (header_size - len(header_encoded)) // 2
    if padding_len > 0:
        header_encoded += b'\x00\x00' * padding_len
    
    with open(filename, 'wb') as file:
        # 写入完整header(含BOM)
        file.write(header_encoded)
        # 写入原始数据字节
        file.write(data_bytes)


# 示例使用
header, data_bytes, width, height = read_bcrf_file('test_file.bcrf')
# 如需处理数据,可在此转换为float数组,处理后再转回字节
# float_data = struct.unpack('<' + 'f' * (width * height), data_bytes)
# # 数据处理逻辑...
# data_bytes = struct.pack('<' + 'f' * len(float_data), *float_data)
write_bcr_file('new.bcrf', header_dict=header, data_bytes=data_bytes, width=width, height=height)

关键修正点

  • 从header动态获取图像宽高,适配不同尺寸的BCRF文件。
  • 严格按照UTF-16LE编码处理header,填充双字节空字符确保header总字节数为2048。
  • 保留原始header的\r\n换行格式,避免重构时的格式偏差。
  • 直接读写原始数据字节,保证数据一致性。

内容的提问来源于stack exchange,提问作者Alex

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 09:08:10