Screenshot.java

net.minecraft.client.Screenshot

信息

  • 全限定名:net.minecraft.client.Screenshot
  • 类型:public class
  • 包:net.minecraft.client
  • 源码路径:src/main/java/net/minecraft/client/Screenshot.java
  • 起始行号:L23
  • 职责:

    TODO

字段/常量

  • LOGGER

    • 类型: Logger
    • 修饰符: private static final
    • 源码定位: L24
    • 说明:

      TODO

  • SCREENSHOT_DIR

    • 类型: String
    • 修饰符: public static final
    • 源码定位: L25
    • 说明:

      TODO

内部类/嵌套类型

构造器

方法

下面的方法块按源码顺序生成。

public static void grab(File workDir, RenderTarget target, Consumer<Component> callback) @ L27

  • 方法名:grab
  • 源码定位:L27
  • 返回类型:void
  • 修饰符:public static

参数:

  • workDir: File
  • target: RenderTarget
  • callback: Consumer

说明:

TODO

public static void grab(File workDir, String forceName, RenderTarget target, int downscaleFactor, Consumer<Component> callback) @ L31

  • 方法名:grab
  • 源码定位:L31
  • 返回类型:void
  • 修饰符:public static

参数:

  • workDir: File
  • forceName: String
  • target: RenderTarget
  • downscaleFactor: int
  • callback: Consumer

说明:

TODO

public static void takeScreenshot(RenderTarget target, Consumer<NativeImage> callback) @ L82

  • 方法名:takeScreenshot
  • 源码定位:L82
  • 返回类型:void
  • 修饰符:public static

参数:

  • target: RenderTarget
  • callback: Consumer

说明:

TODO

public static void takeScreenshot(RenderTarget target, int downscaleFactor, Consumer<NativeImage> callback) @ L86

  • 方法名:takeScreenshot
  • 源码定位:L86
  • 返回类型:void
  • 修饰符:public static

参数:

  • target: RenderTarget
  • downscaleFactor: int
  • callback: Consumer

说明:

TODO

private static File getFile(File picDir) @ L148

  • 方法名:getFile
  • 源码定位:L148
  • 返回类型:File
  • 修饰符:private static

参数:

  • picDir: File

说明:

TODO

代码

@OnlyIn(Dist.CLIENT)
public class Screenshot {
    private static final Logger LOGGER = LogUtils.getLogger();
    public static final String SCREENSHOT_DIR = "screenshots";
 
    public static void grab(File workDir, RenderTarget target, Consumer<Component> callback) {
        grab(workDir, null, target, 1, callback);
    }
 
    public static void grab(File workDir, @Nullable String forceName, RenderTarget target, int downscaleFactor, Consumer<Component> callback) {
        takeScreenshot(
            target,
            downscaleFactor,
            image -> {
                File picDir = new File(workDir, "screenshots");
                picDir.mkdir();
                File file;
                if (forceName == null) {
                    file = getFile(picDir);
                } else {
                    file = new File(picDir, forceName);
                }
 
                Util.ioPool()
                    .execute(
                        () -> {
                            try {
                                NativeImage twrVar0$ = image;
 
                                try {
                                    image.writeToFile(file);
                                    Component component = Component.literal(file.getName())
                                        .withStyle(ChatFormatting.UNDERLINE)
                                        .withStyle(s -> s.withClickEvent(new ClickEvent.OpenFile(file.getAbsoluteFile())));
                                    callback.accept(Component.translatable("screenshot.success", component));
                                } catch (Throwable var7) {
                                    if (image != null) {
                                        try {
                                            twrVar0$.close();
                                        } catch (Throwable var6) {
                                            var7.addSuppressed(var6);
                                        }
                                    }
 
                                    throw var7;
                                }
 
                                if (image != null) {
                                    image.close();
                                }
                            } catch (Exception var8) {
                                LOGGER.warn("Couldn't save screenshot", (Throwable)var8);
                                callback.accept(Component.translatable("screenshot.failure", var8.getMessage()));
                            }
                        }
                    );
            }
        );
    }
 
