java - 为什么更高分辨率的 BufferedImage 会被包装并压缩在 Canvas 中?

标签 java swing jpanel resolution java-canvas

我有一个 JFrame GUI,它正在从 LAN 连接的摄像机实时捕获原始视频流。我为 BufferedImage (img1) 中的每个坐标设置 RBG 值(相机流式传输像素值,但就像白色和黑色一样),并在标准 Java 扩展 Canvas (MyCanvas canvas1) 上绘制图像。

用于在线程环境中绘图的代码片段,除了分辨率 1280x960 之外,工作正常。

while (true) {
                synchronized (this) {
                    if (shouldrun == false) {
                        System.out.println("Quiting Thread.....\n");
                        break;
                    }
                }
                if (in.read(ch) < 0) {
                    break;
                }
                /* Mono */ 
                pixelvalue = 0x00000000 | (ch[0] << 16)
                        | (ch[0] << 8) | (ch[0]);
                img1.setRGB(x, y, pixelvalue);
                x++;
                //resWidth = 1280
                if (x >= resWidth) {
                    x = 0;
                    y++;
                }
                framedata[pixelcount] = (byte) ch[0];
                pixelcount++;
                //resHeight = 960
                if (pixelcount >= resWidth * resHeight) {
                    System.out.println("pixelcount = " + pixelcount);
                    if (record == true) {
                        System.out.println("Recording Frame...");

                        if (fo != null) {
                            fo.write(framedata);
                        }
                    }
                    synchronized (canvas1) {
                        canvas1.DrawImage(img1);
                        canvas1.repaint();
                    }
                    Thread.sleep(33);
                    pixelcount = 0;
                    x = 0;
                    y = 0;
                }

            }

canvas1 对象的 Canvas 类的代码片段:

class MyCanvas extends Canvas {
    int startAngle = 0;
    int extent = 45;
    boolean filled = false;
    Image disimg = null;

    public void DrawImage(Image img) {
        disimg = img;
    }

    public void paint(Graphics g) {
        g.setColor(Color.pink);
         g.drawImage(disimg, 0, 0, null);
    }

    public void redraw(boolean filled, int start, int extent) {
        this.filled = filled;
        this.startAngle = start;
        this.extent = extent;
        repaint();
    }

}

Java GUI 应用程序成功地从相机中绘制 640x480 (resWidth=640 & resHeight=480) 分辨率的图像,如下所示 640x480Image

我只是将 resWidth 变量设置为 640,将 resHeight 变量设置为 480,以实现坐标增量限制和 Canvas 尺寸。

但是,当对 1280x960 分辨率执行相同操作时,结果显示 2 个重复图像并垂直压缩/挤压: 1280x960Image

为什么会出现这种情况?我不能简单地改变代码中的宽度和高度变量吗?难道是Jpanel的布局?或者相机以该分辨率传输像素值的方式?

最佳答案

当您说宽度和高度时,我假设您不是指来自相机的输入分辨率,而是您想要更改它在 Canvas 上的渲染方式。因为输入分辨率无法更改,并且取决于输入设备。我的意思是,您不能简单地将输入分辨率更改为 1920x1080,因为实际分辨率来自相机本身,但是您可以更改其渲染到显示器的方式(输出分辨率)。

因此,您希望从 640x480 输入分辨率的相机输入将其渲染为 1280x960 显示分辨率。缩放两次。 我会将您的代码恢复为 640x480 的原始宽度和高度,并查看您的 MyCanvas 类扩展以渲染到屏幕。

原代码

public void paint(Graphics g) {
    g.setColor(Color.pink);
    g.drawImage(disimg, 0, 0, null);
}

我会把它改为

public void paint(Graphics g) {
    g.setColor(Color.pink);
    g.drawImage(disimg, 0, 0, desiredWidth, desiredHeight, null);
}

其中desiredWidth和desiredHeight可以是(640x480)或(1280x960)或任何你想要的,因为这是你可以控制的东西,而不是输入分辨率。

您甚至可以绘制图像以填充 Canvas 的整个大小,例如

public void paint(Graphics g) {
    g.setColor(Color.pink);
    g.drawImage(disimg, 0, 0, this.getWidth(), this.getHeight(), null);
}

这是您要研究的 API。 https://docs.oracle.com/javase/7/docs/api/java/awt/Graphics.html#drawImage(java.awt.Image,%20int,%20int,%20int,%20int,%20java.awt.image.ImageObserver)

希望对您有所帮助,祝您编码愉快!

关于java - 为什么更高分辨率的 BufferedImage 会被包装并压缩在 Canvas 中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44992084/

相关文章:

java - Java中RS232口通信

java - 如何获取终端结果并设置 JTextArea 来读取终端?

java - 将 Swing JDialog 设置为非模式

java - 将 JPanel 绘制到 BufferedImage 或打印它而不先将其渲染到屏幕

java - 将 ArrayList 从对象更改为更具体的类型

java - 在 TextView 中显示带有 img html 的图像

java - CDI @ApplicationScoped

java - 使用 SimpleTable 数据填充 JCombobox

Java 6 : How to set up UndoManager to work with a canvas?

java - Java 中的 JPanel 问题