首页 > 其他分享 >REL定长压缩

REL定长压缩

时间:2022-11-29 01:44:06浏览次数:68  
标签:HX name img 压缩 定长 REL img1

定长REL压缩

压缩代码:

from PIL import Image
import numpy as np
import os

#打开一张二元图片并压缩成以REL_为前缀的文件


img_name=input("请输入图片名:")
size1=os.stat('./'+img_name)
size1=size1.st_size	# 原图片的大小

img1=Image.open(img_name)
img1=img1.convert('1')
img1_a=np.array(img1)
sz=img1_a.shape

cnt=int(0)
flag=img1_a[0][0]

L=len(img_name)
for i in range(L):
	if(img_name[i]=='.'):
		img_name=img_name[0:i]
		break

f=open("./REL_"+img_name,"wb")

# 存入图片的大小数据
h=sz[0]
w=sz[1]
lst=""
lst1=""

# 先高度后宽度
while(h):
	n=h%2
	lst=str(n)+lst
	h=int(h/2)
while(len(lst)<16):	#补齐成两个字节
	lst='0'+lst
hexStr=hex(int(lst,2))
hexStr=hexStr[2:]
if(len(hexStr)%2!=0):
	hexStr='0'+hexStr
f.write(bytes.fromhex(hexStr))		# bytes.fromhex(hex)的hex字串的位数必须是2的倍数
lst=""

while(w):
	n=w%2
	lst=str(n)+lst
	w=int(w/2)
while(len(lst)<16):	#补齐成两个字节
	lst='0'+lst
hexStr=hex(int(lst,2))
hexStr=hexStr[2:]
if(len(hexStr)%2!=0):
	hexStr='0'+hexStr
f.write(bytes.fromhex(hexStr))
lst=""

for i in range(sz[0]):
#	print(i)
	for j in range(sz[1]):
		exp=img1_a[i][j]
		if(img1_a[i][j]!=flag or cnt==7):
			while(cnt):
				k=cnt%2
				if(k):
					lst='1'+lst
				else:
					lst='0'+lst
				cnt=int(cnt/2)
			while(len(lst)<3):
				lst='0'+lst
			if(flag):
				lst='1'+lst
			else:
				lst='0'+lst
			lst1=lst1+lst
			lst=""
			if(len(lst1)==8):
				hexStr=hex(int(lst1,2))
				f.write(bytes.fromhex(hexStr[2:]))
				lst1=""
			flag=img1_a[i][j]
			cnt=1
		else:
			cnt+=1
if(lst):
	while(cnt):
		k=cnt%2
		if(k):
			lst='1'+lst
		else:
			lst='0'+lst
		cnt/=2
	while(len(lst)<3):
		lst='0'+lst
	if(flag):
		lst='1'+lst
	else:
		lst='0'+lst
	for i in range(4):
		lst=lst+'0'
	hexStr=hex(int(lst,2))
	f.write(bytes.fromhex(hexStr[2:]))

print("已压缩为文件:"+"./REL_"+img_name)

f.close()
size2=os.stat("./REL_"+img_name)
size2=size2.st_size

rate=(size2/size1)*100
print("压缩率为{:.2f}%".format(rate))

解压代码:

from PIL import Image
import numpy as np

name=input("请输入REL压缩后的文件:")
M_=np.zeros([2,16]) # 存放图片大小数据
f=open(name,'rb')

# 先读取图片的大小
h=f.read(2)     # 和汇编读取字节不一样,纯按顺序
hexStr=h.hex()
height=int(hexStr,16)   # 高度
h=f.read(2)
hexStr=h.hex()
width=int(hexStr,16)   # 宽度


M=np.zeros([height,width])     # 传入一个列表来表示0矩阵的规模,行x列

pos=0 #计数器
while(1):
    h=f.read(1)
    if(len(h)==0):
        break
    HX=h.hex()
   # print(HX)
    try:
        HX=int(HX,16)
    except:
        print("Q1;"+h)

    
    binStr=""
    while(HX):  # 转化成二进制数据
        n=HX%2
        binStr=str(n)+binStr
        HX=int(HX/2)
    while(len(binStr)<8):
        binStr='0'+binStr
    for i in range(2):
        try:
            numM=int(binStr[4*i])
            times=int(binStr[4*i+1:4*i+4],2)
        except:
            print(pos)
            print(binStr)
        for j in range(times):
            if(int(numM)):
                M[int(pos/width)][pos%width]=300
            else:
                M[int(pos/width)][pos%width]=0
           # print(pos)
            pos+=1
