RLE行程编码算法的java实现

目录

针对字符的RLE压缩

针对一维对象的RLE压缩

针对二维图像的RLE压缩


针对字符的RLE压缩

  • 针对纯字符的压缩
  • 不考虑两位数及以上的循环
  • 例如:用1*2#5*3#表示:11555两个1三个5,即 数*重复次数#

至于为什么只考虑一位数:多位数可以用包装类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次......

针对一维对象的RLE压缩

  • 对象具有一个属性值和一个坐标值
  • 不考虑独立多属性值,因为很难重复

 先定义像素点:

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

RLE行程编码算法的java实现_第1张图片

这样就把很多个连续的同值像素点压缩成了3个key-value对,数据量巨大的时候压缩效果很明显

针对二维图像的RLE压缩

上面的那个RLE是只考虑了一维的相关性,而考虑二维相关性的算法一般用WBS跳过白块编码,而不用RLE算法

把图像拆分为多个a×a的小方块,这个方块的灰度值相同

按上面的逻辑对方阵进行判断,具体实现十分复杂,matlab和python有现成的库,此文不再对此进行研究。

一维压缩不光可以用于图片处理,对于大量的连续值的数据存储压缩效果都很好

你可能感兴趣的:(算法,java,图像处理)