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 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155
| /**
*
*/
package millie.plugins.core.artistic;
import java.awt.image.BufferedImage;
import millie.image.PredefinedKernel;
import millie.plugins.GenericPluginFilter;
import millie.plugins.parameters.ComboBoxParameter;
import millie.plugins.parameters.IntSliderParameter;
import millie.se.operator.ConvolveOperator;
import millie.se.operator.extender.BorderExtenderCopy;
/**
* @author Xavier Philippeau
*
*/
public class BloomEffectPlugin extends GenericPluginFilter {
public BloomEffectPlugin() {
setPluginName("Effet Blooming RGB");
setLongProcessing(true);
//setRefreshable(true);
ComboBoxParameter visu = new ComboBoxParameter("visu", "Type de visualisation");
visu.addItem("normal", "Normal");
visu.addItem("mask", "Masque");
visu.addItem("blurmask", "Masque flouté");
addParameter(visu);
addParameter(new IntSliderParameter("threshold", "Seuil", 1,100,50));
addParameter(new IntSliderParameter("radius", "Rayon", 1,20,8));
addParameter(new IntSliderParameter("overlay", "Visibilité", 1,100,25));
}
@Override
public BufferedImage filter() throws Exception {
BufferedImage input = getInputImage();
int radius = getIntValue("radius");
double threshold = getIntValue("threshold")*0.01;
double overlay = getIntValue("overlay")*0.01;
// on cherche le max de luminosité
int graymax = 0;
for (int y = 0; y < input.getHeight(); y++) {
for (int x = 0; x < input.getWidth(); x++) {
int rgb = input.getRGB(x, y);
int gray = rgb2gray(rgb);
if (gray>graymax) graymax=gray;
}
}
int graythr = (int)(graymax*threshold);
// on calcule le masque
BufferedImage mask = new BufferedImage(input.getWidth(), input.getHeight(), input.getType());
for (int y = 0; y < input.getHeight(); y++) {
for (int x = 0; x < input.getWidth(); x++) {
int rgb = input.getRGB(x, y);
int gray = rgb2gray(rgb);
if (gray<=graythr) continue;
double ratio = ((double)(gray-graythr))/(graymax-graythr);
rgb = multiply(rgb,ratio);
mask.setRGB(x, y, rgb);
}
}
if(getStringValue("visu").equals("mask"))
return mask;
// on applique un flou gaussien
ConvolveOperator op = new ConvolveOperator(PredefinedKernel.getGaussianKernel(radius, radius*0.5), new BorderExtenderCopy());
double e0=energy(mask);
mask = op.compute(mask);
double e1=energy(mask);
// boost l'energie du masque flouté
double ratio = (e1==0)?0:e0/e1;
multiply(mask, ratio);
if(getStringValue("visu").equals("blurmask"))
return mask;
// overlay image + masque flouté
BufferedImage out = new BufferedImage(input.getWidth(), input.getHeight(), input.getType());
for (int y = 0; y < out.getHeight(); y++) {
for (int x = 0; x < out.getWidth(); x++) {
int rgbInput = input.getRGB(x, y);
int r = (rgbInput>>16)&0xFF;
int g = (rgbInput>>8)&0xFF;
int b = (rgbInput)&0xFF;
int rgbmask = mask.getRGB(x,y);
int rm = (rgbmask>>16)&0xFF;
int gm = (rgbmask>>8)&0xFF;
int bm = (rgbmask)&0xFF;
r = (int) Math.min(255, r + 2*overlay*rm );
g = (int) Math.min(255, g + 2*overlay*gm );
b = (int) Math.min(255, b + 2*overlay*bm );
out.setRGB(x,y, 0xFF000000+(r<<16)+(g<<8)+b);
}
}
return out;
}
// conversion rgb en niveau de gris (luminosité)
private int rgb2gray(int rgb) {
int r = (rgb >> 16) & 0xFF;
int g = (rgb >> 8) & 0xFF;
int b = rgb & 0xFF;
int l = (int)(0.299*r + 0.587*g + 0.114*b);
return l;
}
// calcul de l'energie d'une image
private double energy(BufferedImage c) {
int width = c.getWidth();
int height = c.getHeight();
double e=0;
for (int y=0; y<height; y++) {
for (int x=0; x<width; x++) {
int rgb=c.getRGB(x, y)&0xFF;
int v = rgb2gray(rgb);
e+=v*v;
}
}
return Math.sqrt(e);
}
// multiplication rgb par un facteur
private int multiply(int rgb , double factor) {
int r = (rgb >> 16) & 0xFF;
int g = (rgb >> 8) & 0xFF;
int b = rgb & 0xFF;
r = (int)Math.min(255,r*factor);
g = (int)Math.min(255,g*factor);
b = (int)Math.min(255,b*factor);
return 0xFF000000 + (r<<16) + (g<<8) + b;
}
// multiplication image par un facteur
private void multiply(BufferedImage c , double factor) {
int width = c.getWidth();
int height = c.getHeight();
for (int y=0; y<height; y++) {
for (int x=0; x<width; x++) {
int rgb = c.getRGB(x, y);
rgb = multiply(rgb,factor);
c.setRGB(x, y, rgb);
}
}
}
} |
Partager