JavaFxのImageViewとCanvasに描画させる例です。
実験で使ったカメラサイズ(176,144)の縦横をそれぞれ4倍にしたイメージビューに表示させる。
またこのイメージは左右を反転したイメージを
生成して使っています。
(createMirrorImageメソッド定義して行う)
なお、オリジナルのサイズのCanvasに、
取得したBufferedImageで描画しています。
またラベルを用意し、4倍にしたイメージビュー上のマウス移動イベントで、
その位置の座標とその画素の色を表示させます。
以上の仕様を実現するソースの例を示します。
import java.awt.Dimension;
import java.awt.image.BufferedImage;
import java.io.File;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;
import javax.imageio.ImageIO;
import com.github.sarxos.webcam.Webcam;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.concurrent.Task;
import javafx.embed.swing.SwingFXUtils;
import javafx.scene.Scene;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.control.Label;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.image.WritableImage;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.Pane;
import javafx.stage.Stage;
class MyWebcaomPane extends Pane {
CameraFx app;//作品全体参照用
ImageView imageViewWebcam = new ImageView();
Webcam webCam = null;//カメラオブジェクト
BufferedImage img;//カメラから取得したイメージ
BufferedImage imgRev;//上記の左右反転イメージ
Dimension cameraSize;//上記の左右反転イメージ描画用のJavaFxイメージビュー
ObjectProperty<Image> imageProperty = new SimpleObjectProperty<Image>();//cameraViewカメラアクセス用
private boolean stopCamera = false;
MyWebcaomPane(){
this.getChildren().addAll(imageViewWebcam);
initCamera();
}
//カメラの初期化
void initCamera(){
//カメラ名列挙
List <Webcam> webcomList = Webcam.getWebcams();
for (Webcam webcam : webcomList) {
System.out.println(webcam.getName());
}
webCam = webcomList.get(0);
webCam.open();
this.cameraSize = webCam.getViewSize();
double height = ((int)cameraSize.getHeight())<<2;//4倍
double width = ((int)cameraSize.getWidth())<<2;
imageViewWebcam.setFitHeight(height);
imageViewWebcam.setFitWidth(width);
System.out.printf("サイズカメラ:(%d,%d)\n", cameraSize.width, cameraSize.height);
startWebCamStream();
imageViewWebcam.setOnMouseMoved(e->{
int x = (int) e.getX();
int y = (int) e.getY();
int color = imgRev.getRGB(x>>2, y>>2);
String s = String.format("(%3d,%3d)色#%07X", x,y,color&0x0FFFFFF);
app.label.setText(s);
});
}
protected void startWebCamStream() {
stopCamera = false;
Task<Void> task = new Task<Void>() {
@Override
protected Void call() throws Exception {
final AtomicReference<WritableImage> ref = new AtomicReference<>();
while (!stopCamera) {//カメラを撮る繰り返し
try {
img = webCam.getImage();//撮ったイメージを得る
if (img != null) {
imgRev = createMirrorImage(img);//イメージの左右逆転
ImageIO.write(imgRev, "JPG", new File("testfx.jpg"));//ファイルに残す
ref.set(SwingFXUtils.toFXImage(imgRev, ref.get()));
img.flush();
Platform.runLater(new Runnable() {
@Override
public void run() {
imageProperty.set(ref.get());//イメージビューへセット
GraphicsContext gc =app.canvas.getGraphicsContext2D();
gc.drawImage(SwingFXUtils.toFXImage(img,null), 0, 0);
}
});
}
} catch (Exception e) {
e.printStackTrace();
}
}
return null;
}
};
Thread th = new Thread(task);
th.setDaemon(true);
th.start();//スレッド実行(上記callを実行)
imageViewWebcam.imageProperty().bind(imageProperty);//imageProperty変更をイメージビュー反映する設定
}
// 鏡に移ったイメージを生成して返す。
public static BufferedImage createMirrorImage(BufferedImage img){
int width = img.getWidth();
int height = img.getHeight();
int size = width * height;
int []buf = new int[ size ];
img.getRGB(0, 0, width, height, buf, 0, width);//イメージを配列に変換
//bufのイメージ配列で、左右を変換する。
int x1, x2, temp;
for(int y = 0; y < size; y+=width){
x1 = 0;
x2 = width -1;
while(x1 < x2){// 交換の繰り返し
temp = buf[y+x1];
buf[y+x1++] = buf[y+x2];
buf[y+x2--] = temp;
}
}
BufferedImage img2= new BufferedImage(width, height, BufferedImage.TYPE_4BYTE_ABGR);
img2.setRGB(0, 0, width, height, buf, 0, width);//配列をイメージに書き込む
return img2;
}
}
public class CameraFx extends Application {
Stage primaryStage;
private BorderPane root = new BorderPane();
private MyWebcaomPane webCamPane = new MyWebcaomPane();
Label label = new Label("テスト");
Canvas canvas=new Canvas(176,144);
@Override
public void start(Stage primaryStage) throws Exception {
this.primaryStage = primaryStage;
root.setCenter(webCamPane);
root.setTop(label);
root.setBottom(canvas);
webCamPane.app=this;
label.setStyle("-fx-font-size: 20pt; -fx-color: black;");
primaryStage.setScene(new Scene(root));
Dimension size = webCamPane.webCam.getViewSize();
primaryStage.setWidth( webCamPane.cameraSize.width << 2 );
primaryStage.setHeight(webCamPane.cameraSize.height<< 2 );
primaryStage.centerOnScreen();
primaryStage.show();
}
public static void main(String... args) throws Exception {
Application.launch(args);
}
}