How to flip BufferedImage in java

北战南征 提交于 2019-11-29 06:37:31

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:

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

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

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

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

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.


                Source Image                     Destination panel

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

This could be good reference for: drawImage() method

Jesse

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);
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!