    public static void takeScreenshot(RenderTarget target, Consumer<NativeImage> callback) {
        takeScreenshot(target, 1, callback);
    }
 
    public static void takeScreenshot(RenderTarget target, int downscaleFactor, Consumer<NativeImage> callback) {
        int width = target.width;
        int height = target.height;
        GpuTexture sourceTexture = target.getColorTexture();
        if (sourceTexture == null) {
            throw new IllegalStateException("Tried to capture screenshot of an incomplete framebuffer");
        } else if (width % downscaleFactor == 0 && height % downscaleFactor == 0) {
            GpuBuffer buffer = RenderSystem.getDevice()
                .createBuffer(() -> "Screenshot buffer", 9, (long)width * height * sourceTexture.getFormat().pixelSize());
            CommandEncoder commandEncoder = RenderSystem.getDevice().createCommandEncoder();
            RenderSystem.getDevice()
                .createCommandEncoder()
                .copyTextureToBuffer(
                    sourceTexture,
                    buffer,
                    0L,
                    () -> {
                        try (GpuBuffer.MappedView read = commandEncoder.mapBuffer(buffer, true, false)) {
                            int outputHeight = height / downscaleFactor;
                            int outputWidth = width / downscaleFactor;
                            NativeImage image = new NativeImage(outputWidth, outputHeight, false);
 
                            for (int y = 0; y < outputHeight; y++) {
                                for (int x = 0; x < outputWidth; x++) {
                                    if (downscaleFactor == 1) {
                                        int argb = read.data().getInt((x + y * width) * sourceTexture.getFormat().pixelSize());
                                        image.setPixelABGR(x, height - y - 1, argb | 0xFF000000);
                                    } else {
                                        int red = 0;
                                        int green = 0;
                                        int blue = 0;
 
                                        for (int i = 0; i < downscaleFactor; i++) {
                                            for (int j = 0; j < downscaleFactor; j++) {
                                                int argb = read.data()
                                                    .getInt(
                                                        (x * downscaleFactor + i + (y * downscaleFactor + j) * width) * sourceTexture.getFormat().pixelSize()
                                                    );
                                                red += ARGB.red(argb);
                                                green += ARGB.green(argb);
                                                blue += ARGB.blue(argb);
                                            }
                                        }
 
                                        int sampleCount = downscaleFactor * downscaleFactor;
                                        image.setPixelABGR(x, outputHeight - y - 1, ARGB.color(255, red / sampleCount, green / sampleCount, blue / sampleCount));
                                    }
                                }
                            }
 
                            callback.accept(image);
                        }
 
                        buffer.close();
                    },
                    0
                );
        } else {
            throw new IllegalArgumentException("Image size is not divisible by downscale factor");
        }
    }
 
    private static File getFile(File picDir) {
        String name = Util.getFilenameFormattedDateTime();
        int count = 1;
 
        while (true) {
            File file = new File(picDir, name + (count == 1 ? "" : "_" + count) + ".png");
            if (!file.exists()) {
                return file;
            }
 
            count++;
        }
    }
}

引用的其他类

  • RenderTarget

    • 引用位置: 参数
  • NativeImage

    • 引用位置: 参数/构造调用
    • 关联成员: NativeImage()
  • RenderSystem

    • 引用位置: 方法调用
    • 关联成员: RenderSystem.getDevice()
  • ClickEvent

    • 引用位置: 方法调用/构造调用
    • 关联成员: ClickEvent.OpenFile(), OpenFile()
  • Component

    • 引用位置: 参数/方法调用
    • 关联成员: Component.literal(), Component.translatable()
  • ARGB

    • 引用位置: 方法调用
    • 关联成员: ARGB.blue(), ARGB.color(), ARGB.green(), ARGB.red()
  • Util

    • 引用位置: 方法调用
    • 关联成员: Util.getFilenameFormattedDateTime(), Util.ioPool()
  • EventLogDirectory

    • 引用位置: 参数/构造调用/返回值
    • 关联成员: File()