【源码】Python3创建1x1像素的图片

前言

Python3创建1x1像素的图片

GIF

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
import os
import struct


def pack_lzw_bits(codes, code_size):
"""Pack a list of integer codes into bytes, LSB-first (GIF LZW style)."""
bits = []
for code in codes:
for i in range(code_size):
bits.append((code >> i) & 1)
out = bytearray()
for i in range(0, len(bits), 8):
byte = 0
for j in range(8):
if i + j < len(bits):
byte |= bits[i + j] << j
out.append(byte)
return bytes(out)


def main():
# --- Header ---
header = b'GIF87a'

# --- Logical Screen Descriptor ---
# Packed byte 0x81: GCT flag=1, color resolution=0 (1 bit),
# sort=0, GCT size=1 => 2^(1+1) = 4 entries
screen_desc = struct.pack('<HHBBB', 1, 1, 0x81, 0, 0)

# --- Global Color Table (4 entries, all black) ---
gct = b'\x00\x00\x00' * 4

# --- Image Descriptor ---
image_desc = b'\x2c' + struct.pack('<HHHHB', 0, 0, 1, 1, 0)

# --- Image Data (LZW) ---
lzw_min_code_size = 8
clear_code = 1 << lzw_min_code_size # 256
eoi_code = clear_code + 1 # 257
code_size = lzw_min_code_size + 1 # 9 bits initially

# One black pixel (index 0): emit clear, 0, EOI
lzw_bytes = pack_lzw_bits([clear_code, 0, eoi_code], code_size)

# Sub-block: min code size, then data sub-block(s), then terminator
image_data = (
bytes([lzw_min_code_size])
+ bytes([len(lzw_bytes)]) + lzw_bytes
+ b'\x00'
)

# --- Trailer ---
trailer = b'\x3b'

data = header + screen_desc + gct + image_desc + image_data + trailer

out_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'black.gif')
with open(out_path, 'wb') as f:
f.write(data)
print(f'created {out_path}')


if __name__ == '__main__':
main()
  • Base64编码的图片原始数据
1
R0lGODdhAQABAIEAAAAAAAAAAAAAAAAAACwAAAAAAQABAAAIBAABBAQAOw==

JPEG

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
import os
import struct


# --- JPEG quantization tables (zig-zag order) ---

DQT_LUMINANCE = [
8, 6, 6, 7, 6, 5, 8, 7,
7, 7, 9, 9, 8, 10, 12, 20,
13, 12, 11, 11, 12, 25, 18, 19,
15, 20, 29, 26, 31, 30, 29, 26,
28, 28, 32, 36, 46, 39, 32, 34,
44, 35, 28, 28, 40, 55, 41, 44,
48, 49, 52, 52, 52, 31, 39, 57,
61, 56, 50, 60, 46, 51, 52, 50,
]

DQT_CHROMINANCE = [
9, 9, 9, 12, 11, 12, 24, 13,
13, 24, 50, 33, 28, 33, 50, 50,
50, 50, 50, 50, 50, 50, 50, 50,
50, 50, 50, 50, 50, 50, 50, 50,
50, 50, 50, 50, 50, 50, 50, 50,
50, 50, 50, 50, 50, 50, 50, 50,
50, 50, 50, 50, 50, 50, 50, 50,
50, 50, 50, 50, 50, 50, 50, 50,
]

# --- Standard JPEG Huffman tables ---
# Each table = (class_and_id, 16 count bytes, symbol bytes)

DC_LUMINANCE = (
0x00, # class 0 (DC), table id 0
[0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0],
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11],
)

DC_CHROMINANCE = (
0x01, # class 0 (DC), table id 1
[0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0],
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11],
)

AC_LUMINANCE = (
0x10, # class 1 (AC), table id 0
[0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 0x7d],
[
0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12,
0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07,
0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08,
0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0,
0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16,
0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28,
0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6,
0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5,
0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4,
0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2,
0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea,
0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
0xf9, 0xfa,
],
)

AC_CHROMINANCE = (
0x11, # class 1 (AC), table id 1
[0, 2, 1, 2, 4, 4, 3, 4, 7, 5, 4, 4, 0, 1, 2, 0x77],
[
0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21,
0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71,
0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91,
0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0,
0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34,
0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26,
0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38,
0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96,
0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5,
0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4,
0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3,
0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2,
0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda,
0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9,
0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
0xf9, 0xfa,
],
)

