/**
  * Traitement d'images.
  */

import java.net.*;
import java.awt.image.*;
import javax.imageio.*;

public class TraitementImageEnConsole {

/**
* Menu principal de l'application.
*
* @return L'entier correspondant a l'option choisie.
*/
  public static int resultatExecutionMenu() {
    int v;
    Console.sautDeLigne();
    Console.afficherln("1: Charger une image depuis raphaello.univ-fcomte.fr");
    Console.afficherln("2: Charger une image depuis 127.0.0.1");
    Console.afficherln("3: Diminuer la luminosite de l'image");
    Console.afficherln("4: Augmenter la luminosite de l'image");
    Console.afficherln("5: Diminuer le contraste de l'image");
    Console.afficherln("6: Augmenter le contraste de l'image");
    Console.afficherln("7: Flouter l'image");
    Console.afficherln("8: Extraire les contours de l'image");
    Console.afficherln("0: Quitter");
    Console.afficher("Que voulez vous faire ? ");
    v = Console.saisirInt();
    Console.sautDeLigne();
    return v;
  }

/**
* Chargement d'une image sur Internet.
*
* @param url L'url de localisation de l'image.
*
* @return Le tableau image telecharge.
*/
  public static int [][] chargeImage(String url) {
    URL u;
    BufferedImage bi = null;
    try {
      u = new URL(url);
      bi = ImageIO.read(u); }
    catch (Exception e) { };
    while ( bi.getWidth() == 0 );
    int tx = bi.getWidth();
    int ty = bi.getHeight();
    int [] t = new int[tx*ty*3];
    t = bi.getRaster().getPixels(0,0,tx,ty,t);
    int [][] img = new int[tx][ty];
    int p = 0;
    for ( int y = 0 ; y < ty ; y++ )
      for ( int x = 0 ; x < tx ; x++ ) {
        img[x][y] = t[p]+t[p+1]*256+t[p+2]*65536;
        p = p+3; }
    return(img);
  }

/////////////////////////////////////////////////

/**
* Conversion d'une couleur RVB en un entier.
*
* @param r La composante de rouge de la couleur a convertir.
* @param v La composante de vert de la couleur a convertir.
* @param b La composante de bleu de la couleur a convertir.
*
* @return L'entier codant la Couleur
* selon la formule b*256*256+v*256+r.
*/
  public static int couleur(int r,int v,int b) {
    int couleur;
    couleur = b*256*256+v*256+r;
    return couleur;
  }

/**
* Diminution de la luminosite d'une image.
*
* @param img Le tableau image a traiter.
* @param prct Le pourcentage de modification.
*/
  static void diminuerLuminosite(int [][] img,double prct) {
    double fact = 1.0-prct/100.0;
    int r;
    int v;
    int b;
    for ( int x = 0 ; x < img.length ; x++ ) {
      for ( int y = 0 ; y < img[0].length ; y++ ) {
        r = img[x][y]%256;
        v = (img[x][y]/256)%256;
        b = img[x][y]/65536;
        r =(int) (r*fact);
        v =(int) (v*fact);
        b =(int) (b*fact);
        img[x][y] = couleur(r,v,b); } }
  }

/**
* Augmentation de la luminosite d'une image.
*
* @param img Le tableau image a traiter.
* @param prct Le pourcentage de modification.
*/
  static void augmenterLuminosite(int [][] img,double prct) {
    double fact = 1.0-prct/100.0;
    int r;
    int v;
    int b;
    for ( int x = 0 ; x < img.length ; x++ ) {
      for ( int y = 0 ; y < img[0].length ; y++ ) {
        r = img[x][y]%256;
        v = (img[x][y]/256)%256;
        b = img[x][y]/65536;
        r = 255 - (int) ((255-r)*fact);
        v = 255 - (int) ((255-v)*fact);
        b = 255 - (int) ((255-b)*fact);
        img[x][y] = couleur(r,v,b); } }
  }

/**
* Diminution du contraste d'une image.
*
* @param img Le tableau image a traiter.
* @param prct Le pourcentage de modification.
*/
  static void diminuerContraste(int [][] img,double prct) {
    double fact = 1.0-prct/100.0;
    int r;
    int v;
    int b;
    for ( int x = 0 ; x < img.length ; x++ ) {
      for ( int y = 0 ; y < img[0].length ; y++ ) {
        r = img[x][y]%256;
        v = (img[x][y]/256)%256;
        b = img[x][y]/65536;
        r = 127 -(int) ((127-r)*fact);
        v = 127 -(int) ((127-v)*fact);
        b = 127 -(int) ((127-b)*fact);
        img[x][y] = couleur(r,v,b); } }
  }

/**
* Augmentation du contraste d'une image.
*
* @param img Le tableau image a traiter.
* @param prct Le pourcentage de modification.
*/
  static void augmenterContraste(int [][] img,double prct) {
    double fact = 1.0-prct/100.0;
    int r;
    int v;
    int b;
    for ( int x = 0 ; x < img.length ; x++ ) {
      for ( int y = 0 ; y < img[0].length ; y++ ) {
        r = img[x][y]%256;
        v = (img[x][y]/256)%256;
        b = img[x][y]/65536;
        if ( r <= 127 )
          r =(int) (r*fact);
          else
          r = 255 - (int) ((255-r)*fact);
        if ( v <= 127 )
          v =(int) (v*fact);
          else
          v = 255 - (int) ((255-v)*fact);
        if ( b <= 127 )
          b =(int) (b*fact);
          else
          b = 255 - (int) ((255-b)*fact);
        img[x][y] = couleur(r,v,b); } }
  }

/* Fonction de clonage d'un tableau        */
/* a 2 indices de int                      */

