目录
针对字符的RLE压缩
针对一维对象的RLE压缩
针对二维图像的RLE压缩
至于为什么只考虑一位数:多位数可以用包装类Integer表示,并且实际压缩中不会单纯压缩字符,一般都是整个对象一起压缩,所以没必要两位相连的数与后面判断
public static StringBuffer RLE(char...chars){//行程编码方法,形参放char型数组
//因为频繁更改字符串,所以返回值不用String
StringBuffer dest = new StringBuffer();
//注意:StringBuffer必须用new,不然不分配空间
//StringBuffer dest = null;会空指针异常
for(int i = 0 ; i
//main方法中实现
String s1 = "1112233334455566777778889999";
StringBuffer s2 = RLE(s1.toCharArray());
System.out.println(s2.toString());
输出结果:1*3#2*2#3*4#4*2#5*3#6*2#7*5#8*3#9*4#
含义为:1出现了3次,2出现了2次......
先定义像素点:
public class PixelPoint {//一维像素点
private int grayScale;//灰度值
private int x;//x坐标
public PixelPoint(int grayScale,int x){
this.grayScale = grayScale;
this.x = x;
}
public int getX(){
return this.x;
}
public int getGrayScale() {
return grayScale;
}
}
定义像素点的压缩方法:
public static LinkedHashMap RLE(ArrayList px){
//形参放入ArryaList,返回值用LinkedHashMap存储键值对,并且LinkedHashMap可以按添加顺序遍历
LinkedHashMap linkedHashMap = new LinkedHashMap<>();
for(int i = 0 ; i < px.size() ; ){//
int j = i;
boolean bo = true;
int count = 1;//计相同个数
while(bo){
if(i
载入像素点:并使用上面定义好的压缩方法,最后迭代器遍历(完整源码如下)
public class RLE_complex_one {//对一维像素点的RLE算法测试
public static void main(String[] args) {
//此例中所有像素点x坐标连续分布,故暂不考虑排序,用ArrayList效率更高
ArrayList arrayList = new ArrayList<>(20);//初始容量设为20(默认是10,每次扩大1.5X)
//以下模拟像素点的连续排布及灰度值情况
arrayList.add(new PixelPoint(1,1));
arrayList.add(new PixelPoint(1,2));
arrayList.add(new PixelPoint(1,3));
arrayList.add(new PixelPoint(1,4));
arrayList.add(new PixelPoint(1,5));
arrayList.add(new PixelPoint(50,6));
arrayList.add(new PixelPoint(50,7));
arrayList.add(new PixelPoint(50,8));
arrayList.add(new PixelPoint(50,9));
arrayList.add(new PixelPoint(255,10));
arrayList.add(new PixelPoint(255,11));
arrayList.add(new PixelPoint(255,12));
arrayList.add(new PixelPoint(255,13));
arrayList.add(new PixelPoint(255,14));
arrayList.add(new PixelPoint(255,15));
arrayList.add(new PixelPoint(255,16));
arrayList.add(new PixelPoint(255,17));
arrayList.add(new PixelPoint(255,18));
LinkedHashMap rleDest = RLE(arrayList);//返回编码结果
//以下用迭代器遍历
Set> entries = rleDest.entrySet();
Iterator> iterator = entries.iterator();
int i = 1;
while(iterator.hasNext()){
Map.Entry nextentries = iterator.next();
System.out.println("第"+i+"位压缩后的元素的灰度值是:"+nextentries.getKey().getGrayScale()+",且压缩了"+nextentries.getValue()+"个连续的像素点");
i++;
}
}
public static LinkedHashMap RLE(ArrayList px){
//形参放入ArryaList,返回值用LinkedHashMap存储键值对,并且LinkedHashMap可以按添加顺序遍历
LinkedHashMap linkedHashMap = new LinkedHashMap<>();
for(int i = 0 ; i < px.size() ; ){//
int j = i;
boolean bo = true;
int count = 1;//计相同个数
while(bo){
if(i
这样就把很多个连续的同值像素点压缩成了3个key-value对,数据量巨大的时候压缩效果很明显
上面的那个RLE是只考虑了一维的相关性,而考虑二维相关性的算法一般用WBS跳过白块编码,而不用RLE算法
把图像拆分为多个a×a的小方块,这个方块的灰度值相同
按上面的逻辑对方阵进行判断,具体实现十分复杂,matlab和python有现成的库,此文不再对此进行研究。
一维压缩不光可以用于图片处理,对于大量的连续值的数据存储压缩效果都很好