Why does the higher resolution BufferedImage get wrapped and compressed within Canvas?

206 views Asked by At

I have a JFrame GUI that is capturing raw video stream live from a LAN connected camera. I'm setting the RBG value (camera streams the pixel values, but just as white and black colors) for each coordinate in the BufferedImage (img1) and drawing the image on a standard Java extended Canvas (MyCanvas canvas1).

Code snippet for drawing in threaded environment which works fine except for the resolution 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;
                }

            }

Code snippet of Canvas class for canvas1 object:

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();
    }

}

The Java GUI app was successfully able to draw the image in 640x480 (resWidth=640 & resHeight=480) resolution image from the camera as shown below 640x480Image

I'm simply setting the resWidth variable to 640 and resHeight variable to 480 for coordinate increment limits and the canvas dimension.

However when doing the same for 1280x960 resolution the result shows 2 duplicate images and compressed/squashed vertically: 1280x960Image

Why would this occur? Can I not simply vary the width and height variables in the code? Could it be the Jpanel layout? Or the way the camera streams the pixel values in that resolution?

1

There are 1 answers

1
Itherael On

When you say width and height, I assume you are not referring to the input resolution that comes from the camera but you are wanting to change how it is rendered on your canvas. Because the input resolution cannot be change and will depend on the input device. I mean, you just can't simply change the input resolution to 1920x1080 for example since the actual resolution comes from the camera itself, however you can change the way it is rendered to your display (output resolution).

So from 640x480 input resolution camera input, you want to render it to a 1280x960 display resolution. Scaling it twice. I would revert your code to the original width and height of 640x480 and I would look at your MyCanvas class extension for rendering to the screen.

The original code

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

I would change it to

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

where the desiredWidth and desiredHeight can be (640x480) or (1280x960) or anything you desire since this is something you can control, not the input resolution.

You can even draw the image to fill the entire size of the canvas something like

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

This is the API you would be looking into. https://docs.oracle.com/javase/7/docs/api/java/awt/Graphics.html#drawImage(java.awt.Image,%20int,%20int,%20int,%20int,%20java.awt.image.ImageObserver)

Hope it helps, Happy Coding!