  static int [][] clone(int [][] t) {
    int n = t.length;
    int m = t[0].length;
    int [][] nt = new int[n][m];
    for ( int i = 0 ; i < n ; i++ ) {
      for ( int j = 0 ; j < m ; j++ ) {
        nt[i][j] = t[i][j]; } }
    return nt;
  }

/**
* Floutage d'une image.
*
* @param img Le tableau image a traiter.
*/
  static void flouter(int [][] img) {
    int [][] image = clone(img);
    int r;
    int v;
    int b;
    int totr;
    int totv;
    int totb;
    int nb;
    for ( int x = 0 ; x < image.length ; x++ ) {
      for ( int y = 0 ; y < image[0].length ; y++ ) {
        totr = 0;
        totv = 0;
        totb = 0;
        nb = 0;
        for ( int xx = x-2 ; xx <= x+2 ; xx++ ) {
          for ( int yy = y-2 ; yy <= y+2 ; yy++ ) {
            if ( ( xx >= 0 ) && ( xx < image.length ) &&
                 ( yy >= 0 ) && ( yy < image[0].length ) ) {
              totr = totr+image[xx][yy]%256;
              totv = totv+(image[xx][yy]/256)%256;
              totb = totb+image[xx][yy]/65536;
              nb++; } } }
        r = totr/nb;
        v = totv/nb;
        b = totb/nb;
        img[x][y] = couleur(r,v,b); } }
  }

/**
* Extraction de contours dans une image.
*
* @param img Le tableau image a traiter.
*/
  static void extraireContours(int [][] img) {
    int [][] image = clone(img);
    int r;
    int v;
    int b;
    for ( int x = 0 ; x < image.length ; x++ ) {
      img[x][0] = 0;
      img[x][img[0].length-1] = 0; }
    for ( int y = 1 ; y < image[0].length-1 ; y++ ) {
      img[0][y] = 0;
      img[img.length-1][y] = 0; }
    for ( int x = 1 ; x < image.length-1 ; x++ ) {
      for ( int y = 1 ; y < image[0].length-1 ; y++ ) {
        r = 4*(image[x][y]%256);
        v = 4*((image[x][y]/256)%256);
        b = 4*(image[x][y]/65536);
        r = r-image[x-1][y]%256;
        v = v-(image[x-1][y]/256)%256;
        b = b-image[x-1][y]/65536;
        r = r-image[x+1][y]%256;
        v = v-(image[x+1][y]/256)%256;
        b = b-image[x+1][y]/65536;
        r = r-image[x][y-1]%256;
        v = v-(image[x][y-1]/256)%256;
        b = b-image[x][y-1]/65536;
        r = r-image[x][y+1]%256;
        v = v-(image[x][y+1]/256)%256;
        b = b-image[x][y+1]/65536;
        r = Math.abs(r);
        if ( r > 255 )
          r = 255;
        v = Math.abs(v);
        if ( v > 255 )
          v = 255;
        b = Math.abs(b);
        if ( b > 255 )
          b = 255;
        img[x][y] = couleur(r,v,b); } }
  }

/////////////////////////////////////////////////

/**
* Programme principal.
*
*/
  public static void main(String [] args) {
    Console.setTitle("TraitementImage");
    int choix;
    double prct;
    int [][] img = new int[640][480];
    int tx;
    int ty;
    EcranGraphique.init(50,50,900,700,800,600,"Traitement d'images");
    choix = resultatExecutionMenu();
    while ( choix != 0 ) {
      switch (choix) {
        case 1 : {
          String url = "http://raphaello.univ-fcomte.fr/Algo-S2/06-Matrices/Image.jpg";
          img = chargeImage(url);
          tx = img.length;
          ty = img[0].length;
          EcranGraphique.drawImage(0,0,img);
          EcranGraphique.flush(); }
          break;
        case 2 : {
          String url = "http://127.0.0.1:9000/Algo-S2/06-Matrices/Image.jpg";
          img = chargeImage(url);
          tx = img.length;
          ty = img[0].length;
          EcranGraphique.drawImage(0,0,img);
          EcranGraphique.flush(); }
          break;
        case 3 : {
          Console.afficher("Diminution de luminosité. De combien de % ? ");
          prct = Console.saisirDouble();
          diminuerLuminosite(img,prct);
          EcranGraphique.drawImage(0,0,img);
          EcranGraphique.flush(); }
          break;
        case 4 : {
          Console.afficher("Augmentation de luminosité. De combien de % ? ");
          prct = Console.saisirDouble();
          augmenterLuminosite(img,prct);
          EcranGraphique.drawImage(0,0,img);
          EcranGraphique.flush(); }
          break;
        case 5 : {
          Console.afficher("Diminution du contraste. De combien de % ? ");
          prct = Console.saisirDouble();
          diminuerContraste(img,prct);
          EcranGraphique.drawImage(0,0,img);
          EcranGraphique.flush(); }
          break;
        case 6 : {
          Console.afficher("Augmentation du contraste. De combien de % ? ");
          prct = Console.saisirDouble();
          augmenterContraste(img,prct);
          EcranGraphique.drawImage(0,0,img);
          EcranGraphique.flush(); }
          break;
        case 7 : {
          flouter(img);
          EcranGraphique.drawImage(0,0,img);
          EcranGraphique.flush(); }
          break;
        case 8 : {
          extraireContours(img);
          EcranGraphique.drawImage(0,0,img);
          EcranGraphique.flush(); }
          break; }
    choix = resultatExecutionMenu(); }
    EcranGraphique.exit();
  }
}