12

I get RGB24 byte array and want to show it in Java.

public void getByteArray(byte byteArray[]){     
        int count1 = 0;
        byte temp1 = 0;

        for (int i = 0; i < byteArray.length; i++) {       //The order of RGB24 is red,green and blue.Change the
            //order to blue,green and red so that java can use TYPE_3BYTE_BGR to recognize it
            if (count1 == 0) {
                temp1 = byteArray[i];  
                count1++;
            } else if(count1 == 1) {
                //do nothing
                count1++;
            } else if(count1 == 2) {
                byteArray[i - 2] = byteArray[i];
                byteArray[i] = temp1;
                count1=0;
            }
        }
        image = new BufferedImage(width, height, BufferedImage.TYPE_3BYTE_BGR);
        image.getWritableTile(0, 0).setDataElements(0, 0, width, height, byteArray);

        mainPanel.repaint();

However,the effect is not conform to my requirement and it is strange. enter image description here

How can I flip the BufferedImage to the correct direction like this? enter image description here

Eugene
  • 10,627
  • 5
  • 49
  • 67
  • Do you want to rotate the image 180 degree? – Braj May 04 '14 at 15:14
  • 1
    It is unclear what you're asking. There are 3 answers: 1 telling you how to flip the image, one how to invert the colors, and one how to apply an AffineTransform. They're all different because the question is unclear. Please edit the question to give us more information about what you're trying to achieve. – mttdbrd May 04 '14 at 16:01
  • Question has been modified.Actually there is no problem with color presentation and I just want the image to be what it really is. – Eugene May 04 '14 at 16:49
  • Are you by any chance reading a BMP? :-) If so, you should just read each scanline from *bottom to top*, which is the correct way to read a BMP. – Harald K May 04 '14 at 20:57
  • But how to convert the byte array of image in color space of RGB24 to BMP? – Eugene May 05 '14 at 02:08
  • @upma If you want to swap the byte order from BGR to RGB, you can do that either while reading, or use a `SampleModel` with the bands inversed (BGR order). This has nothing to do with color space though. It is RGB in both cases. – Harald K May 06 '14 at 06:44

6 Answers6

23

There are 3 options: (EDIT ->: At least, there have been 3 options, until you edited the question <-)

  • You can flip the image vertically
  • You can rotate the image
  • You can invert the image

The difference is shown in this image:

ImageFlipTest01.png

Based on the image that you posted, I assume that you want to flip the image vertically. This can be done pixel by pixel, or (when it should be done efficiently) with an AffineTransformOp or by directly painting the image using a transformed Graphics2D.

import java.awt.Component;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.RenderingHints;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.awt.image.ByteLookupTable;
import java.awt.image.LookupOp;
import java.awt.image.LookupTable;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;

