Image Data

Image Data

hackini>2022(bugku)

通过给的json数据和提示宽:800;高:80画出图片

image

对应代码:

import json
from PIL import Image
import os

# 1. 配置文件名
INPUT_FILENAME = "E:\edge下载\imageData.json"
OUTPUT_FILENAME = "E:\edge下载\generated_image_from_file.png"


DEFAULT_WIDTH = 500
DEFAULT_HEIGHT = 80
DEFAULT_MODE = 'RGBA'

# ----------------------------------------------------
# 3. 读取和解析数据
try:
    if not os.path.exists(INPUT_FILENAME):
        print(f"错误:文件 '{INPUT_FILENAME}' 未找到。请确保文件路径正确。")
    else:
//创建一个文件对象,把文件对象赋值给变量f
        with open(INPUT_FILENAME, 'r') as f:
            data_dict = json.load(f)

        # 尝试从 JSON 数据中获取宽度、高度和模式
        IMAGE_WIDTH = data_dict.get('width', DEFAULT_WIDTH)
        IMAGE_HEIGHT = data_dict.get('height', DEFAULT_HEIGHT)
        IMAGE_MODE = data_dict.get(
            'mode', DEFAULT_MODE).upper()  # 转换为大写,以匹配PIL要求

        pixel_data_dict = data_dict.get("data", {})

        # 将字典形式的像素数据转换成有序的列表
        # 1. 获取所有的键,并将其转换为整数以便排序
        sorted_keys = sorted([int(k) for k in pixel_data_dict.keys()])

        # 2. 按照排序后的整数键重新提取值
        pixel_values = [pixel_data_dict[str(k)] for k in sorted_keys]

        # 4. 验证数据长度
        if IMAGE_MODE == 'RGBA':
            channels = 4
        elif IMAGE_MODE == 'RGB':
            channels = 3
        elif IMAGE_MODE == 'L':  # 灰度图
            channels = 1
        else:
            raise ValueError(f"不支持的图像模式: {IMAGE_MODE}")

        expected_length = IMAGE_WIDTH * IMAGE_HEIGHT * channels

        if len(pixel_values) != expected_length:
            print(
                f"警告:像素值数量 ({len(pixel_values)}) 与预期 ({expected_length}) 不匹配。")
            print(f"预期尺寸: {IMAGE_WIDTH}x{IMAGE_HEIGHT}, 模式: {IMAGE_MODE}")

# 接收字节流 (data): 接收所有像素的颜色值。确定像素结构 (mode): 知道每几个字节组合成一个像素。确定布局结构 (size): 知道每多少个像素组成一行。
        # 将列表转换为字节串
        image_bytes = bytes(pixel_values)

        # 使用 Image.frombytes 创建图像
'''
1. 图像的本质:像素数据的有序排列
在计算机中,一个位图图像(如 PNG, BMP, JPEG)本质上就是一个巨大的数字序列。这个序列中的每一个数字或每组数字都代表图像中的一个点——像素 (Pixel) 的颜色和/或透明度。
2.data=image_bytes
提供原始颜料: image_bytes 是一个字节序列(Python 的 bytes 类型),它包含了图像中所有像素点按顺序排列的颜色值。
例如,在 RGBA 模式下,这个序列是:R1, G1, B1, A1, R2, G2, B2, A2, ...。
Image.frombytes() 将这些原始字节视为图像的“颜料”。
3.mode=IMAGE_MODE (颜色模式)
决定如何解释颜料: mode(如 'RGBA', 'RGB', 'L' 等)告诉函数如何分组和解释这些原始字节。
如果 mode='RGB',函数知道每 3 个字节 为一组,代表一个像素的 (Red, Green, Blue) 值。
如果 mode='RGBA',函数知道每 4 个字节 为一组,代表一个像素的 (Red, Green, Blue, Alpha) 值。
如果 mode='L' (灰度),函数知道每 1 个字节 代表一个像素的灰度值。
4.size=(IMAGE_WIDTH, IMAGE_HEIGHT) (几何结构)
定义画板大小和顺序: size 告诉函数这个一维的、长长的字节序列应该如何被“折叠”成一个二维的矩形结构。
图像数据在内存中通常是按行存储的。
函数知道:在处理完 IMAGE_WIDTH * (每个像素的字节数) 个字节后,它应该“换行”,开始处理图像的下一行像素。
'''
        image = Image.frombytes(
            mode=IMAGE_MODE,
            size=(IMAGE_WIDTH, IMAGE_HEIGHT),
            data=image_bytes
        )

        # 6. 保存图像
        image.save(OUTPUT_FILENAME)
        print(f"成功从文件 '{INPUT_FILENAME}' 创建并保存图像为:{OUTPUT_FILENAME}")

except json.JSONDecodeError:
    print(f"错误:文件 '{INPUT_FILENAME}' 中的JSON数据解析失败,请检查格式。")
except ValueError as ve:
    print(f"错误:数据处理或模式校验失败: {ve}")
except Exception as e:
    print(f"处理图像时发生未知错误: {e}")

posted @ 2025-11-25 21:49  一只妙蛙  阅读(0)  评论(0)    收藏  举报