可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
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.
How can I flip the BufferedImage to the correct direction like this?
回答1:
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;
}
}
回答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);
}
}
回答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;
}
回答4:
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);
回答5:
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
回答6:
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);