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 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194
|
/**
*
*/
package millie.se.image;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import millie.se.operator.helper.OperatorHelper;
import millie.util.ColorUtils;
/**
*
* Cette image aide à la manipulation rapide de BufferedImage en travaillant directement sur les pixels de destination
*
* Pour qu'un groupe de modification soit prise en compte, il faut terminer le traitement par "commit()"
*
* Il est possible d'utiliser simulaténement un accès au buffer et un appel aux méthodes set/getRGB qui travaillent sur le même buffer !
*
* @author florent
*
*/
public class ImageProcessor {
private BufferedImage image; //image d'origine
private BufferedImage valid; //image de type INT_ARGB ou RGB
private int[] pixels; //accès direct au format ARGB sur l'image valide
private int width; //largeur de l'aimge
public ImageProcessor(BufferedImage image) {
int type = image.getType();
if(type == BufferedImage.TYPE_BYTE_INDEXED)
throw new IllegalArgumentException("Type indexé non geré par ImageProcessor");
this.image = image;
if(type == BufferedImage.TYPE_INT_RGB || type == BufferedImage.TYPE_INT_ARGB) {
valid = image;
}
else {
if(image.getColorModel().hasAlpha())
valid = new BufferedImage(image.getWidth(), image.getHeight(), BufferedImage.TYPE_INT_ARGB);
else
valid = new BufferedImage(image.getWidth(), image.getHeight(), BufferedImage.TYPE_INT_RGB);
Graphics2D g2d = valid.createGraphics(); //copy
g2d.drawImage(image, 0,0,null);
g2d.dispose();
}
//récuperation du buffer
pixels = OperatorHelper.getDirectIntRGBAccess(valid);
}
/**
* Permet d'accèder directement aux pixels de l'image au format ARGB
* -> pour accèder au pixel (x,y), il faut utiliser pixels[x+image.getWidth()*y]
*
* @return
*/
public int[] getPixels() {
return pixels;
}
/**
* Helper pour positionner une couleur RGB en (x,y)
* NB : Il n'y a aucune vérification de dépassement
* @param x
* @param y
* @param rgb
*/
public void setRGB(int x, int y, int rgb) {
pixels[x+y*width] = rgb;
}
/**
* Helper pour positionner une couleur RGB en (x,y)
* NB : Il n'y a aucune vérification de dépassement
* @param x
* @param y
* @param r doit être entre 0 et 255
* @param g doit être entre 0 et 255
* @param b doit être entre 0 et 255
*/
public void setRGB(int x, int y, int r, int g, int b) {
pixels[x+y*width] = (r<<16)+(g<<8)+b;
}
private int clamp(int x) {
if(x<0) return 0;
if(x>255) return 255;
return x;
}
/**
* Repositionne les valeurs (r,g,b) dans 0-255
*
* @param x
* @param y
* @param r peut être <0 et >255
* @param g peut être <0 et >255
* @param b peut être <0 et >255
*/
public void setAndClampRGB(int x, int y, int r, int g, int b) {
setRGB(x,y,clamp(r), clamp(g), clamp(b));
}
/**
* Repositionne les valeurs (r,g,b,a ) dans 0-255
*
* @param x
* @param y
* @param r peut être <0 et >255
* @param g peut être <0 et >255
* @param b peut être <0 et >255
* @param a peut être <0 et >255
*/
public void setAndClampRGBA(int x, int y, int r, int g, int b, int a) {
setRGB(x,y,clamp(r), clamp(g), clamp(b), clamp(a));
}
/**
* Helper pour positionner une couleur RGBA en (x,y)
* NB : Il n'y a aucune vérification de dépassement
* @param x
* @param y
* @param r doit être entre 0 et 255
* @param g doit être entre 0 et 255
* @param b doit être entre 0 et 255
* @param a doit être entre 0 et 255
*/
public void setRGB(int x, int y, int r, int g, int b, int a) {
pixels[x+y*width] = (a<<24)+(r<<16)+(g<<8)+b;
}
/**
* Récupère la couleur au format RGB
* NB : Il n'y a aucune vérification de dépassement
* @param x
* @param y
* @return
*/
public int getRGB(int x, int y) {
return pixels[x+y*width];
}
/**
* Récupère directement les valeurs R/G/B/A dans rgbT.
* Si rgbT est de taille 3 => rgbT[0] = r, rgbT[1] = g, rgbT[2] = b;
* Si rgbT est de taille 4 => rgbT[0] = r, rgbT[1] = g, rgbT[2] = b, rgbT[3] = a
* @param x
* @param y
* @param rgbT
*/
public void getRGB(int x, int y, int[] rgbT) {
int rgb = getRGB(x, y);
if(rgbT.length==3)
ColorUtils.getRGB(rgb, rgbT);
else
ColorUtils.getRGBA(rgb, rgbT);
}
/**
* Récupère la couleur au format HSL
*
* @param x
* @param y
* @param hsl
*/
public void getHSL(int x, int y, double[] hsl) {
int rgb = getRGB(x,y);
ColorUtils.RGBToHSL(rgb, hsl);
}
/**
* Positionne la couleur au format HSL
*
* @param x
* @param y
* @param hsl
*/
public void setHSL(int x, int y, double[] hsl) {
setRGB(x,y,ColorUtils.HSLToRGB(hsl));
}
/**
* En cas de modification via un accès direct au buffer ou via aux méthodes get/setRGB, il faut appeler commit() pour prendre en compte les modifications
*/
public void commit() {
if(image!=valid) {
Graphics2D g2d = image.createGraphics();
g2d.drawImage(valid, 0,0,null);
g2d.dispose();
}
}
} |
Partager