【发布时间】:2014-02-02 00:54:43
【问题描述】:
所以,我碰了壁。我正在尝试获取 JFrame 的内容或整个 JFrame 将其转换为或绘制到 BufferedImage 中,然后将该图像写入 jpeg 文件。我让写入文件位工作正常。问题是我找不到一种方法可以让我在没有一些奇怪问题的情况下获取 JFrame 的内容。
我尝试使用机器人,但这带来了很多问题,例如导致程序挂起和 alpha 层无法正常工作。
我发现似乎最有希望的方法并没有更好地工作。它不会导致我的程序挂起,但不幸的是,当我使用此方法获取 JFrame 的内容时,生成的图像与 JFrame 大小相同,但只包含一个灰色面板,顶部有一个 25 像素的黑色边框和一个其他所有侧面 3 像素。这对应于 JFrame 本身的边界大小。
我想知道这是否与 BufferStrategy 有关。或者也许我只得到 JFrame 的后面板,在这种情况下,我需要知道如何抓住前面或整个东西。但实际上我不知道该去哪里,而且我从搜索中得到的大部分结果都是关于将图像放入 JFrame 而不是将 JFrame 转换为图像。
我已经尽可能地减少了我写的文件,并将在此处发布。
现在可以了,但多次修改后仍有一些奇怪的怪癖
import java.awt.Color;
import java.awt.Container;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Insets;
import java.awt.Rectangle;
import java.awt.image.BufferStrategy;
import java.awt.image.BufferedImage;
import java.io.File;
import java.util.Scanner;
import javax.imageio.IIOImage;
import javax.imageio.ImageIO;
import javax.imageio.ImageWriteParam;
import javax.imageio.ImageWriter;
import javax.imageio.stream.FileImageOutputStream;
import javax.swing.JFrame;
import static javax.swing.JFrame.EXIT_ON_CLOSE;
public class Window extends JFrame {
private static final long serialVersionUID = 1L;
private BufferStrategy graphicBuffer;
int frame = 0;
public static void main(String[] cats) {
new Window("Testing", 600, 400);
}
public Window(String title, int sizeX, int sizeY) {
setTitle(title);
setSize(sizeX, sizeY);
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
this.setResizable(false);
this.setUndecorated(false);
this.setVisible(true);
System.out.print("New Input: ");
Scanner scanner = new Scanner(System.in);
scanner.nextLine();
String input = scanner.nextLine();
while (scanner.hasNext()) {
input = scanner.next();
if (input.equals("end")) {
scanner.close();
break;
} else {
System.out.println("Working " + input);
render();
System.out.print("New Input: ");
}
}
System.out.println("End of Loop");
}
public void render(boolean toImg)
{
if( toImg ){
renderToImage();
} else {
renderToScreen();
}
}
public void render() {
if (graphicBuffer == null) {
createBufferStrategy(3);
graphicBuffer = getBufferStrategy();
}
Graphics g = graphicBuffer.getDrawGraphics();
Graphics2D g2 = (Graphics2D) g;
Rectangle bounds = g2.getDeviceConfiguration().getBounds();
int h = (int) bounds.getHeight();
int w = (int) bounds.getWidth();
Insets insets = this.getInsets();
int t = insets.top;
int l = insets.right;
int r = insets.left;
int b = insets.bottom;
int areaW = w - (l + r);
int areaH = h - (t + b);
g2.setColor(new Color(100, 0, 0));
g2.fillRect(0, 0, w, h);
flicker(g2, l, t, areaW, areaH);
g2.dispose();
g.dispose();
graphicBuffer.show();
grabFrame();
}
public void renderToImage( )
{
frame++;
if (graphicBuffer == null) {
createBufferStrategy(3);
graphicBuffer = getBufferStrategy();
}
Rectangle bounds = this.getBounds();
int h = (int) bounds.getHeight();
int w = (int) bounds.getWidth();
BufferedImage image = new BufferedImage( this.getWidth(), this.getHeight(), BufferedImage.TYPE_INT_RGB );
Graphics g = image.getGraphics();
Graphics2D g2 = (Graphics2D) g;
Insets insets = this.getInsets();
int t = insets.top;
int l = insets.right;
int r = insets.left;
int b = insets.bottom;
int areaW = w - (l + r);
int areaH = h - (t + b);
g2.setColor(new Color(100, 0, 0));
g2.fillRect(0, 0, w, h);
flicker(g2, l, t, areaW, areaH);
g2.dispose();
g.dispose();
g = graphicBuffer.getDrawGraphics();
g2 = (Graphics2D) g;
g2.drawImage( image, 0, 0, null );
g2.dispose();
g.dispose();
graphicBuffer.show();
testPrintToJpeg( image, frame );
}
public void testPrintToJpeg(BufferedImage frame, int frNum) {
try {
String userHome = System.getProperty("user.home");
File outputFile = new File(userHome + "/Desktop/JavaOutput/EOL" + frNum + ".jpg");
if (outputFile.getParentFile().mkdirs()) {
System.out.println("[FrameToFile] Missing Folders Probably Added");
}
IIOImage outputImage = new IIOImage(frame, null, null);
ImageWriter writer = ImageIO.getImageWritersByFormatName("jpeg").next();
writer.setOutput(new FileImageOutputStream(outputFile));
ImageWriteParam writeParam = writer.getDefaultWriteParam();
writeParam.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
writeParam.setCompressionQuality(1.0f);
writer.write(null, outputImage, writeParam);
} catch (Exception e) {
e.printStackTrace();
System.out.println("Fail at Image Writer");
}
}
}
【问题讨论】:
-
如果我能弄清楚这个问题与什么有关,我会弄清楚这个问题的最佳标题是什么。但是现在我所知道的是,无论 JFrame 的内容如何,JFrame.paint(BufferedImage.getGraphics()) 都会导致灰色图像。以及无穷无尽的乐趣!我快速而肮脏的解决方法中的某些内容可能会导致无限循环。
标签: java jframe bufferedimage