Как перевернуть изображение по горизонтали

Привет, мне было интересно, как отразить и изображение по горизонтали, для практического задания мне дали код, который считывает изображение, инвертируя его в изображение, указывающее его яркость от 0 до 5, мне нужно было перевернуть изображение.

Это мой код чтения изображения и его рисования.

    public int[][] readImage(String url) throws IOException
{
    // fetch the image
    BufferedImage img = ImageIO.read(new URL(url));

    // create the array to match the dimensions of the image
    int width = img.getWidth();
    int height = img.getHeight();
    int[][] imageArray = new int[width][height];

    // convert the pixels of the image into brightness values
    for (int x = 0; x < width; x++)
    {
        for (int y = 0; y < height; y++)
        {
            // get the pixel at (x,y) 

            int rgb = img.getRGB(x,y);
            Color c = new Color(rgb);
            int red = c.getRed();
            int green = c.getGreen();
            int blue = c.getBlue();

            // convert to greyscale
            float[] hsb = Color.RGBtoHSB(red, green, blue, null);                
            int brightness = (int)Math.round(hsb[2] * (PIXEL_CHARS.length - 1));

            imageArray[x][y] = brightness;
        }
    }
    return imageArray;
}

public void draw() throws IOException
{
    int[][] array = readImage("http://sfpl.org/images/graphics/chicklets/google-small.png");
    for(int i=0; i<array.length; i++)
    {
        for(int pic=0; pic<array[i].length; pic++)
        {
            if(array[pic][i] == 0)
            {
                System.out.print("X");
            }
            else if(array[pic][i] == 1)
            {
                System.out.print("8");
            }

            else if(array[pic][i] == 2)
            {
                System.out.print("0");
            }       

            else if(array[pic][i] == 3)
            {
                System.out.print(":");
            }

            else if(array[pic][i] == 4)
            {
                System.out.print(".");
            }

            else if (array[pic][i] == 5)
            {
                System.out.print(" ");
            }

            else 
            {
                System.out.print("error");
                break;
            }   

        }
        System.out.println();
    }
}    

и это код, который я пытался создать, чтобы отразить его по горизонтали,

void mirrorUpDown()
{
    int[][] array = readImage("http://sfpl.org/images/graphics/chicklets/google-small.png");
    int i = 0;

    for (int x = 0; x < array.length; x++)
    {
        for (int y = 0; y < array[i].length; y++)
        {{
                int temp = array[x][y]; 
                array[x][y]= array[-x][y]; 
                array[array[i].length-x][y]=temp;
            }
        }
    }

}    

я получаю сообщение об ошибке

 unreported exception java.io.IException;
 must be caught or declared to be thrown

person Judy Tran    schedule 24.09.2012    source источник
comment
С какой ошибкой вы столкнулись, пожалуйста, обновите ее здесь?   -  person gks    schedule 24.09.2012
comment
webmuch.com/image-flip-using-jquery   -  person Dilip Godhani    schedule 24.09.2012
comment
ошибка, с которой я сталкиваюсь, - это незарегистрированное исключение java.io.IException; должен быть пойман или объявлен брошенным @Stranger   -  person Judy Tran    schedule 24.09.2012
comment
Если вам нужно простое решение, взгляните на stackoverflow.com/questions/11911610/, в основном он использует метод отрицательного масштабирования, который приводит к изображение было перевернуто   -  person MadProgrammer    schedule 24.09.2012


Ответы (4)


Я бы на самом деле сделал это таким образом...

    BufferedImage flip(BufferedImage sprite){
        BufferedImage img = new BufferedImage(sprite.getWidth(),sprite.getHeight(),BufferedImage.TYPE_INT_ARGB);
        for(int xx = sprite.getWidth()-1;xx>0;xx--){
            for(int yy = 0;yy < sprite.getHeight();yy++){
                img.setRGB(sprite.getWidth()-xx, yy, sprite.getRGB(xx, yy));
            }
        }
    return img;
}

Просто цикл, в котором x начинается в конце первого изображения и помещает свое значение rgba в перевернутую позицию второго изображения. Чистый, простой код :)

person eProw    schedule 04.09.2017

