首页 文章

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

提问于
浏览
0

我有一个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以获得坐标增量限制和画布尺寸 .

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

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

1 回答

  • 1

    当你说宽度和高度时,我假设你没有提到来自相机的输入分辨率,但你想要改变它在画布上的渲染方式 . 因为输入分辨率不能改变,并且取决于输入设备 . 我的意思是,你不能简单地将输入分辨率更改为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)或任何您想要的东西,因为这是您可以控制的,而不是输入分辨率 .

    您甚至可以绘制图像以填充画布的整个大小

    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)

    希望它有所帮助,快乐编码!

相关问题