summaryrefslogtreecommitdiff
path: root/src/misc/CompressedImage.java
blob: b37daf998779cade582a91816756b9480eb98282 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
package misc;

import java.awt.Color;
import java.awt.image.BufferedImage;
import java.util.ArrayList;

public class CompressedImage {
	
	private BufferedImage image;
	private int blockWidth, blockHeight, colors;
	private byte[] data;
	
	public CompressedImage(BufferedImage image, int blockWidth, int blockHeight, int colors) {
		ArrayList<Byte[]> compData = new ArrayList<Byte[]>();
		int imageWidth = image.getWidth(), imageHeight = image.getHeight();
		this.image = new BufferedImage(imageWidth, imageHeight, image.getType());
		this.blockWidth = blockWidth;
		this.blockHeight = blockHeight;
		compData.add(Utils.intToByteArray(imageWidth));
		compData.add(Utils.intToByteArray(imageHeight));
		compData.add(Utils.intToByteArray(image.getType()));
		compData.add(Utils.intToByteArray(blockWidth));
		compData.add(Utils.intToByteArray(blockHeight));
		compData.add(Utils.intToByteArray(colors));
		Color[][] block;
		int[][][] table;
		boolean inList;
		ArrayList<Integer[]> list;
		for(int xb = 0; xb<imageWidth; xb+=blockWidth) {
			for(int yb = 0; yb<imageHeight; yb+=blockHeight) {
				block = new Color[blockWidth][blockHeight];
				list = new ArrayList<Integer[]>();
				x: for(int x = 0; x<blockWidth; x++) {
					y: for(int y = 0; y<blockHeight; y++) {
						System.out.println("Lese pixel: (" + (xb+x) + "," + (yb+y) + ")");
						if(xb+x>=imageWidth) break y;
						if(yb+y>=imageHeight) continue x;
						block[x][y] = new Color(image.getRGB(xb+x, yb+y));
						inList = false;
						for(int i = 0, size = list.size(); i<size; i++) {
							if(list.get(i)[0] == block[x][y].getRed() && list.get(i)[1] == block[x][y].getGreen() && list.get(i)[2] == block[x][y].getBlue() && list.get(i)[3] == block[x][y].getAlpha()) {
								list.set(i, new Integer[] { block[x][y].getRed(), block[x][y].getGreen(), block[x][y].getBlue(), block[x][y].getAlpha(), list.get(i)[4]+1 });
								inList = true;
							}
						}
						if(!inList)
							list.add(new Integer[] { block[x][y].getRed(), block[x][y].getGreen(), block[x][y].getBlue(), block[x][y].getAlpha(), 1 });
					}
				}
				int count = 0;
				Stapel a = new Stapel(), b = new Stapel(), c = new Stapel();
				for(int i = 0, size = list.size(); i<size; i++) {
					System.out.println("Zwischenspeichern... (" + i + "/" + size + ")");
					a.ablegen(list.get(i));
				}
				count = 0;
				while(!a.istLeer()) {
					System.out.println("Verarbeiten... (" + count + "/" + list.size() + ")");
					Integer[] top = (Integer[])a.entnehmen();
					while(!b.istLeer() && ((Integer[])b.inhaltGeben())[4] > top[4]) {
						a.ablegen(b.entnehmen());
						count--;
					}
					b.ablegen(top);
					count++;
				}
				Color[] palette = new Color[colors];
				Color previous = null;
				Integer[] current = null;
				for(int i = 0; i<palette.length; i++) {
					if(b.istLeer()) {
						if(previous == null) {
							palette[i] = new Color(0,0,0);
						} else {
							palette[i] = previous;
						}
					} else {
						current = (Integer[])b.entnehmen();
						palette[i] = new Color(current[0], current[1], current[2], current[3]);
						previous = new Color(current[0], current[1], current[2], current[3]);
					}
					
				}
				for(int i = 0; i<palette.length; i++) {
					compData.add(Utils.intToByteArray(palette[i].getRGB()));
				}
				int min, diff, smallest;
				x: for(int x = 0; x<blockWidth; x++) {
					y: for(int y = 0; y<blockHeight; y++) {
						if(xb+x>=imageWidth) break y;
						if(yb+y>=imageHeight) continue x;
						Color col = new Color(image.getRGB(xb+x, yb+y));
						min = 2000;
						diff = 0;
						smallest = 0;
						for(int i = 0; i<palette.length; i++) {
							if((diff = (int)Math.sqrt(Math.pow(((palette[i].getRed()+palette[i].getGreen()+palette[i].getBlue()+palette[i].getAlpha()) - (col.getRed()+col.getGreen()+col.getBlue()+col.getAlpha())), 2))) < min) {
								min = diff;
								smallest = i;
							}
						}
						this.image.setRGB(xb+x, yb+y, palette[smallest].getRGB());
						compData.add(new Byte[] {(byte)smallest});
					}
				}
			}
		}
		int total = 0;
		for(int i = 0, size = compData.size(); i<size; i++) {
			total += compData.get(i).length;
		}
		this.data = new byte[total];
		for(int i = 0, size = compData.size(); i<size; i++) {
			Byte[] current = compData.get(i);
			for(int j = 0; j<current.length; j++) {
				this.data[i+j] = current[j];
			}
		}
	}
	
	public BufferedImage getImage() {
		return image;
	}
	
	public byte[] getData() {
		return data;
	}

}