testing some new stuff!
This commit is contained in:
147
src/main/java/io/swtc/proccessing/ImageEffectEngine.java
Normal file
147
src/main/java/io/swtc/proccessing/ImageEffectEngine.java
Normal file
@@ -0,0 +1,147 @@
|
||||
package io.swtc.proccessing;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
|
||||
public class ImageEffectEngine {
|
||||
|
||||
public static BufferedImage applyEffects(BufferedImage img, EffectState state, float[] currentGains) {
|
||||
if (img == null) return null;
|
||||
|
||||
int width = img.getWidth();
|
||||
int height = img.getHeight();
|
||||
BufferedImage result = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
|
||||
|
||||
for (int y = 0; y < height; y++) {
|
||||
for (int x = 0; x < width; x++) {
|
||||
int rgb = img.getRGB(x, y);
|
||||
int r = (rgb >> 16) & 0xFF;
|
||||
int g = (rgb >> 8) & 0xFF;
|
||||
int b = rgb & 0xFF;
|
||||
|
||||
// 1. AWB
|
||||
if (state.awbEnabled) {
|
||||
float s = state.awbStrength / 100f;
|
||||
r = (int) Math.min(255, r * (1 + (currentGains[0] - 1) * s));
|
||||
g = (int) Math.min(255, g * (1 + (currentGains[1] - 1) * s));
|
||||
b = (int) Math.min(255, b * (1 + (currentGains[2] - 1) * s));
|
||||
}
|
||||
|
||||
// 2. Temp & Tint
|
||||
if (state.temperature != 0) {
|
||||
float factor = state.temperature / 100f;
|
||||
r = clamp(r + (int)(factor * 30));
|
||||
b = clamp(b - (int)(factor * 30));
|
||||
}
|
||||
if (state.tint != 0) {
|
||||
g = clamp(g + (int)((state.tint / 100f) * 20));
|
||||
}
|
||||
|
||||
// 3. Saturation
|
||||
if (state.saturation != 100) {
|
||||
float factor = state.saturation / 100f;
|
||||
float gray = (r + g + b) / 3f;
|
||||
r = clamp((int)(gray + (r - gray) * factor));
|
||||
g = clamp((int)(gray + (g - gray) * factor));
|
||||
b = clamp((int)(gray + (b - gray) * factor));
|
||||
}
|
||||
|
||||
// 4. Shadows/Highlights
|
||||
float lum = (r + g + b) / 3f / 255f;
|
||||
if (lum < 0.5f && state.shadows != 0) {
|
||||
int adj = (int)((state.shadows / 100f) * (1 - lum * 2) * 50);
|
||||
r = clamp(r + adj); g = clamp(g + adj); b = clamp(b + adj);
|
||||
} else if (lum > 0.5f && state.highlights != 0) {
|
||||
int adj = (int)((state.highlights / 100f) * (lum * 2 - 1) * 50);
|
||||
r = clamp(r + adj); g = clamp(g + adj); b = clamp(b + adj);
|
||||
}
|
||||
|
||||
result.setRGB(x, y, (r << 16) | (g << 8) | b);
|
||||
}
|
||||
}
|
||||
|
||||
if (state.sharpness != 100 || state.edgeEnhance) {
|
||||
result = applySharpness(result, state.sharpness / 100f, state.edgeEnhance);
|
||||
}
|
||||
|
||||
if (state.dnrEnabled) {
|
||||
result = applyDenoise(result, state.dnrSpatial / 100f);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static BufferedImage applySharpness(BufferedImage img, float amount, boolean edgeEnhance) {
|
||||
if (amount == 1f && !edgeEnhance) return img;
|
||||
|
||||
int width = img.getWidth();
|
||||
int height = img.getHeight();
|
||||
BufferedImage result = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
|
||||
|
||||
float[][] kernel = edgeEnhance ?
|
||||
new float[][]{{0, -1, 0}, {-1, 5, -1}, {0, -1, 0}} :
|
||||
new float[][]{{-1, -1, -1}, {-1, 9, -1}, {-1, -1, -1}};
|
||||
|
||||
for (int y = 1; y < height - 1; y++) {
|
||||
for (int x = 1; x < width - 1; x++) {
|
||||
float r = 0, g = 0, b = 0;
|
||||
|
||||
for (int ky = -1; ky <= 1; ky++) {
|
||||
for (int kx = -1; kx <= 1; kx++) {
|
||||
int rgb = img.getRGB(x + kx, y + ky);
|
||||
float weight = kernel[ky + 1][kx + 1] * (amount - 1) / 8f;
|
||||
if (kx == 0 && ky == 0) weight += 1;
|
||||
|
||||
r += ((rgb >> 16) & 0xFF) * weight;
|
||||
g += ((rgb >> 8) & 0xFF) * weight;
|
||||
b += (rgb & 0xFF) * weight;
|
||||
}
|
||||
}
|
||||
|
||||
result.setRGB(x, y, (clamp((int)r) << 16) | (clamp((int)g) << 8) | clamp((int)b));
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static BufferedImage applyDenoise(BufferedImage img, float strength) {
|
||||
if (strength == 0) return img;
|
||||
|
||||
int width = img.getWidth();
|
||||
int height = img.getHeight();
|
||||
BufferedImage result = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
|
||||
|
||||
int radius = (int)(strength * 2) + 1;
|
||||
|
||||
for (int y = 0; y < height; y++) {
|
||||
for (int x = 0; x < width; x++) {
|
||||
int rSum = 0, gSum = 0, bSum = 0, count = 0;
|
||||
|
||||
for (int dy = -radius; dy <= radius; dy++) {
|
||||
for (int dx = -radius; dx <= radius; dx++) {
|
||||
int nx = Math.min(width - 1, Math.max(0, x + dx));
|
||||
int ny = Math.min(height - 1, Math.max(0, y + dy));
|
||||
|
||||
int rgb = img.getRGB(nx, ny);
|
||||
rSum += (rgb >> 16) & 0xFF;
|
||||
gSum += (rgb >> 8) & 0xFF;
|
||||
bSum += rgb & 0xFF;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
int r = rSum / count;
|
||||
int g = gSum / count;
|
||||
int b = bSum / count;
|
||||
|
||||
result.setRGB(x, y, (r << 16) | (g << 8) | b);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static int clamp(int val) {
|
||||
return Math.max(0, Math.min(255, val));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user