2017-02-01 1 views
-1

Je travaille donc sur un programme en java qui crée une image rectangulaire (voir le lien ci-dessous) sous la forme d'une image ppm qui sera ensuite écrite dans un fichier ppm. Créer et écrire l'image dans le fichier que je reçois. Cependant, j'ai de la difficulté à créer dynamiquement l'image de sorte qu'elle fonctionne pour toutes les largeurs et hauteurs spécifiées. A ma connaissance, un fichier p3 ppm suit simplement le format suivant pour une image 4x4.Création d'une image PPM à écrire dans un fichier Java

P3 
4 4 
15 
0 0 0 0 0 0 0 0 0 15 0 15 
0 0 0 0 15 7 0 0 0 0 0 0 
0 0 0 0 0 0 0 15 7 0 0 0 
15 0 15 0 0 0 0 0 0 0 0 0 

Lorsque les trois premiers chiffres sont les têtes et le reste est tout simplement les valeurs rgb de chaque pixel. Mais j'ai du mal à comprendre comment je peux créer la matrice ci-dessus pour l'image ci-dessous et pour toutes les dimensions spécifiées car elle n'inclut pas les couleurs unies en ligne droite?

image à créer:

enter image description here

je me suis dit que je pouvais créer un ArrayList qui contient un tableau de valeurs rgb de sorte que chaque index dans la liste est un jeu de rgb suivi du prochain rgb mis à la droite. Cependant, je suis assez confus sur ce que seraient les valeurs rgb. Voici ce que j'ai:

public static void createImage(int width, int height){ 
     pic = new ArrayList(); 
     int[] rgb = new int[3]; 

     for(int i = 0; i <= width; i++){ 
      for(int j = 0; i <= height; j++){ 
       rgb[0] = 255-j; //random values as im not sure what they should be or how to calculate them    
       rgb[1] = 0+j; 
       rgb[1] = 0+j; 
       pic.add(rgb); 
      } 
     } 
    } 

Merci d'avance.


ÉDITÉ:: code mis à jour J'ai réussi à corriger la plupart des problèmes, cependant, l'image générée ne correspond pas à celui affiché ci-dessus. Avec ce code. Je reçois l'image suivante:

enter image description here

package ppm; 

    import java.awt.Color; 
    import java.awt.image.BufferedImage; 
    import java.io.File; 
    import java.io.FileInputStream; 
    import java.io.FileNotFoundException; 
    import java.io.FileOutputStream; 
    import java.io.IOException; 
    import java.util.ArrayList; 


    public class PPM { 

    private BufferedImage img; 
    private static final String imageDir = "Image/rect.ppm"; 
    private final static String filename = "assignment1_q1.ppm"; 

    private static byte bytes[]=null;  // bytes which make up binary PPM image 
    private static double doubles[] = null; 
    private static int height = 0; 
    private static int width = 0; 
    private static ArrayList pic; 
    private static String matrix=""; 

    /** 
    * @param args the command line arguments 
    */ 
    public static void main(String[] args) throws IOException { 
     createImage(200, 200); 
     writeImage(filename); 
    } 


    public static void createImage(int width, int height){ 
     pic = new ArrayList(); 
     int[] rgb = new int[3]; 
     matrix +="P3\n" + width + "\n" + height + "\n255\n"; 
     for(int i = 0; i <= height; i++){ 
      for(int j = 0; j <= width; j++){ 
       Color c = getColor(width, height, j, i); 
       //System.out.println(c); 
       if(c==Color.red){ 
         rgb[0] = (int) (255*factor(width, height, j, i)); 
         rgb[1] = 0; 
         rgb[2] = 0; 
       }else if(c==Color.green){ 
         rgb[0] = 0; 
         rgb[1] = (int) (255*factor(width, height, j, i)); 
         rgb[2] = 0; 
       }else if(c==Color.blue){ 
         rgb[0] = 0; 
         rgb[1] = 0; 
         rgb[2] = (int) (255*factor(width, height, j, i)); 
       }else if(c== Color.white){ 
         rgb[0] = (int) (255*factor(width, height, j, i)); 
         rgb[1] = (int) (255*factor(width, height, j, i)); 
         rgb[2] = (int) (255*factor(width, height, j, i)); 
       } 
       matrix += ""+ rgb[0] + " " + rgb[1] + " " + rgb[2] + " " ; 
       //System.out.println(""+ rgb[0] + " " + rgb[1] + " " + rgb[2] + " "); 
       //pic.add(rgb); 
      } 
      matrix += "\n"; 
     } 
    } 

    public static Color getColor(int width, int height, int a, int b){ 
     double d1 = ((double) width/height) * a; 
     double d2 = (((double) -width/height) * a + height); 

     if(d1 > b && d2 > b) return Color.green; 
     if(d1 > b && d2 < b) return Color.blue; 
     if(d1 < b && d2 > b) return Color.red; 
     return Color.white; 
    } 

    public static double factor(int width, int height, int a, int b){ 
     double factorX = (double) Math.min(a, width - a)/width * 2; 
     double factorY = (double) Math.min(b, height - b)/height * 2; 

     //System.out.println(Math.min(factorX, factorY)); 

     return Math.min(factorX, factorY); 
    } 

    public static void writeImage(String fn) throws FileNotFoundException, IOException { 

     //if (pic != null) { 

       FileOutputStream fos = new FileOutputStream(fn); 
       fos.write(new String(matrix).getBytes()); 

       //fos.write(data.length); 
       //System.out.println(data.length); 
       fos.close(); 
     // } 
    } 
} 

