This commit is contained in:
yumoqing 2024-12-11 18:08:41 +08:00
parent 3adab2a60e
commit 4b46f2ff00
4 changed files with 83 additions and 17 deletions

View File

@ -519,12 +519,33 @@ bricks.App = class extends bricks.Layout {
this._Height = this.dom_element.offsetHeight; this._Height = this.dom_element.offsetHeight;
this.video_stream = null; this.video_stream = null;
this.audio_stream = null; this.audio_stream = null;
this.video_devices = null
this.vpos = null;
document.addEventListener('keydown', this.key_down_action.bind(this)); document.addEventListener('keydown', this.key_down_action.bind(this));
} }
async start_camera() { async getCameras() {
if (this.video_stream) return; try {
const devices = await navigator.mediaDevices.enumerateDevices();
this.video_devices = devices.filter(device => device.kind === 'videoinput');
} catch (error) {
console.error('获取摄像头数量出错:', error);
}
}
async start_camera(vpos) {
if (typeof(vpos) == 'undefined') vpos = 0;
if (this.video_devices === null){
await this.getCameras();
}
if (vpos == this.vpos) return;
this.vpos = vpos;
if (this.video_stream){
this.video_stream.getTracks().forEach(track => {
track.stop();
});
}
if (navigator.mediaDevices.getUserMedia) { if (navigator.mediaDevices.getUserMedia) {
this.video_stream = await navigator.mediaDevices.getUserMedia({ video: true }); var x = { deviceId: this.video_devices[vpos].deviceId };
this.video_stream = await navigator.mediaDevices.getUserMedia({ video: x });
} else { } else {
console.log("Webcam access is not supported in this browser."); console.log("Webcam access is not supported in this browser.");
} }

View File

@ -7,42 +7,73 @@ bricks.Camera = class extends bricks.Popup {
*/ */
constructor(opts){ constructor(opts){
opts.fps = opts.fps || 60; opts.fps = opts.fps || 60;
opts.auto_dismiss = false;
super(opts); super(opts);
this.stream = null; this.stream = null;
this.video = document.createElement('video'); this.video = document.createElement('video');
var filler = new bricks.Filler({}); var filler = new bricks.Filler({});
var hbox = new bricks.HBox({ var hbox = new bricks.HBox({
cheight:2 cheight:3
}); });
this.cur_camera_id = 0;
this.add_widget(filler); this.add_widget(filler);
this.add_widget(hbox); this.add_widget(hbox);
var shot_btn = new bricks.Icon({ var shot_btn = new bricks.Icon({
url:bricks_resource('imgs/camera.png'), url:bricks_resource('imgs/camera.png'),
margin: '10px',
tip:'Take a picture',
rate:2.5
});
var switch_btn = new bricks.Icon({
url:bricks_resource('imgs/switch-camera.png'),
tip:'switch camera',
margin: '10px',
rate:1.5 rate:1.5
}); });
var del_btn = new bricks.Icon({ var del_btn = new bricks.Icon({
url:bricks_resource('imgs/delete.png'), url:bricks_resource('imgs/delete.png'),
tip:'canel it',
margin: '10px',
rate:1.5 rate:1.5
}) })
del_btn.bind('click', this.dismiss.bind(this)); del_btn.bind('click', this.dismiss.bind(this));
shot_btn.bind('click', this.take_picture.bind(this)); shot_btn.bind('click', this.take_picture.bind(this));
switch_btn.bind('click', this.switch_camera.bind(this, switch_btn));
this.imgw = new bricks.Image({ this.imgw = new bricks.Image({
width:'100%' width:'100%'
}); });
hbox.add_widget(switch_btn);
hbox.add_widget(shot_btn); hbox.add_widget(shot_btn);
hbox.add_widget(new bricks.Filler({}));
hbox.add_widget(del_btn); hbox.add_widget(del_btn);
filler.add_widget(this.imgw); filler.add_widget(this.imgw);
this.task_period = 1 / this.fps; this.task_period = 1 / this.fps;
schedule_once(this.startCamera.bind(this), 0.3); schedule_once(this.startCamera.bind(this), 0.1);
} }
async startCamera() { async switch_camera(btn, event){
await bricks.app.start_camera(); if (bricks.app.video_devices.length < 2){
btn.disabled(true);
return;
}
var vpos = bricks.app.vpos;
vpos += 1;
if (vpos >= bricks.app.video_devices.length){
vpos = 0;
}
this.startCamera(vpos);
}
async startCamera(vpos) {
await bricks.app.start_camera(vpos);
this.stream = bricks.app.video_stream; this.stream = bricks.app.video_stream;
this.video.srcObject = this.stream; this.video.srcObject = this.stream;
this.video.play(); this.video.play();
this.show_cnt = 1;
this.task = schedule_once(this.show_picture.bind(this), this.task_period); this.task = schedule_once(this.show_picture.bind(this), this.task_period);
} }
show_picture(){ show_picture(){
if (this.task_period == 0){
return;
}
var canvas = document.createElement('canvas'); var canvas = document.createElement('canvas');
canvas.height = this.video.videoHeight; canvas.height = this.video.videoHeight;
canvas.width = this.video.videoWidth; canvas.width = this.video.videoWidth;
@ -50,15 +81,18 @@ bricks.Camera = class extends bricks.Popup {
context.drawImage(this.video, 0, 0); context.drawImage(this.video, 0, 0);
this.imgw.set_url(canvas.toDataURL('image/jpeg')); this.imgw.set_url(canvas.toDataURL('image/jpeg'));
this.task = schedule_once(this.show_picture.bind(this), this.task_period); this.task = schedule_once(this.show_picture.bind(this), this.task_period);
this.show_cnt += 1;
} }
take_picture(){ take_picture(event){
event.stopPropagation();
if (this.task){ if (this.task){
task.cancel(); task.cancel();
this.task = null;
} }
this.task_period = 0;
this.task = null; this.task = null;
var d = this.imgw.base64(); var d = this.imgw.base64();
this.dispatch('shot', d); this.dispatch('shot', d);
// Create a blob from the canvas data URL
} }
} }

View File

@ -46,7 +46,7 @@ bricks.Image = class extends bricks.JsWidget {
// 获取画布数据并转换为 base64 // 获取画布数据并转换为 base64
var dataURL = canvas.toDataURL('image/png'); // 可以根据需要修改图像格式 var dataURL = canvas.toDataURL('image/png'); // 可以根据需要修改图像格式
dataURL = this.removeBase64Header(dataURL); // dataURL = this.removeBase64Header(dataURL);
return dataURL; return dataURL;
} }
set_url(url){ set_url(url){

View File

@ -352,7 +352,8 @@ bricks.UiImage =class extends bricks.VBox {
this.uitype='image'; this.uitype='image';
this.camera_w = new bricks.Icon({ this.camera_w = new bricks.Icon({
url:bricks_resource('imgs/camera.png'), url:bricks_resource('imgs/camera.png'),
rate:1.5}); tip:'use cemera to take a picture',
rate:2});
this.add_widget(this.camera_w); this.add_widget(this.camera_w);
this.camera_w.bind('click', this.take_photo.bind(this)); this.camera_w.bind('click', this.take_photo.bind(this));
this.bind('drop', this.dropHandle.bind(this)); this.bind('drop', this.dropHandle.bind(this));
@ -365,21 +366,23 @@ bricks.UiImage =class extends bricks.VBox {
this.dom_element.appendChild(this.input); this.dom_element.appendChild(this.input);
this.imgw = null; this.imgw = null;
} }
take_photo(){ take_photo(event){
event.stopPropagation();
var camera = new bricks.Camera({ var camera = new bricks.Camera({
"archor":"cc", "archor":"cc",
"auto_open":true, "auto_open":true,
"height":"90%", "height":"90%",
"width":"90%" "width":"90%"
}); });
camera.bind('shot', this.accept_photo.bind(this)); camera.bind('shot', this.accept_photo.bind(this, camera));
} }
accept_photo(url){ accept_photo(camera, event){
camera.dismiss();
if (this.imgw){ if (this.imgw){
this.remove_widget(this.imgw); this.remove_widget(this.imgw);
} }
this.imgw = new bricks.Image({ this.imgw = new bricks.Image({
url:url, url:event.params,
width:'100%' width:'100%'
}); });
this.add_widget(this.imgw); this.add_widget(this.imgw);
@ -410,8 +413,16 @@ bricks.UiImage =class extends bricks.VBox {
}; };
reader.readAsDataURL(file); reader.readAsDataURL(file);
} }
set_formdata(formdata){ set_formdata(fd){
formdata.append(this.name, this.value); // fd.append(this.name, this.resultValue(), 'test.png');
fd.append(this.name, this.resultValue());
}
resultValue(){
if (this.imgw){
this.value = this.imgw.base64();
return this.value;
}
return null;
} }
getValue(){ getValue(){
var ret = {} var ret = {}