# Entropy-coded scan data for a 1x1 black pixel.
# Encodes 6 blocks (4Y + 1Cb + 1Cr, 4:2:0 sampling) with all-zero DCT
# coefficients using the standard Huffman tables above.
SCAN_DATA = b'\xf9\xfe\x8a\x28\xa0\x0f'


def segment(marker, payload):
"""Build a JPEG marker segment: FF xx + 2-byte length + payload."""
return marker + struct.pack('>H', len(payload) + 2) + payload


def dqt_segment(table_id, values):
"""Build a DQT marker segment (FF DB)."""
payload = bytes([table_id]) + bytes(values)
return segment(b'\xff\xdb', payload)


def dht_segment(class_and_id, counts, symbols):
"""Build a DHT marker segment (FF C4)."""
payload = bytes([class_and_id]) + bytes(counts) + bytes(symbols)
return segment(b'\xff\xc4', payload)


def main():
parts = []

# SOI
parts.append(b'\xff\xd8')

# APP0 - JFIF
parts.append(segment(
b'\xff\xe0',
b'JFIF\x00' # identifier + zero
b'\x01\x01' # version 1.1
b'\x00' # units (no units)
b'\x00\x01' # X density
b'\x00\x01' # Y density
b'\x00\x00', # no thumbnail
))

# DQT - luminance (table 0) and chrominance (table 1)
parts.append(dqt_segment(0x00, DQT_LUMINANCE))
parts.append(dqt_segment(0x01, DQT_CHROMINANCE))

# SOF0 - baseline DCT, 1x1, 3 components, 4:2:0 sampling
sof0_payload = struct.pack(
'>BHHB',
8, # precision (8 bits)
1, # height
1, # width
3, # number of components
)
# Component: id, sampling factors (H|V), quant table id
sof0_payload += bytes([1, 0x22, 0]) # Y: 2x2 sampling, QT 0
sof0_payload += bytes([2, 0x11, 1]) # Cb: 1x1 sampling, QT 1
sof0_payload += bytes([3, 0x11, 1]) # Cr: 1x1 sampling, QT 1
parts.append(segment(b'\xff\xc0', sof0_payload))

# DHT - four Huffman tables
parts.append(dht_segment(*DC_LUMINANCE))
parts.append(dht_segment(*AC_LUMINANCE))
parts.append(dht_segment(*DC_CHROMINANCE))
parts.append(dht_segment(*AC_CHROMINANCE))

# SOS - start of scan
sos_payload = struct.pack('>B', 3) # 3 components
sos_payload += bytes([1, 0x00]) # Y: DC table 0, AC table 0
sos_payload += bytes([2, 0x11]) # Cb: DC table 1, AC table 1
sos_payload += bytes([3, 0x11]) # Cr: DC table 1, AC table 1
sos_payload += bytes([0, 0x3f, 0x00]) # Ss=0, Se=63, Ah=0/Al=0
parts.append(segment(b'\xff\xda', sos_payload))

# Entropy-coded scan data
parts.append(SCAN_DATA)

# EOI
parts.append(b'\xff\xd9')

data = b''.join(parts)

out_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'black.jpg')
with open(out_path, 'wb') as f:
f.write(data)
print(f'created {out_path}')


if __name__ == '__main__':
main()
  • Base64编码的图片原始数据
1
/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjL/wAARCAABAAEDASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD5/ooooA//2Q==

PNG

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
import os
import struct
import zlib


def make_chunk(chunk_type, data):
"""Assemble a PNG chunk: length + type + data + CRC-32."""
length = struct.pack('>I', len(data))
crc = struct.pack('>I', zlib.crc32(chunk_type + data) & 0xFFFFFFFF)
return length + chunk_type + data + crc


def main():
# PNG signature
signature = b'\x89PNG\r\n\x1a\n'

# IHDR: width=1, height=1, bit depth=8, color type=2 (truecolor RGB),
# compression=0, filter=0, interlace=0
ihdr_data = struct.pack('>IIBBBBB', 1, 1, 8, 2, 0, 0, 0)
ihdr = make_chunk(b'IHDR', ihdr_data)

# IDAT: deflate-compressed scanline.
# One scanline = filter byte (0x00 = None) + 3 bytes (R=0, G=0, B=0)
raw_scanline = b'\x00\x00\x00\x00'
compressed = zlib.compress(raw_scanline, 6)
idat = make_chunk(b'IDAT', compressed)