Функция mirrorUpDown() , добавьте туда исключение throws IOException.

Кроме того, функция, из которой вы вызываете эти методы, обрабатывает исключение, делает ли этот код заключенным в блоке try catch или функция также настроена на выброс IOException (один из них должен быть там)

person Mukul Goel    schedule 24.09.2012
comment
Да, извините, я добавил бросок, так что это работает, но я продолжаю выходить за рамки, так как я сделал -x, но я не знаю, как это исправить, если я изменю -x на просто array.length-x, но я все еще выходит за рамки - person Judy Tran; 24.09.2012
comment
вопрос: какова цель i=0 вне цикла. i будет иметь значение 0 во всей функции? внутренний цикл всегда будет указывать на первую строку вашего массива изображений. также из связей: array[x][y] = array[-x][y] ; take an example x=1, y=1 then you are trying to do array[1][1] = array[-1][1] я не думаю, что массив содержит отрицательный индекс строки.. не так ли ?? - person Mukul Goel; 24.09.2012

Как ваше изображение должно знать, что оно должно получать данные из imageArray?

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

void flip(BufferedImage image) {
         WritableRaster raster = image.getRaster();
         int h = raster.getHeight();
         int w = raster.getWidth();
         int x0 = raster.getMinX();
         int y0 = raster.getMinY();
         for (int x = x0; x < x0 + w; x++){
             for (int y = y0; y < y0 + h / 2; y++){
                 int[] pix1 = new int[3];
                 pix1 = raster.getPixel(x, y, pix1);
                 int[] pix2 = new int[3];
                 pix2 = raster.getPixel(x, y0 + h - 1 - (y - y0), pix2);
                 raster.setPixel(x, y, pix2);
                 raster.setPixel(x, y0 + h - 1 - (y - y0), pix1);
             }
         }
         return;
    }
person Alix Martin    schedule 24.09.2012

Извините за публикацию этого здесь более года спустя, но это должно помочь кому-то на этапе

   try{
   java.awt.image.BufferedImage bi = javax.imageio.ImageIO.read(getClass().getResource("Your image bro.jpg")) ;
 int[] h = bi.getRGB(0, 0, bi.getWidth(), bi.getHeight(), null, 0, bi.getWidth());
 int [] h1 = new int[h.length];
 System.out.println(""+h.length);
  for(int j = 0;500>j;j++){
   for(int i = 500;i>0;i--){
         h1[j*500+(500-i)] = h[(j*500)+(i-1)];
   }
  }
 bi.setRGB(0, 0, bi.getWidth(), bi.getHeight(), h1, 0, bi.getWidth());
      }
      catch(Exception e){e.printStackTrace();}

Давайте сломаем код

java.awt.image.BufferedImage bi =javax.imageio.ImageIO.read(getClass().getResource("Your image bro.jpg"));

Пытается прочитать изображение и сохраняет прочитанное изображение в переменной BufferedImage bi.

  int[] h = bi.getRGB(0, 0, bi.getWidth(), bi.getHeight(), null, 0, bi.getWidth());
  int [] h1 = new int[h.length];

создать экземпляр двух массивов, h — исходный массив RGB, а h1 — массив RGB, перевернутый по горизонтали.

for(int j = 0;500>j;j++){
 for(int i = 500;i>0;i--){
  h1[j*500+(500-i)] = h[(j*500)+(i-1)];
 }
}

Давайте посмотрим на что-то в частности более внимательно

  h1[j*500+(500-i)] = h[(j*500)+(i-1)];

Изображения сканируются от позиции 0;0 до x.length;y.length, но сканируются в непрерывном массиве. Таким образом, мы используем псевдомассив для управления переворачиванием изображения. j*500 ссылается на значения Y, а (500-i) ссылается на значения x.

 bi.setRGB(0, 0, bi.getWidth(), bi.getHeight(), h1, 0, bi.getWidth());

Наконец, изображение сохраняется обратно в переменную BufferedImage.

Обратите внимание, что константа 500 указывает на ваше разрешение x изображения. Например, для изображения размером 1920 x 1080 используется максимальное значение 1920. Логика остается за вами.

person Community    schedule 18.12.2013