function imgCompressionArray = jpgcompression(imgArray)
%b = imread('lena.bmp');
b=imgArray;
%b = im2uint8(b);
% bb=uint8(b);
% imwrite(bb,'Lena1.bmp','bmp');
% figure(1);imshow(bb);% 显示原始图像
% b = double(b);
b_temp = b-128;
m = size(b_temp,1);n = size(b_temp,2);
%% 离散余弦变换DCT
b_DCT = zeros(m,n);
% 初始化DCT矩阵,便于计算
N = 8;
DCT_matrix = zeros(N,N);
for k = 1:N
for l = 1:N
DCT_matrix(k,l) = cos((2*(k-1)+1)*(l-1)*pi/(2*N));
end
end
% 将原始图像分块(NXN)并进行DCT变换
for k = 1:m/N
for l = 1:n/N
x1 = 1+N*(k-1);x2 = N*k;y1 = 1+N*(l-1);y2 = N*l;
b_DCT(x1:x2,y1:y2) = my_dct2(b_temp(x1:x2,y1:y2),DCT_matrix,N);
end
end
%% 量化
b_Q = zeros(m,n);
% 初始化量化矩阵(低频部分量化系数小,高频部分量化系数大),滤去更多高频信息
Q_matrix = zeros(N,N);Q11 = 4;step = 3;
for k = 1:N
for l = 1:N
Q_matrix(k,l) = Q11+step*(k-1)+step*(l-1);
end
end
% 将DCT后的矩阵进行量化并去整
for k = 1:m/N
for l = 1:n/N
x1 = 1+N*(k-1);x2 = N*k;y1 = 1+N*(l-1);y2 = N*l;
b_Q(x1:x2,y1:y2) = round(b_DCT(x1:x2,y1:y2)./Q_matrix);% 点除
end
end
%% 编码
% % 构建zigzag变换表(可以快速实现变换),注意仅适用于8X8矩阵
% zigzag = [ 0, 1, 8, 16, 9, 2, 3, 10, ...
% 17, 24, 32, 25, 18, 11, 4, 5, ...
% 12, 19, 26, 33, 40, 48, 41, 34, ...
% 27, 20, 13, 6, 7, 14, 21, 28, ...
% 35, 42, 49, 56, 57, 50, 43, 36, ...
% 29, 22, 15, 23, 30, 37, 44, 51, ...
% 58, 59, 52, 45, 38, 31, 39, 46, ...
% 53, 60, 61, 54, 47, 55, 62, 63];
% zigzag = zigzag+1;
b_encode = zeros(m,n);number = 0;j = 0;
for k = 1:m/N
for l = 1:n/N
x1 = 1+N*(k-1);x2 = N*k;y1 = 1+N*(l-1);y2 = N*l;
% 将8X8矩阵zig-zag变换生成1X64数组,使连续的零个数最多
% B = reshape(b_Q(x1:x2,y1:y2),1,N*N);
% B_encode = B(zigzag);
B_encode = toZigzag(b_Q(x1:x2,y1:y2));
% 游程编码
for i = 1:N*N
if B_encode(i)~=0
% 第一个字节存储下一个非零值与上一个非零值之间0的个数
byte1 = uint8(j);% 使用无符号8位整型
% byte1 = bitshift(uint8(j),4);
% byte1 = byte1+uint8(1);
% 第二个字节存储下一个非零值
byte2 = int8(B_encode(i));% 使用有符号8位整型
b_encode(number+1) = byte1;
b_encode(number+2) = byte2;
j = 0;number = number+2;
else
j = j+1;
end
end
end
end
b_encode = b_encode(1:number);% 压缩后的数据
imgCompressionArray = b_encode;
%% 计算压缩比
code_bits = number*8;% 压缩数据大小(比特)
origin_bits = m*n*8;% 源数据大小(比特)
compression_ratio = origin_bits/code_bits;% 压缩比
disp('压缩比:');disp(compression_ratio);