2017-02-01 17 views
-1

поэтому я работаю над программой в java, которая создает прямоугольное изображение (см. Ссылку ниже) в виде изображения ppm, которое будет записано в файл ppm. Создание и запись изображения в файл, который я получаю. Тем не менее, мне трудно создавать изображение динамически, так что он работает для любой ширины и высоты. По моему мнению, файл p3 ppm просто следует за следующим форматом для изображения 4x4.Создание изображения PPM для написания файла 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 

где первые три цифры являются заголовки, а остальное просто значения RGB каждого пикселя. Но мне трудно понять, как я могу создать указанную выше матрицу для изображения ниже и для любых размеров, указанных, поскольку он не включает сплошные цвета по прямой?

Изображение будет создано:

enter image description here

Я полагал, что я мог бы создать ArrayList, который хранит массив значений RGB таким образом, что каждый индекс в списке один RGB набор затем следующий RGB установлен в право. Однако я совершенно смущен тем, что будут значения rgb. Вот что у меня есть:

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); 
      } 
     } 
    } 

Заранее спасибо.


Редакции:: Обновленный кодом мне удалось исправить большинство проблем, однако, изображение, сформированное не соответствует тому, размещенному выше. С помощью этого кода. Я получаю следующее изображение:

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(); 
     // } 
    } 
} 

ответ

0

Вы можете использовать Linear functions для моделирования диагоналей на картинке. Имейте в виду, что в координатах (0, 0) лежат в верхнем левом углу изображения!

Допустим, вы хотите создать изображение с размерами width и height, диагональ из левого верхнего угла в правый нижний пересечет точки (0, 0) и (width, height):

y = ax + t 

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

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

Теперь мы можем вычислить функцию для второй диагонали. Эта диагональ проходит через точку (0, height) и , так:

y = ax + t 

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

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

Из этого мы можем определить, находится ли определенная точка на изображении ниже или выше диагонали. В качестве примера для точки (a, b):

  • if d1(a) > b: (а, б) лежит над первой диагональной (слева-сверху правой нижней части), таким образом, он должен быть либо синий или зеленый цвет. В противном случае он должен быть либо красным, либо белым

  • if d2(a) > b: (a, b) лежит над второй диагональю, поэтому он должен быть красным или зеленым.В противном случае он должен быть белым или синим

Применяя оба отношения это легко определить, к какой из четырех цветов определенная точка принадлежит:

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; 
} 

Теперь есть одна последняя вещь, которую мы должны принять во внимание: изображение темнеть к его границам.

Более темную версию цвета можно создать, умножив каждый канал с коэффициентом. Чем ниже коэффициент, тем темнее получится цвет. Для простоты я предполагаю, что изменение яркости линейно от центра изображения.

Поскольку яркость изменяется независимо друг от друга на две оси, нам необходимо смоделировать это, вычислив изменение вдоль обеих осей и используя максимум.

Изменение яркости в зависимости от расстояния от центра можно смоделировать с помощью расстояния до более тесной границы изображения в зависимости от расстояния до центра (только по одной оси):

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

Таким образом, мы можем получить коэффициент, чтобы умножить каждый цветной канал таким образом:

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); 
} 

 Смежные вопросы

  • Нет связанных вопросов^_^