Répondre

0

Vous pouvez utiliser Linear functions pour modéliser les diagonales dans l'image. Gardez à l'esprit cependant que dans les coordonnées (0, 0) se trouvent dans le coin supérieur gauche de l'image!

que vous voulez créer une image avec les dimensions width et height, la diagonale du haut à gauche vers le bas à droite traverserait points (0, 0) et (width, height):

y = ax + t 

0  = a *  0 + t => t = 0 
height = a * width + 0 => a = height/width 

d1(x) = (height/width) * x 

Maintenant, nous pouvons calculer la fonction pour la deuxième diagonale. Cette diagonale va à travers les points (0, height) et , donc:

y = ax + t 

height = a *  0 + t  => t = height 
0  = a * width + height => a = -(height/width) 

d2(x) = -(height/width) * x + height 

De cela, nous pouvons déterminer si un certain point dans l'image ci-dessous ou au-dessus se trouve une diagonale. A titre d'exemple pour le point (a, b):

  • if d1(a) > b: (a, b) se situe au-dessus de la première diagonale (à gauche en haut à droite en bas), il doit donc être bleu ou vert. Sinon, il doit être rouge ou blanc

  • if d2(a) > b: (a, b) se trouve au-dessus de la deuxième diagonale, donc il doit être soit rouge ou vert.Sinon, il doit être blanc ou bleu

En appliquant les relations qu'il est facile de déterminer auquel des quatre couleurs d'un certain point appartient:

Color getColor(int width, int height, int a, int b){ 
    double d1 = ((double) height/width) * a; 
    double d2 = ((double) -height/width) * a + height; 

    if(d1 > b && d2 > b) return greenColor; 
    if(d1 > b && d2 < b) return blueColor; 
    if(d1 < b && d2 > b) return redColor; 
    return whiteColor; 
} 

Maintenant, il y a une dernière chose que nous devons prendre en compte: l'image s'assombrit vers ses frontières.

Une version plus sombre d'une couleur peut être créée en multipliant chaque canal par un facteur. Plus le facteur est bas, plus la couleur est sombre. Par souci de simplicité, je suppose que le changement de luminosité est linéaire à partir du centre de l'image. Comme la luminosité varie indépendamment selon deux axes, nous devons modéliser cela en calculant le changement le long des deux axes et en utilisant le maximum.

Le changement de luminosité en fonction de la distance du centre peut être modélisé en utilisant la distance à la frontière plus près de l'image en fonction de la distance par rapport au centre (sur un seul axe):

deltaX = min(a, width - a)/(width/2) 
deltaY = min(b, height - b)/(height/2) 

Donc, nous pouvons obtenir le facteur pour multiplier chaque canal de couleur de cette manière:

double factor(int width, int height, int a, int b){ 
    double factorX = (double) Math.min(a, width - a)/width * 2; 
    double factorY = (double) Math.min(b, height - b)/height * 2; 

    return Math.min(factorX, factorY); 
}