gdx-studio

#libgdx#java#desktop

git clone https://git.pyrossh.dev/gdx-studio

An IDE for creating Games using libgdx and Java supported on all platforms Android, iOS, Desktop


src_libs/com/badlogic/gdx/tools/imagepacker/ColorBleedEffect.java
a62d533 1
a62d533 2
package com.badlogic.gdx.tools.imagepacker;
a62d533 3
a62d533 4
import com.badlogic.gdx.tools.imagepacker.ColorBleedEffect.Mask.MaskIterator;
a62d533 5
a62d533 6
import java.awt.image.BufferedImage;
a62d533 7
import java.util.NoSuchElementException;
a62d533 8
a62d533 9
/** @author Ruben Garat
a62d533 10
 * @author Ariel Coppes
a62d533 11
 * @author Nathan Sweet */
a62d533 12
public class ColorBleedEffect {
a62d533 13
	static int TO_PROCESS = 0;
a62d533 14
	static int IN_PROCESS = 1;
a62d533 15
	static int REALDATA = 2;
a62d533 16
	static int[][] offsets = { {-1, -1}, {0, -1}, {1, -1}, {-1, 0}, {1, 0}, {-1, 1}, {0, 1}, {1, 1}};
a62d533 17
a62d533 18
	ARGBColor color = new ARGBColor();
a62d533 19
a62d533 20
	public BufferedImage processImage (BufferedImage image, int maxIterations) {
a62d533 21
		int width = image.getWidth();
a62d533 22
		int height = image.getHeight();
a62d533 23
a62d533 24
		BufferedImage processedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
a62d533 25
		int[] rgb = image.getRGB(0, 0, width, height, null, 0, width);
a62d533 26
		Mask mask = new Mask(rgb);
a62d533 27
a62d533 28
		int iterations = 0;
a62d533 29
		int lastPending = -1;
a62d533 30
		while (mask.pendingSize > 0 && mask.pendingSize != lastPending && iterations < maxIterations) {
a62d533 31
			lastPending = mask.pendingSize;
a62d533 32
			executeIteration(rgb, mask, width, height);
a62d533 33
			iterations++;
a62d533 34
		}
a62d533 35
a62d533 36
		processedImage.setRGB(0, 0, width, height, rgb, 0, width);
a62d533 37
		return processedImage;
a62d533 38
	}
a62d533 39
a62d533 40
	private void executeIteration (int[] rgb, Mask mask, int width, int height) {
a62d533 41
		MaskIterator iterator = mask.new MaskIterator();
a62d533 42
		while (iterator.hasNext()) {
a62d533 43
			int pixelIndex = iterator.next();
a62d533 44
			int x = pixelIndex % width;
a62d533 45
			int y = pixelIndex / width;
a62d533 46
			int r = 0, g = 0, b = 0;
a62d533 47
			int count = 0;
a62d533 48
a62d533 49
			for (int i = 0, n = offsets.length; i < n; i++) {
a62d533 50
				int[] offset = offsets[i];
a62d533 51
				int column = x + offset[0];
a62d533 52
				int row = y + offset[1];
a62d533 53
a62d533 54
				if (column < 0 || column >= width || row < 0 || row >= height) continue;
a62d533 55
a62d533 56
				int currentPixelIndex = getPixelIndex(width, column, row);
a62d533 57
				if (mask.getMask(currentPixelIndex) == REALDATA) {
a62d533 58
					color.argb = rgb[currentPixelIndex];
a62d533 59
					r += color.red();
a62d533 60
					g += color.green();
a62d533 61
					b += color.blue();
a62d533 62
					count++;
a62d533 63
				}
a62d533 64
			}
a62d533 65
a62d533 66
			if (count != 0) {
a62d533 67
				color.setARGBA(0, r / count, g / count, b / count);
a62d533 68
				rgb[pixelIndex] = color.argb;
a62d533 69
				iterator.markAsInProgress();
a62d533 70
			}
a62d533 71
		}
a62d533 72
a62d533 73
		iterator.reset();
a62d533 74
	}
a62d533 75
a62d533 76
	private int getPixelIndex (int width, int x, int y) {
a62d533 77
		return y * width + x;
a62d533 78
	}
a62d533 79
a62d533 80
	static class Mask {
a62d533 81
		int[] data, pending, changing;
a62d533 82
		int pendingSize, changingSize;
a62d533 83
a62d533 84
		Mask (int[] rgb) {
a62d533 85
			data = new int[rgb.length];
a62d533 86
			pending = new int[rgb.length];
a62d533 87
			changing = new int[rgb.length];
a62d533 88
			ARGBColor color = new ARGBColor();
a62d533 89
			for (int i = 0; i < rgb.length; i++) {
a62d533 90
				color.argb = rgb[i];
a62d533 91
				if (color.alpha() == 0) {
a62d533 92
					data[i] = TO_PROCESS;
a62d533 93
					pending[pendingSize] = i;
a62d533 94
					pendingSize++;
a62d533 95
				} else
a62d533 96
					data[i] = REALDATA;
a62d533 97
			}
a62d533 98
		}
a62d533 99
a62d533 100
		int getMask (int index) {
a62d533 101
			return data[index];
a62d533 102
		}
a62d533 103
a62d533 104
		int removeIndex (int index) {
a62d533 105
			if (index >= pendingSize) throw new IndexOutOfBoundsException(String.valueOf(index));
a62d533 106
			int value = pending[index];
a62d533 107
			pendingSize--;
a62d533 108
			pending[index] = pending[pendingSize];
a62d533 109
			return value;
a62d533 110
		}
a62d533 111
a62d533 112
		class MaskIterator {
a62d533 113
			private int index;
a62d533 114
a62d533 115
			boolean hasNext () {
a62d533 116
				return index < pendingSize;
a62d533 117
			}
a62d533 118
a62d533 119
			int next () {
a62d533 120
				if (index >= pendingSize) throw new NoSuchElementException(String.valueOf(index));
a62d533 121
				return pending[index++];
a62d533 122
			}
a62d533 123
a62d533 124
			void markAsInProgress () {
a62d533 125
				index--;
a62d533 126
				changing[changingSize] = removeIndex(index);
a62d533 127
				changingSize++;
a62d533 128
			}
a62d533 129
a62d533 130
			void reset () {
a62d533 131
				index = 0;
a62d533 132
				for (int i = 0; i < changingSize; i++) {
a62d533 133
					int index = changing[i];
a62d533 134
					data[index] = REALDATA;
a62d533 135
				}
a62d533 136
				changingSize = 0;
a62d533 137
			}
a62d533 138
		}
a62d533 139
	}
a62d533 140
a62d533 141
	static class ARGBColor {
a62d533 142
		int argb = 0xff000000;
a62d533 143
a62d533 144
		public int red () {
a62d533 145
			return (argb >> 16) & 0xFF;
a62d533 146
		}
a62d533 147
a62d533 148
		public int green () {
a62d533 149
			return (argb >> 8) & 0xFF;
a62d533 150
		}
a62d533 151
a62d533 152
		public int blue () {
a62d533 153
			return (argb >> 0) & 0xFF;
a62d533 154
		}
a62d533 155
a62d533 156
		public int alpha () {
a62d533 157
			return (argb >> 24) & 0xff;
a62d533 158
		}
a62d533 159
a62d533 160
		public void setARGBA (int a, int r, int g, int b) {
a62d533 161
			if (a < 0 || a > 255 || r < 0 || r > 255 || g < 0 || g > 255 || b < 0 || b > 255)
a62d533 162
				throw new IllegalArgumentException("Invalid RGBA: " + r + ", " + g + "," + b + "," + a);
a62d533 163
			argb = ((a & 0xFF) << 24) | ((r & 0xFF) << 16) | ((g & 0xFF) << 8) | ((b & 0xFF) << 0);
a62d533 164
		}
a62d533 165
	}
a62d533 166
}