f.close()
img_new=Image.fromarray(M)
img_new=img_new.convert('1')    # 默认为浮点类型F,无法直接存储
img_new.save("./"+name+"_new.jpg")
print("已输出为图片:"+"./"+name+"_new.jpg")

合理地存储压缩信息能够有效提高压缩率,最糟糕的办法就是将压缩信息以文本方式存入文件中,这样做会起到负压缩的效果。将压缩信息保存为文本是非常浪费的,于是考虑将其保存在字节信息中。

采取定长REL压缩,取4位二进制数来保存每一段元素,一段元素最长为7个,存储为二进制的“000”,还有一位用于保存压缩连续的元素是1还是0,如要保存连续出现6次的元素1,6的二进制表示为“110”,因此最后存储为“1110”,第一位的1表示连续的元素是1,后面的“110”表示该元素出现了6次,两段元素拼接成一个字节,利用python的字节流将其存入文件中即可。读取时只要将该过程逆运算即可得到图片信息。为了保存图片的大小,在压缩信息前额外增添四个字节用于存储图片的尺寸,分别用两个字节(16位二进制最多可以表示十进制的65535)保存图片的高度和宽度。

参考:[

读取文件属性

RGB—RLE行程编码示例

[文件流](https://www.likecs.com/show-204965563.html#sc=2100 python),

读取文件属性

控制浮点数输出位数

]

标签:HX,name,img,压缩,定长,REL,img1
From: https://www.cnblogs.com/Forest-set-you/p/16934298.html

相关文章

  • Maven导入Spring5.2.6.RELEASE所有jar包
    <properties><spring.version>5.2.6.RELEASE</spring.version></properties><dependencies><!--springstart--><!--springcorestart--><depe......
  • 011relabel_configs详解
    写在之前prometheus配置文件大体框架有以下几个部分:data:  prometheus.yml:|#    rule_files:    -etc/prometheus/rules.yml    alerting:     ......
  • 同步压缩变换感性认识
    对WSST做出一个感性的认识并没有对具体的公式进行探究文章对一篇英文博客进行了翻译timefrequency参考了一篇《SynchrosqueezedWaveletTransforms:aToolforEmpi......
  • 010Prometheus配置文件中metric_relabel_configs详解
    Prometheus从数据源拉取数据后,会对原始数据进行编辑其中 ​​metric_relabel_configs​​​是Prometheus在保存数据前的最后一步标签重新编辑(relabel_configs)。所以,哪......
  • vs2012 发布网站Release发布模式 any cpu 与.net与mixed platforms 有什么区别?
    https://zhidao.baidu.com/question/304148101202171804.html这是目标平台的设定。一般来说包括但不局限于以下:x86:将程序集编译为由兼容x86的32位公共语言运行库(CLR)......
  • Linux:CentOS release 8.5 安装Mysql5.7
    添加Mysqlyum存储库下载安装软件包#下载软件包wgethttps://dev.mysql.com/get/mysql80-community-release-el7-6.noarch.rpm#安装软件包rpm-Uvhmysql80-commun......
  • 图数据库ONgDB Release v-1.0.2
    图数据库ONgDBReleasev-1.0.2​​图数据库ONgDBReleasev-1.0.2​​​​一、升级内容​​​​二、其它补充​​Here’sthetableofcontents:图数据库ONgDBReleasev......
  • WinRAR软件,添加压缩时,系统内存很快爆满,Windows系统卡死
    问题:WinRAR软件,添加压缩时,系统内存很快爆满,Windows系统卡死解析:软件bug,配置时,字典未初始化成功,导致内存溢出。解决:导出配置为,reg文件。修改不同的字段为下列数据后,重新导......
  • PARALLEL Related Hint
    PARALLELHintNoteonParallelHints BeginningwithOracleDatabase11gRelease2(11.2.0.1),the​​PARALLEL​​​and​​NO_PARALLEL​​​hintsarestatem......
  • 本地JS文件批量压缩
    最近在维护一个小后台项目,有段JS需要压缩上传到CDN存储服务器。由于之前压缩的JS文件都比较少,都是手动压缩的。这次需要压缩的文件比较多,所以用了批量压缩。特此记录一下......