# IEND
iend = make_chunk(b'IEND', b'')

data = signature + ihdr + idat + iend

out_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'black.png')
with open(out_path, 'wb') as f:
f.write(data)
print(f'created {out_path}')


if __name__ == '__main__':
main()
  • Base64编码的图片原始数据
1
iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAADElEQVR4nGNgYGAAAAAEAAH2FzhVAAAAAElFTkSuQmCC

BMP

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
import os
import struct


def main():
# BITMAPFILEHEADER (14 bytes)
file_header = struct.pack( # type: ignore[call-overload]
'<2sIHHI',
b'BM', # signature
58, # total file size (14 + 40 + 4)
0, # reserved1
0, # reserved2
54, # bfOffBits: offset from file start to pixel data
)

# BITMAPINFOHEADER (40 bytes)
info_header = struct.pack( # type: ignore[call-overload]
'<IiiHHIIiiII',
40, # biSize
1, # biWidth
1, # biHeight (positive => bottom-up)
1, # biPlanes
24, # biBitCount (24-bit RGB, no palette)
0, # biCompression (BI_RGB)
4, # biSizeImage (1 pixel * 3 bytes, padded to 4-byte row)
3780, # biXPelsPerMeter (~96 DPI)
3780, # biYPelsPerMeter (~96 DPI)
0, # biClrUsed
0, # biClrImportant
)

# Pixel data: one BGR black pixel + one padding byte (row must be 4-aligned)
pixel_data = b'\x00\x00\x00\x00'

data = file_header + info_header + pixel_data

out_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'black.bmp')
with open(out_path, 'wb') as f:
f.write(data)
print(f'created {out_path}')


if __name__ == '__main__':
main()
  • Base64编码的图片原始数据
1
Qk06AAAAAAAAADYAAAAoAAAAAQAAAAEAAAABABgAAAAAAAQAAADEDgAAxA4AAAAAAAAAAAAAAAAAAA==

WEBP

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
import os
import struct


def main():
width = 1
height = 1

# --- VP8 (lossy) bitstream for a 1x1 black keyframe ---
#
# Uncompressed 10-byte keyframe header:
# frame_tag (3 bytes) + start code (3 bytes) + dimensions (4 bytes)
#
# frame_tag (24-bit LE) packs:
# frame_type (1 bit) = 0 (keyframe)
# version (3 bits) = 0
# show_frame (1 bit) = 1
# first_part_size (19 bits)= 9 (size of the first data partition)
frame_type = 0
version = 0
show_frame = 1
first_part_size = 9

frame_tag = (frame_type
| (version << 1)
| (show_frame << 4)
| (first_part_size << 5))
frame_tag_bytes = struct.pack('<I', frame_tag)[:3] # 3 bytes, little-endian

start_code = b'\x9d\x01\x2a' # fixed VP8 keyframe magic
dimensions = struct.pack('<HH', width, height) # scale = 0

uncompressed_header = frame_tag_bytes + start_code + dimensions

# Boolean-coded VP8 frame header + residual for a 1x1 black keyframe.
# The first partition (9 bytes) carries the frame header; the remaining
# 5 bytes are the (empty) coefficient partition. These bytes are the
# entropy-coded output of the VP8 boolean encoder and cannot be derived
# from simple arithmetic, so they are embedded directly.
vp8_bitstream = bytes([
0x01, 0x40, 0x26, 0x25, 0xa4, 0x00, 0x03, 0x70, 0x00, # first partition (9)
0xfe, 0xfd, 0x36, 0x68, 0x00, # second partition (5)
])

vp8_data = uncompressed_header + vp8_bitstream

# --- RIFF container ---
chunk_id = b'VP8 ' # lossy VP8 chunk
chunk_size = struct.pack('<I', len(vp8_data))

webp_body = b'WEBP' + chunk_id + chunk_size + vp8_data

riff = b'RIFF' + struct.pack('<I', len(webp_body)) + webp_body

data = riff

out_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'black.webp')
with open(out_path, 'wb') as f:
f.write(data)
print(f'created {out_path}')


if __name__ == '__main__':
main()
  • Base64编码的图片原始数据
1
UklGRiQAAABXRUJQVlA4IBgAAAAwAQCdASoBAAEAAUAmJaQAA3AA/v02aAA=

完成