import javax.imageio.ImageIO;
import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class ImageFlipTest
{
    public static void main(String[] args)
    {
        SwingUtilities.invokeLater(new Runnable()
        {
            @Override
            public void run()
            {
                createAndShowGUI();
            }
        });
    }

    private static void createAndShowGUI()
    {
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().setLayout(new GridLayout(1, 1));

        BufferedImage image = null;
        try
        {
            image = convertToARGB(ImageIO.read(new File("lena512color.png")));
        }
        catch (IOException e1)
        {
            e1.printStackTrace();
        }

        JPanel panel = new JPanel(new GridLayout(2,2));
        panel.add(createComponent("Original", image));
        panel.add(createComponent("Flipped", createFlipped(image)));
        panel.add(createComponent("Rotated", createRotated(image)));
        panel.add(createComponent("Inverted", createInverted(image)));

        frame.getContentPane().add(panel);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    private static BufferedImage convertToARGB(BufferedImage image)
    {
        BufferedImage newImage = new BufferedImage(
            image.getWidth(), image.getHeight(),
            BufferedImage.TYPE_INT_ARGB);
        Graphics2D g = newImage.createGraphics();
        g.drawImage(image, 0, 0, null);
        g.dispose();
        return newImage;
    }    

    private static BufferedImage createFlipped(BufferedImage image)
    {
        AffineTransform at = new AffineTransform();
        at.concatenate(AffineTransform.getScaleInstance(1, -1));
        at.concatenate(AffineTransform.getTranslateInstance(0, -image.getHeight()));
        return createTransformed(image, at);
    }

    private static BufferedImage createRotated(BufferedImage image)
    {
        AffineTransform at = AffineTransform.getRotateInstance(
            Math.PI, image.getWidth()/2, image.getHeight()/2.0);
        return createTransformed(image, at);
    }

    private static BufferedImage createTransformed(
        BufferedImage image, AffineTransform at)
    {
        BufferedImage newImage = new BufferedImage(
            image.getWidth(), image.getHeight(),
            BufferedImage.TYPE_INT_ARGB);
        Graphics2D g = newImage.createGraphics();
        g.transform(at);
        g.drawImage(image, 0, 0, null);
        g.dispose();
        return newImage;
    }

    private static BufferedImage createInverted(BufferedImage image)
    {
        if (image.getType() != BufferedImage.TYPE_INT_ARGB)
        {
            image = convertToARGB(image);
        }
        LookupTable lookup = new LookupTable(0, 4)
        {
            @Override
            public int[] lookupPixel(int[] src, int[] dest)
            {
                dest[0] = (int)(255-src[0]);
                dest[1] = (int)(255-src[1]);
                dest[2] = (int)(255-src[2]);
                return dest;
            }
        };
        LookupOp op = new LookupOp(lookup, new RenderingHints(null));
        return op.filter(image, null);
    }

    private static Component createComponent(
        String title, BufferedImage image)
    {
        JLabel label = new JLabel(new ImageIcon(image));
        JPanel panel = new JPanel(new GridLayout(1,1));
        panel.add(label);
        panel.setBorder(BorderFactory.createTitledBorder(title));
        return panel;
    }
}
Marco13
  • 53,703
  • 9
  • 80
  • 159
  • 1
    Part of the intention in this (elaborate) answer was to point out the difference between flipping, rotating and inverting (before the question was clarified), and at the same time answering all three possible interpretations of the question. Now it may still serve as a snippet quarry, however. – Marco13 May 04 '14 at 17:15
  • You help me to understand my question more clearly and the flip function you provide actually works – Eugene May 05 '14 at 02:37
4

you only have to draw the bufferedImage in negative width or negative height in drawImage method thats all

//flip horizontally
g.drawImage(bufferedImage , x,y,-width,height,null);

//flip vertically
g.drawImage(bufferedImage , x,y,width,-height,null);
Vi Matviichuk
  • 1,122
  • 15
  • 32
Jesse
  • 75
  • 3
  • 1
    easy and works, but you have to remeber to offset the x and y respectively. so it should be something like `g.drawImage(bufferedImage, x + width, y, -width, height, null);` `g.drawImage(bufferedImage, x, y + height, width, -height, null);` – Sbiera Bogdan Apr 13 '21 at 06:41
3

Here is the code to flip the image at any angle

public static GraphicsConfiguration getDefaultConfiguration() {
    GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
    GraphicsDevice gd = ge.getDefaultScreenDevice();
    return gd.getDefaultConfiguration();
}

public static BufferedImage rotate(BufferedImage image, double angle) {
    int w = image.getWidth(), h = image.getHeight();
    GraphicsConfiguration gc = getDefaultConfiguration();
    BufferedImage result = gc.createCompatibleImage(w, h);
    Graphics2D g = result.createGraphics();
    g.rotate(Math.toRadians(angle), w / 2, h / 2);
    g.drawRenderedImage(image, null);
    g.dispose();
    return result;
}
Braj
  • 46,415
  • 5
  • 60
  • 76
2

You could flip the image like this:

public void flip(BufferedImage image)
{
    for (int i=0;i<image.getWidth();i++)
        for (int j=0;j<image.getHeight()/2;j++)
        {
            int tmp = image.getRGB(i, j);
            image.setRGB(i, j, image.getRGB(i, image.getHeight()-j-1));
            image.setRGB(i, image.getHeight()-j-1, tmp);
        }
}
schmop
  • 1,440
  • 1
  • 12
  • 21
1

If you are using paintComponent() method of swing.

With

 graphic.drawImage(img,
                   dx1, dy1, dx2, dy2,
                   sx1, sy1, sx2, sy2,
                   null);

Just flip the sx1 with sx2

TADA! Its done.

enter image description here


                Source Image                     Destination panel

 sx1, sy1      
    +---------------+---------+        +-----------------------------+
    |               |         |        |                             |
    | region to     |         |        | dx1, dy1                    |
    |        draw   |         |        |    +----------+             |    
    |               |         |        |    |          |             |
    +---------------+         |        |    |          |             | 
    |           sx2, sy2      |        |    +----------+             |     
    |                         |        |            dx2, dy2         |
    |                         |        |                             |
    +-------------------------+        +-----------------------------+

This could be good reference for: drawImage() method

Community
  • 1
  • 1
SHA2NK
  • 189
  • 2
  • 12
0

Maybe you can use AffineTransform.

AffineTransform transform = new AffineTransform();
transform.rotate(radians, bufferedImage.getWidth()/2, bufferedImage.getHeight()/2);
AffineTransformOp op = new AffineTransformOp(transform, AffineTransformOp.TYPE_BILINEAR);
bufferedImage = op.filter(bufferedImage, null);
Hirak
  • 3,601
  • 1
  • 22
  • 33
  • will this essentially be equivalent to manually rearranging pixels in the byte array or will there be some loss of data during transformation? – Denis Tulskiy May 04 '14 at 15:14
  • You provide an example of how to rotate an image but not about how to flip an image.You can refer to http://stackoverflow.com/a/23458883/3378204 which I accept as the best answer. – Eugene May 05 '14 at 05:14