Convert camera from 3:2 to 16:9

Hi,

I’m trying to convert an live camera image of 640x480 (3:2)to 640x360 (16:9) only to display it at a size of 1126x633 (still 16:9). Clearly it needs cropping, which is fine. But how? I have:

if (cam.available() ) {
  cam.read();
}
PImage notcropped = cam;
PImage cropped = notcropped.get(0,0,640,360);
image(cropped, 20,20, 1126,633)

but it turns out that cropped is just a black image. I don’t understand why. What would be the correct, efficient way to do this?

1 Like

Hi @illus,

This code works for me on Windows:

import processing.video.*;

Capture cam;

void setup() {
  size(1126, 633);

  cam = new Capture(this, "pipeline:autovideosrc");
  cam.start();
}

void draw() {
  background(255);
  
  if (cam.available() == true) {
    cam.read();
  }
  
  PImage cropped = cam.get(0, 0, 640, 360);
  image(cropped, 20, 20, width, height);
}

Can you try it? :innocent: (you might need to change the camera name to the one you are using if the autovideosrc option doesn’t recognize your camera)

1 Like

Hello,

Modified Capture reference:

import processing.video.*;

Capture cam;
PImage img0, img1;

void setup() {
  size(640, 480);

  String[] cameras = Capture.list();
  
  if (cameras.length == 0) {
    println("There are no cameras available for capture.");
    exit();
  } else {
    println("Available cameras:");
    for (int i = 0; i < cameras.length; i++) {
      println(cameras[i]);
    }
    
    // The camera can be initialized directly using an 
    // element from the array returned by list():
    cam = new Capture(this, cameras[0]);
    cam.start();     
  }      
}

void draw() {
  if (cam.available() == true) {
    cam.read();
  }
  image(cam, 0, 0);
  img1 = cam.get(0, 0, 640, 360);
  // The following does the same, and is faster when just drawing the image
  // without any additional resizing, transformations, or tint.
  image(img1, 0, 60); // Offset to see the crop on top of original
}

The above cropped and displayed. I did not resize it.

:)

1 Like

cam.get()… that works!! thanks

1 Like

i didn’t know cam.get() would work. but it does. Thanks!

1 Like

Some more references:

:)

I thought it would work, but in my case it doesn’t
the change I have to make is that in the size(), I need to add P2D (because I want to use a shader to do some chromakey) and that makes the provided solution return a black image again.
This doesn’t work:

import processing.video.*;

Capture cam;
PImage bgimage;
  
void setup() {
  size(1920,1080,P2D);

  cam = new Capture(this, 640,480);
  cam.start();
}

void draw() {
  background(255);
  
  if (cam.available() == true) {
    cam.read();
  }
  
  PImage cropped = cam.get(0, 0, 640, 360);
   image(cropped, 20, 20, 640,360);
}
1 Like

@josephh any solution to this ?

You are right, it doesn’t work for me neither… I even tried to use a separate PGraphics to draw the camera image without luck.

I’m still a beginner, so I have no clue of what to try next

Hello @illus ,

Try this with P2D:

import processing.video.*;

Capture cam;
PImage img;

void setup() {
  size(640, 480, P2D);

  img = createImage(640, 360, RGB);
  //img.format = 1;

  String[] cameras = Capture.list();
  
  if (cameras.length == 0) {
    println("There are no cameras available for capture.");
    exit();
  } else {
    println("Available cameras:");
    for (int i = 0; i < cameras.length; i++) {
      println(cameras[i]);
    }
    
    // The camera can be initialized directly using an 
    // element from the array returned by list():
    cam = new Capture(this, cameras[0]);
    cam.start();     
  }      
}

void draw() {
  if (cam.available() == true) {
    cam.read();
  }
  image(cam, 0, 0);
  img.copy(cam, 0, 0, cam.width, cam.height, 0, 0, 640, 360); 
  
  image(img, 0, 60);
}

Note… this was some very quick testing before work so there may be better options.

:)

1 Like

yeah, that works, somehow it feels strange to first draw the image, read it back and draw it again, but it works.

I can even use image(cam,1920,0) so it is completely off screen, and it will work, but when I comment that line out, the result is black. This doesn’t compute in my brain, but alas, I’m happy.

I found some related issues:

1 Like

here is some more weird behavior. Without any image(cam,0,0) call it fails, but with that call the copy made to img updates just fine, but the direct view of image(cam,0,0) updates about 1 fps (if you don’t include the frameRate() it will even be slower like 1 per minute.)
it makes programming more a trial and error thing, and hoping that it works on some other machine.

import processing.video.*;

Capture cam;
PImage img;

void setup() {
  size(1920,1080,P2D);
  frameRate(10);
  String[] cameras = Capture.list();
  if (cameras.length == 0) {
    println("There are no cameras available for capture.");
    exit();
  } else {
    println("Available cameras:");
    for (int i = 0; i < cameras.length; i++) {
      println(cameras[i]);
    }
    cam = new Capture(this, 640,480);
    cam.start(); 
  }
  img = createImage(640,480,RGB);
}

void draw () {
  background(128);
  if (cam.available()) {
    cam.read();
    //image(cam, 0,0);
     img.copy(cam,0,0,640,480,0,0,640,480);
     image(cam,0,0);
    //img.loadPixels();
    
  }
  //image(cam,0,0);
  image(img,640,0);
}