瀏覽代碼

ScreenshotAppState to use old FB read-back
Also, set compression quality for JPG to 95% (same as on Android)

shadowislord 10 年之前
父節點
當前提交
30efc7ce86

+ 1 - 1
jme3-core/src/main/java/com/jme3/app/state/ScreenshotAppState.java

@@ -230,7 +230,7 @@ public class ScreenshotAppState extends AbstractAppState implements ActionListen
             int viewHeight = (int) ((curCamera.getViewPortTop() - curCamera.getViewPortBottom()) * curCamera.getHeight());
 
             renderer.setViewPort(0, 0, width, height);
-            renderer.readFrameBufferWithFormat(out, outBuf, Image.Format.BGRA8);
+            renderer.readFrameBuffer(out, outBuf);
             renderer.setViewPort(viewX, viewY, viewWidth, viewHeight);
 
             File file;

+ 46 - 3
jme3-desktop/src/main/java/com/jme3/system/JmeDesktopSystem.java

@@ -47,6 +47,10 @@ import com.jme3.texture.image.DefaultImageRaster;
 import com.jme3.texture.image.ImageRaster;
 import com.jme3.util.Screenshots;
 import java.awt.EventQueue;
+import java.awt.Graphics2D;
+import java.awt.RenderingHints;
+import java.awt.geom.AffineTransform;
+import java.awt.image.AffineTransformOp;
 import java.awt.image.BufferedImage;
 import java.io.IOException;
 import java.io.OutputStream;
@@ -55,7 +59,13 @@ import java.nio.ByteBuffer;
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.logging.Level;
+import javax.imageio.IIOImage;
 import javax.imageio.ImageIO;
+import javax.imageio.ImageWriteParam;
+import javax.imageio.ImageWriter;
+import javax.imageio.plugins.jpeg.JPEGImageWriteParam;
+import javax.imageio.stream.ImageOutputStream;
+import javax.imageio.stream.MemoryCacheImageOutputStream;
 import javax.swing.SwingUtilities;
 
 /**
@@ -69,11 +79,44 @@ public class JmeDesktopSystem extends JmeSystemDelegate {
         return new DesktopAssetManager(configFile);
     }
 
+    private static BufferedImage verticalFlip(BufferedImage original) {
+        AffineTransform tx = AffineTransform.getScaleInstance(1, -1);
+        tx.translate(0, -original.getHeight());
+        AffineTransformOp transformOp = new AffineTransformOp(tx, AffineTransformOp.TYPE_NEAREST_NEIGHBOR);
+        BufferedImage awtImage = new BufferedImage(original.getWidth(), original.getHeight(), BufferedImage.TYPE_INT_BGR);
+        Graphics2D g2d = awtImage.createGraphics();
+        g2d.setRenderingHint(RenderingHints.KEY_RENDERING,
+                             RenderingHints.VALUE_RENDER_SPEED);
+        g2d.drawImage(original, transformOp, 0, 0);
+        g2d.dispose();
+        return awtImage;
+    }
+    
     @Override
     public void writeImageFile(OutputStream outStream, String format, ByteBuffer imageData, int width, int height) throws IOException {
-        BufferedImage awtImage = new BufferedImage(width, height, BufferedImage.TYPE_4BYTE_ABGR);
-        Screenshots.convertScreenShot(imageData, awtImage);
-        ImageIO.write(awtImage, format, outStream);
+        BufferedImage awtImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_BGR);
+        Screenshots.convertScreenShot2(imageData.asIntBuffer(), awtImage);
+
+        ImageWriter writer = ImageIO.getImageWritersByFormatName(format).next();
+        ImageWriteParam writeParam = writer.getDefaultWriteParam();
+
+        if (format.equals("jpg")) {
+            JPEGImageWriteParam jpegParam = (JPEGImageWriteParam) writeParam;
+            jpegParam.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
+            jpegParam.setCompressionQuality(0.95f);
+        }
+
+        awtImage = verticalFlip(awtImage);
+        
+        ImageOutputStream imgOut = new MemoryCacheImageOutputStream(outStream);
+        writer.setOutput(imgOut);
+        IIOImage outputImage = new IIOImage(awtImage, null, null);
+        try {
+            writer.write(null, outputImage, writeParam);
+        } finally {
+            imgOut.close();
+            writer.dispose();
+        }
     }
 
     @Override