Java LibGDX截图奇怪的行为
我在LibGDX中遇到了一个相当奇怪的截屏行为。我重新制作了一个小程序来重现这个只渲染黑色背景和红色矩形的“bug”。这些图像是结果: 左图是window的屏幕剪辑工具的屏幕截图,这是运行该程序的样子。右边是我在下面发布的截图代码。为了澄清这一点,我希望程序的截图能够得到左边图像的结果,而不会让透明度变得很奇怪 这是我的渲染代码,不介意坐标。因为我可以看到矩形被完美地渲染,所以在渲染方法中出现错误对我来说毫无意义。但我还是要把它贴出来Java LibGDX截图奇怪的行为,java,libgdx,screenshot,Java,Libgdx,Screenshot,我在LibGDX中遇到了一个相当奇怪的截屏行为。我重新制作了一个小程序来重现这个只渲染黑色背景和红色矩形的“bug”。这些图像是结果: 左图是window的屏幕剪辑工具的屏幕截图,这是运行该程序的样子。右边是我在下面发布的截图代码。为了澄清这一点,我希望程序的截图能够得到左边图像的结果,而不会让透明度变得很奇怪 这是我的渲染代码,不介意坐标。因为我可以看到矩形被完美地渲染,所以在渲染方法中出现错误对我来说毫无意义。但我还是要把它贴出来 @Override public void render(
@Override
public void render() {
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
Gdx.gl.glActiveTexture(GL20.GL_TEXTURE0);
Gdx.gl.glEnable(GL20.GL_BLEND);
Gdx.gl.glBlendFunc(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA);
shape.begin(ShapeType.Filled);
shape.setColor(Color.BLACK);
shape.rect(0, 0, 300, 300);
shape.setColor(1f, 0f, 0f, 0.5f);
shape.rect(100, 100, 100, 100);
shape.end();
Gdx.gl.glDisable(GL20.GL_BLEND);
}
以下是截图代码:
public static void screenshot() {
Pixmap pixmap = getScreenshot(0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
PixmapIO.writePNG(new FileHandle(Gdx.files.getLocalStoragePath() + "screenshots/test.png"), pixmap);
pixmap.dispose();
}
private static Pixmap getScreenshot(int x, int y, int w, int h) {
final Pixmap pixmap = ScreenUtils.getFrameBufferPixmap(x, y, w, h);
// Flip the pixmap upside down
ByteBuffer pixels = pixmap.getPixels();
int numBytes = w * h * 4;
byte[] lines = new byte[numBytes];
int numBytesPerLine = w * 4;
for(int i = 0; i < h; i++) {
pixels.position((h - i - 1) * numBytesPerLine);
pixels.get(lines, i * numBytesPerLine, numBytesPerLine);
}
pixels.clear();
pixels.put(lines);
return pixmap;
}
publicstaticvoid屏幕截图(){
Pixmap Pixmap=getScreenshot(0,0,Gdx.graphics.getWidth(),Gdx.graphics.getHeight());
writePNG(新文件句柄(Gdx.files.getLocalStoragePath()+“screenshots/test.png”)、pixmap;
dispose();
}
私有静态Pixmap getScreenshot(整数x、整数y、整数w、整数h){
final Pixmap Pixmap=ScreenUtils.getFrameBufferPixmap(x,y,w,h);
//将像素贴图翻转过来
ByteBuffer pixels=pixmap.getPixels();
int numBytes=w*h*4;
字节[]行=新字节[numBytes];
int numBytesPerLine=w*4;
对于(int i=0;i
我去研究了一下,我只发现了这个,这是完全相同的问题。不过,它的信息稍少,也没有答案。我希望你们中有人能回答这个谜团。我的问题在2017年2月23日得到了回答,但由于他对将自己的解决方案作为答案发表不感兴趣,我这样做是为了解决这个问题。非常感谢他。我所做的是将getPixels()
返回的ByteBuffer
中的每四个元素(alpha值)设置为(字节)255
(不透明)。这是我的结果:
private static Pixmap getScreenshot(int x, int y, int width, int height) {
final Pixmap pixmap = ScreenUtils.getFrameBufferPixmap(x, y, width, height);
ByteBuffer pixels = pixmap.getPixels();
for(int i = 4; i < pixels.limit(); i += 4) {
pixels.put(i - 1, (byte) 255);
}
int numBytes = width * height * 4;
byte[] lines = new byte[numBytes];
int numBytesPerLine = width * 4;
for(int i = 0; i < height; i++) {
pixels.position((height - i - 1) * numBytesPerLine);
pixels.get(lines, i * numBytesPerLine, numBytesPerLine);
}
pixels.clear();
pixels.put(lines);
pixels.clear();
return pixmap;
}
private static Pixmap getScreenshot(int x,int y,int width,int height){
final Pixmap Pixmap=ScreenUtils.getFrameBufferPixmap(x,y,width,height);
ByteBuffer pixels=pixmap.getPixels();
对于(int i=4;i
这不是一个bug。代码中的屏幕截图包括当时在后台缓冲区中的任何alpha,运行时在屏幕上不可见,因为您有一个不透明的窗口。使用预乘alpha,绘制到帧缓冲区,然后将帧缓冲区绘制到具有混合的屏幕,或者在保存前手动替换pixmap中每个像素的alpha。不知道您要做什么,但这可能有效。当您准备拍摄屏幕截图时,首先将混合函数更改为GL_ONE,GL_ONE。然后在整个屏幕上画一个黑色不透明的矩形。我认为这应该确保alpha在任何地方都是1,而不会影响颜色(因为黑色的RGB为0,将其添加到场景中不会改变RGB,但不透明颜色意味着将alpha添加到所有内容中)。然后调用您的屏幕截图方法来拍摄图片。如果您想在拍摄屏幕截图后替换Pixmap上的alpha everywhere,可以调用getPixels()
,然后将ByteBuffer中的每四个字节设置为(byte)255。但实际上,我认为上述方法会更快。