如何在java中翻转BufferedImage

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/23457754/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 23:07:24  来源:igfitidea点击:

How to flip BufferedImage in java

javaswingawtrgbbufferedimage

提问by Eugene

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

我得到 RGB24 字节数组并想用 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

我怎样才能像这样将 BufferedImage 翻转到正确的方向? 在此处输入图片说明

采纳答案by Marco13

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

有3个选项:(编辑- >:至少有已经过3个选项,直到你编辑的问题< - )

  • 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

ImageFlipTest01.png

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

根据您发布的图像,我假设您想垂直翻转图像。这可以逐个像素地完成,或者(当它应该有效地完成时)使用AffineTransformOp或 直接使用转换的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;
    }
}

回答by Hirak

Maybe you can use AffineTransform.

也许你可以使用 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);

回答by schmop

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

回答by Braj

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

回答by Jesse

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

您只需要在 drawImage 方法中以负宽度或负高度绘制 bufferedImage

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

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

回答by SHA2NK

If you are using paintComponent() method of swing.

如果您使用的是paintComponent() 方法的swing。

With

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

Just flip the sx1with sx2

只需用sx2翻转sx1

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

这可能是很好的参考: drawImage() 方法