3
3
#
4
4
# 这是一个灰度图像的 JPEG 压缩算法。
5
5
# 它不调用除了 numpy 以外的任何库,完整而简洁地展示了 JPEG 算法的原理。
6
+ # 简单起见,本代码只支持长和宽为 8 的倍数的图象,尽管 JPEG 标准支持长和宽不为 8 的倍数的图象。
6
7
#
7
- # 另外为了进行测试,它还调用了 PIL.Image 库用来读取待压缩的原始文件,但在JPEG 压缩算法中没用 PIL.Image 库。
8
+ # 另外为了进行测试,它还调用了 PIL.Image 库用来读取待压缩的原始文件,但在JPEG 压缩算法中完全不使用 PIL.Image 库。
8
9
#
9
10
# 你可以用它来进行图像图像压缩,比如,运行以下命令可以把 image.pgm (原始像素文件) 压缩成 image.jpg (JPEG压缩文件) 。
10
11
# python JpegEncoder.py image.pgm image.jpg
16
17
import numpy as np
17
18
from PIL .Image import open as imgopen
18
19
20
+
19
21
class BitstreamWriter ():
20
22
def __init__ (self ):
21
23
self .bitpos = 7
@@ -44,6 +46,7 @@ def flush(self):
44
46
def get (self ):
45
47
return self .stream
46
48
49
+
47
50
dct_mat = np .matrix ( [
48
51
[ 32 , 32 , 32 , 32 , 32 , 32 , 32 , 32 ],
49
52
[ 44 , 38 , 25 , 9 , - 9 ,- 25 ,- 38 ,- 44 ],
@@ -64,6 +67,7 @@ def get(self):
64
67
[21 ,34 ,37 ,47 ,50 ,56 ,59 ,61 ],
65
68
[35 ,36 ,48 ,49 ,57 ,58 ,62 ,63 ] ], dtype = np .int32 )
66
69
70
+
67
71
def shift_round_clip (x ):
68
72
y = np .int8 (x >> 16 )
69
73
if x >> 15 & 0x1 :
@@ -74,6 +78,7 @@ def shift_round_clip(x):
74
78
y = - 63
75
79
return y
76
80
81
+
77
82
def dct_quant_zig (tile ): # input tile must be (8*8)
78
83
tile = np .matrix (tile , dtype = np .int32 )
79
84
zig_vect = np .zeros ((64 ,), dtype = np .int8 )
@@ -85,6 +90,7 @@ def dct_quant_zig(tile): # input tile must be (8*8)
85
90
zig_vect [pos ] = shift_round_clip ( dct_tile [i ,j ] >> quant_level )
86
91
return zig_vect
87
92
93
+
88
94
def get_code (val ):
89
95
absval = val if val >= 0 else - val
90
96
length = 0
@@ -94,6 +100,7 @@ def get_code(val):
94
100
code = val if val >= 0 else (val - 1 )
95
101
return length , code
96
102
103
+
97
104
def bit_encoding (stream_writer , zig_vect ):
98
105
zero_cnt = 0
99
106
for ii , val in enumerate (zig_vect ):
@@ -107,6 +114,7 @@ def bit_encoding(stream_writer, zig_vect):
107
114
elif ii == 63 :
108
115
stream_writer .writebits ( 0x0f , 8 )
109
116
117
+
110
118
def jpeg_encoding (img_map ): # img_map must be a 2-dim numpy array, and has a height and width which can divide 8
111
119
h , w = img_map .shape
112
120
JpegStreamWriter = BitstreamWriter ()
0 commit comments