2012-12-06 49 views
4

如何翻轉屏幕截圖圖片?我在其他地方找不到我的問題。
示例代碼:如何使用glReadPixels()Bufferedimage水平翻轉圖像並使用ImageIO輸出?

/* 
*@param fileLoc //Location of fileoutput destination 
*@param format //"png" 
*@param WIDTH //Display.width(); 
*@param HEIGHT //Display.height(); 
*/ 
private void getScreenImage(){ 
      int[] pixels = new int[WIDTH * HEIGHT]; 
      int bindex; 
      // allocate space for RBG pixels 
      ByteBuffer fb = ByteBuffer.allocateDirect(WIDTH * HEIGHT * 3);//.order(ByteOrder.nativeOrder()); 
      // grab a copy of the current frame contents as RGB 

      glReadPixels(0, 0, WIDTH, HEIGHT, GL_RGB, GL_UNSIGNED_BYTE, fb); 

      BufferedImage image = new BufferedImage(WIDTH, HEIGHT,BufferedImage.TYPE_INT_RGB); 
      // convert RGB data in ByteBuffer to integer array 
      for (int i=0; i < pixels.length; i++) { 
       bindex = i * 3; 
       pixels[i] = 
        ((fb.get(bindex) << 16)) + 
        ((fb.get(bindex+1) << 8)) + 
        ((fb.get(bindex+2) << 0)); 
      } 
      try { 
       //Create a BufferedImage with the RGB pixels then save as PNG 
       image.setRGB(0, 0, WIDTH, HEIGHT, pixels, 0 , WIDTH); 

       ImageIO.write(image, format , fileLoc); 
      } 
      catch (Exception e) { 
       System.out.println("ScreenShot() exception: " +e); 
      } 
     } 

基本上代碼工作用於捕獲屏幕,在爲「PNG」格式存儲。
但它輸出的圖像水平翻轉,因爲glReadPixels();,
從左下角讀到右上角。

那麼如何在水平翻轉圖像之前我ImageIO.write();

謝謝在前面, 玫瑰。

+0

我想它畫上一個新的圖像時使用'AffineTransform'翻轉。然後使用'ImageIO'保存新圖像。 –

回答

6

E.G.使用AffineTransform水平翻轉圖像。

flipping an image horizontally

import java.awt.*; 
import java.awt.geom.AffineTransform; 
import java.awt.image.BufferedImage; 
import javax.swing.*; 

public class Test001 { 

    public static BufferedImage getFlippedImage(BufferedImage bi) { 
     BufferedImage flipped = new BufferedImage(
       bi.getWidth(), 
       bi.getHeight(), 
       bi.getType()); 
     AffineTransform tran = AffineTransform.getTranslateInstance(bi.getWidth(), 0); 
     AffineTransform flip = AffineTransform.getScaleInstance(-1d, 1d); 
     tran.concatenate(flip); 

     Graphics2D g = flipped.createGraphics(); 
     g.setTransform(tran); 
     g.drawImage(bi, 0, 0, null); 
     g.dispose(); 

     return flipped; 
    } 

    Test001(BufferedImage bi) { 
     JPanel gui = new JPanel(new GridLayout(1,2,2,2)); 

     gui.add(new JLabel(new ImageIcon(bi))); 
     gui.add(new JLabel(new ImageIcon(getFlippedImage(bi)))); 

     JOptionPane.showMessageDialog(null, gui); 
    } 

    public static void main(String[] args) throws AWTException { 
     final Robot robot = new Robot(); 
     Runnable r = new Runnable() { 

      @Override 
      public void run() { 
       final BufferedImage bi = robot.createScreenCapture(
         new Rectangle(0, 360, 200, 100)); 
       new Test001(bi); 
      } 
     }; 
     SwingUtilities.invokeLater(r); 
    } 
} 
+0

希望看到一個使用'ImageIo.write()'但感謝 –

+1

請參閱[本示例]中的'drawImage()'方法的最後一部分(http://stackoverflow.com/a/13796268/418556 )。 –

0

值得一提的,它可能會更快簡單地讀出緩衝的像素在你希望的順序,而不是向後閱讀,並做了昂貴的轉換操作。此外,由於您確定BufferedImage是TYPE_INT_RGB,因此直接寫入其柵格應該是安全的。

ByteBuffer fb = BufferUtils.createByteBuffer(WIDTH * HEIGHT * 3); 
BufferedImage image = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB); 
glReadPixels(0, 0, WIDTH, HEIGHT, GL_RGB, GL_UNSIGNED_BYTE, fb); 
int[] pixels = ((DataBufferInt) image.getRaster().getDataBuffer()).getData(); 
for (int i = pixels.length - 1; i >= 0; i--) { 
    int x = i % WIDTH, y = i/WIDTH * WIDTH; 
    pixels[y + WIDTH - 1 - x] = (fb.get() & 0xff) << 16 | (fb.get() & 0xff) << 8 | fb.get() & 0xff; 
}