Tipos de Cámaras by XOne
XOne entre sus bondades, ha implementado un módulo de cámara, brindando excelentes potencialidades para esta función y para poder habilitarlas se puede hacer a través de varios alternativas que detallamos a continuación:
Modos para implementar cámara en las App XOne |
---|
Prop Type="IMG" + ui.startCamera |
Prop Type="IMG" + ui.startCamera con JSON |
Prop Type VD |
Prop Type PH |
Prop Type PH con atributo |
Prop Type="IMG" + ui.startCamera
En este caso se define un prop type IMG, mediante el cual se accede a la cámara del dispositivo y esta queda embebida en la propia ventana desde la que es invocada .
Ejemplo:
<frame name="frPpal1" width="100%" height="90%" align="top|center" scroll="true" tmargin="5%" > <prop name="FOTO1" title="Foto" width="74%" labelwidth="4" text-border="true" labelbox="false" locked="true" type="T" tmargin="20p" /> <prop type="B" name="MAP_BTNFOTO1" img="bt_camera.png" width="100p" height="100p" method="ExecuteNode(camera('FOTO1'))" newline="false" tmargin="10p" lmargin="15p" title=" " /> <prop type="B" name="MAP_BTNDELFOTO1" img="bt_Delete.png" width="100p" height="100p" method="ExecuteNode(delcamera('FOTO1'))" newline="false" tmargin="10p" title=" " /> <prop name="FOTO2" title="Foto 2" width="74%" labelwidth="6" text-border="true" locked="true" type="T" tmargin="20p" /> <prop type="B" name="MAP_BTNFOTO2" img="camera.png" width="64p" height="64p" method="ExecuteNode(camera('FOTO2'))" newline="false" tmargin="10p" title=" " /> <prop type="B" name="MAP_BTNDELFOTO2" img="deshacer.png" width="64p" height="64p" method="ExecuteNode(delcamera('FOTO2'))" newline="false" tmargin="10p" title=" " /> <prop name="FOTO3" title="Foto 3" width="74%" labelwidth="6" text-border="true" locked="true" type="T" tmargin="20p" /> <prop type="B" name="MAP_BTNFOTO3" img="camera.png" width="64p" height="64p" method="ExecuteNode(camera('FOTO3'))" newline="false" tmargin="10p" title=" " /> <prop type="B" name="MAP_BTNDELFOTO3" img="deshacer.png" width="64p" height="64p" method="ExecuteNode(delcamera('FOTO3'))" newline="false" tmargin="10p" title=" " /> <frame name="frPpal2" width="90%" height="50%" align="top|center" xscroll="true" tmargin="5%" > <prop name="MAP_FOTO1" type="IMG" tmargin="3%" readonly="true" locked="true" width="100%" height="100%" file-maxwidth="800" file-maxheight="600" xlmargin="58%"/> <prop name="MAP_FOTO2" type="IMG" tmargin="1%" readonly="true" locked="true" width="30%" height="20%" file-maxwidth="800" file-maxheight="600" newline="false" /> <prop name="MAP_FOTO3" type="IMG" tmargin="1%" readonly="true" locked="true" width="30%" height="20%" file-maxwidth="800" file-maxheight="600" newline="false" /> </frame> </frame> <onchange> <field name="FOTO1"> <action name="runscript"> <script language="javascript"> self.MAP_FOTO1 = self.FOTO1; ui.refresh("MAP_FOTO1"); </script> </action> </field> <field name="FOTO2"> <action name="runscript"> <script language="javascript"> self.MAP_FOTO2 = self.FOTO2; ui.refresh("MAP_FOTO2"); </script> </action> </field> <field name="FOTO3"> <action name="runscript"> <script language="javascript"> self.MAP_FOTO3 = self.FOTO3; ui.refresh("MAP_FOTO3"); </script> </action> </field> </onchange> <camera show-wait-dialog="false"> <action name="runscript"> <param name="CAMPO" /> <script language="javascript"> ui.startCamera(CAMPO,"photo"); </script> </action> </camera> <delcamera show-wait-dialog="false"> <action name="runscript"> <param name="CAMPO" /> <script language="javascript"> self[CAMPO] = ""; </script> </action> </delcamera> </group> </coll>
Prop Type="IMG" + ui.startCamera con JSON
En este caso se define un prop type IMG igual que el ejemplo anterior y lo que cambia es que la llamada a la cámara se hace a través del método ui y un JSON como parámetro.
Ejemplo:
<frame name="frPpal1" width="100%" height="90%" align="top|center" scroll="true" tmargin="5%"> <prop name="MAP_FOTOSELFIE_BT" width="15%" height="8%" tmargin="1%" lmargin="27%" newline="true" onclick="doStartCameraReservaIMG(e,self,'MAP_FOTOSELFIE','MAP_FOTOSELFIE');" img="bt_camera.png" type="B" visible="1" class="propBTInferior colorBTInferior" bgcolor="#00000000" /> <frame name="frmselfie" width="90%" height="50%" xlmargin="15%" align="top|center" tmargin="1%" framebox="true" > <prop name="MAP_FOTOSELFIE" type="IMG" width="100%" height="100%" keep-aspect-ratio="false" xclass="nada" /> </frame> </frame>
function doStartCameraReservaIMG(evento,obj,propbt,propfoto) { let sDeviceOS = appData.getGlobalMacro("##DEVICE_OS##"); let jsParams; let ventana; if (sDeviceOS == "android") { jsParams = { width : 800, height : 600, onSuccess : function(sNuevaFoto) { obj[propfoto] = sNuevaFoto; ventana = ui.getView(obj); if (ventana) { //ventana.refresh(propbt); ventana.refresh(); } }, onCancelled: function() { //Nada } }; } else { jsParams = { width : 800, height : 600, quality : 0.6, onSuccess : function(sNuevaFoto) { obj[propfoto] = sNuevaFoto; ventana = ui.getView(obj); if (ventana) { //ventana.refresh(propbt); ventana.refresh(); } }, onCancelled: function() { //Nada } }; } ui.startCamera(jsParams); }
Cámara con CallBacks
/* * Type (opcional), photo/video. Por defecto photo * Width (opcional) * Height (opcional) * UseInternalCamera (opcional), indica si usar la app de fotos del dispositivo * o la implementación interna de XOne. Por defecto false */ function startPhotoCameraWithCallbacks() { let jsParams = { type : "photo", width : 800, height : 600, useInternalCamera: false, onSuccess : function(sPhoto) { ui.showToast("Todo OK. Foto: " + sPhoto); }, onCancelled : function() { ui.showToast("Se ha cancelado la captura de foto."); } }; ui.startCamera(jsParams); }
Prop Type VD
Esta es la propia cámara XOne, se define a través de un Prop Type VD. Para este tipo de prop pueden definirse 3 tipos de cámaras al usarse el atributo camera-api=“V1|v2|camerax” .
<prop name="MAP_CAMERA" type="VD" visible="1" viewmode="camerapreview" width="90%" height="55%" tmargin="0" camera-api="v1" scandit-license="" />
<prop name="MAP_CAMERA" type="VD" visible="1" viewmode="camerapreview" width="90%" height="55%" tmargin="0" camera-api="v2" scandit-license="" />
<prop name="MAP_CAMERA" type="VD" visible="1" viewmode="camerapreview" width="90%" height="55%" tmargin="0" camera-api="camerax" scandit-license="" />
Las funciones que brinda este control Cámara se obtienen haciendo:
let control = getControl(“MAP_CAMERA”), donde “MAP_CAMERA” es la propiedad de la cámara.
Estas funciones son:
Funciones | Descripción |
---|---|
control.takePicture(params) | para hacer foto |
control.record | para grabar vídeo |
control.stopRecording | para detener la grabación |
control.setFlashMode(sFlashMode) | para decirle si el flash está activo, desactivado, automático, etc. |
control.setCamera(“front”) | para escoger entre la cámara trasera y la frontal. |
control.startPreview | para iniciar la visualización de la cámara en tiempo real. |
control.stopPreview | para tener la visualización de la cámara en tiempo real. |
control.isCameraOpened | para saber si la visualización está activada (devuelve true p false) |
control.setAutoFocus | para decir si quieres que se active el auto enfoque o no. |
control.isAutoFocus | true o false, para saber si está activado el auto enfoque. |
control.getSupportedAspectRatios | devuelve un arreglo con las relaciones de aspecto permitidas por la cámara. |
control.getSupportedVideoProfiles | devuelve un arreglo con los perfiles de vídeo permitidos por la cámara. |
control.getMaxZoom | devuelve el max Zoom permisible por la cámara. |
control.setZoom(nZoom), | pone el zoom según el parámetro. (Son números que van desde 1 hasta el mayor valor permitido por la cámara). |
control.setOnCodeScanned, | es para escanear (En este caso tiene un parámetro que es una función de callback, para lo que se quiera hacer con el código escaneado). |
Ejemplo:
<coll name="CustomCamera" title="" notab="true" editmask="0" sql="SELECT * FROM GEN_USUARIOS"> <group name="HEADER" id="10" class="groupfixed_header"> <frame name="frmtitulo" class="frmsuperior"> <prop name="SALIR" type="B" class="btvolversuper" /> <prop name="MENU" type="TL" class="tlsuper" title="CAMARA" /> <prop name="MAP_COLORACTIVO" type="T" visible="0" /> </frame> </group> <group name="FOOTER" id="0" class="groupfixed_footer"> <prop name="MAP_GROUP" type="N" visible="0" /> <prop name="MAP_TOTAL_PAGES" type="N" visible="0" /> <frame name="FLOAT_FOOTER_FRAME" class="frmsuperior"> <prop name="MAP_LAST" type="B" img="last.png" title="Anterior" onclick="javascript:prev(self,'ir');" methodx="ExecuteNode(anterior)" forecolor="#FFFFFF" width="45%" height="80%" labelwidth="1" imgsel="last-sel.png" disablevisible="MAP_GROUP=1" /> <prop name="MAP_LAST_EMPTY" type="B" bgcolor="#00000000" width="45%" height="80%" labelwidth="1" newline="false" disablevisible="MAP_GROUP>1" /> <prop name="MAP_NEXT" type="B" img="next.png" title="Siguiente " onclick="javascript:next(self,'ir');" methodx="ExecuteNode(siguiente)" forecolor="#FFFFFF" width="45%" height="80%" labelwidth="1" newline="false" lmargin="6%" imgsel="next-sel.png" disablevisible="MAP_GROUP=MAP_TOTAL_PAGES" /> </frame> </group> <group name="General" id="1"> <frame name="group1Frame" class="frmtodo" height="1040p" bgcolor="#FFFFFF" align="top|center"> <frame name="frmTop" tmargin="0" width="100%" height="28%" align="center|top" xbgcolor="#FF040E1A"> <prop name="MAP_TOGGLE_FLASH_MODE" title="Cambiar Flash" type="B" visible="1" onclick="javascript:doToggleFlashMode();" class="btnButton" align="center" height="80p" /> <prop name="MAP_TOGGLE_CAMERA" title="Cambiar Cámara" type="B" visible="1" onclick="javascript:doToggleCamera();" lmargin="5%" newline="false" class="btnButton" align="center" height="80p" /> <prop name="MAP_TOGGLE_AUTOFOCUS" title="Cambiar Auto Enfoque" type="B" visible="1" onclick="javascript:doToggleAutoFocus();" class="btnButton" align="center" height="80p" /> <prop name="MAP_CAMERA_QUALITY" type="T" visible="1" labelwidth="9" width="700p" height="50p" tmargin="30p" img-height="55p" img-width="60p" linkedto="MAP_CAMERA_QUALITY" linkedfield="DATA" mapcol-values="high,qvga,low,480p,720p,1080p,2160p" title="Calidad de vídeo" showinline="true" text-border="true" /> </frame> <prop name="MAP_CAMERA" type="VD" visible="1" width="80%" height="50%" viewmode="camerapreview" Xcode-type="ean13" /> <frame name="frmBottom" tmargin="0" width="100%" height="30%" align="center|top" xbgcolor="#FF040E1A"> <prop name="MAP_TAKE_PICTURE" title="Hacer Foto" type="B" visible="1" onclick="javascript:takePicture();" class="btnButton" align="center" height="80p"/> <prop name="MAP_START_RECORDING" title="Grabar Vídeo" type="B" visible="1" newline="false" lmargin="5%" onclick="javascript:record();" class="btnButton" align="center" disablevisible="MAP_RECORDING=1" height="80p" /> <prop name="MAP_STOP_RECORDING" title="Detener Vídeo" type="B" visible="1" newline="false" lmargin="5%" onclick="javascript:stopRecording();" class="btnButton" align="center" disablevisible="MAP_RECORDING=0" height="80p" /> <prop name="MAP_START_PREVIEW" title="Iniciar" type="B" visible="1" onclick="javascript:startPreview();" class="btnButton" align="center" disablevisible="MAP_RECORDING=1" height="80p" /> <prop name="MAP_STOP_PREVIEW" title="Detener" type="B" visible="1" newline="false" lmargin="5%" onclick="javascript:stopPreview();" class="btnButton" align="center" disablevisible="MAP_RECORDING=1" height="80p" /> </frame> </frame> <prop name="MAP_RECORDING" type="N" visible="0" /> </group>
function takePicture() { let control = getControl("MAP_CAMERA"); if (!control) { return; } var params = { filename : "test.jpg", saveToGallery: true, width : 360, height : 360, onFinished : function(sFileName) { if (!sFileName) { ui.showToast("Error de cámara"); } else { ui.showToast("Abriendo nueva foto..."); ui.openFile(sFileName); } } }; control.takePicture(params); } function record() { let control = getControl("MAP_CAMERA"); if (!control) { return; } var currentObj = self; let params = { quality : self.MAP_CAMERA_QUALITY, maxDuration : 10000, // Milisegundos //maxFileSize : 10485760, // Bytes withMicAudio: true, onFinished : function(sFileName) { self.MAP_RECORDING=0; ui.refresh("MAP_START_RECORDING,MAP_STOP_RECORDING,MAP_START_PREVIEW,MAP_STOP_PREVIEW"); if (!sFileName) { ui.showToast("Error de cámara"); } else { ui.showToast("Nuevo vídeo..."); ui.openFile(sFileName); } } }; control.record(params); self.MAP_RECORDING=1; ui.refresh("MAP_START_RECORDING,MAP_STOP_RECORDING,MAP_START_PREVIEW,MAP_STOP_PREVIEW"); } function stopRecording() { let control = getControl("MAP_CAMERA"); if (!control) { return; } control.stopRecording(); } function startPreview() { let control = getControl("MAP_CAMERA"); if (!control) { return; } control.startPreview(); } function stopPreview() { let control = getControl("MAP_CAMERA"); if (!control) { return; } control.stopPreview(); } function isOpened() { let control = getControl("MAP_CAMERA"); if (!control) { return; } let bOpened = control.isCameraOpened(); ui.showToast("Abierta: " + bOpened); } function isAutoFocus() { let control = getControl("MAP_CAMERA"); if (!control) { return; } let bAutoFocus = control.isAutoFocus(); ui.showToast("Autofoco: " + bAutoFocus); } function getSupportedAspectRatios() { let control = getControl("MAP_CAMERA"); if (!control) { return; } let allAspectRatios = control.getSupportedAspectRatios(); let sMessage = "Relaciones de aspecto soportadas: "; for (let i = 0;i < allAspectRatios.length;i++) { sMessage = sMessage + "\n" + allAspectRatios[i]; } ui.msgBox(sMessage, "Mensaje", 0); } function doSetOnCodeScanned() { let control = getControl("MAP_CAMERA"); if (!control) { return; } control.setOnCodeScanned(function(evento) { let nResult = ui.msgBox("Valor: " + evento.data + "\nTipo: " + evento.type, "¿Código OK?", 4); if (nResult == 6) { return true; } else { return false; } }); } /** * Modifica el comportamiento de flash de la cámara. * * Valores posibles: * 1) on: Siempre encendido al tomar una foto * 2) off: Siempre apagado al tomar una foto * 3) torch: Siempre encendido * 4) auto: Encendido o apagado al tomar una foto dependiendo de lo que diga el * sensor de luz * 5) red_eye: Encendido o apagado al tomar una foto dependiendo de lo que diga * el sensor de luz, en un modo especial que reduce los ojos rojos */ function doSetFlashMode(sFlashMode) { let control = getControl("MAP_CAMERA"); if (!control) { return; } control.setFlashMode(sFlashMode); } function doToggleFlashMode() { let control = getControl("MAP_CAMERA"); if (!control) { return; } let sFlashMode = control.getFlashMode(); if (sFlashMode == "on") { control.setFlashMode("off"); self.setFieldPropertyValue("MAP_TOGGLE_FLASH_MODE", "img", "flash-off.png"); } else if (sFlashMode == "off") { control.setFlashMode("auto"); self.setFieldPropertyValue("MAP_TOGGLE_FLASH_MODE", "img", "flash-auto.png"); } else if (sFlashMode == "auto") { control.setFlashMode("torch"); self.setFieldPropertyValue("MAP_TOGGLE_FLASH_MODE", "img", "flash-torch.png"); } else if (sFlashMode == "torch") { control.setFlashMode("on"); self.setFieldPropertyValue("MAP_TOGGLE_FLASH_MODE", "img", "flash-on.png"); } ui.refresh("MAP_TOGGLE_FLASH_MODE"); } function doToggleCamera() { let control = getControl("MAP_CAMERA"); if (!control) { return; } let sCamera = control.getCamera(); if (sCamera == "front") { control.setCamera("back"); } else if (sCamera == "back") { control.setCamera("front"); } } function doToggleAutoFocus() { let control = getControl("MAP_CAMERA"); if (!control) { return; } control.setAutoFocus(!control.isAutoFocus()); } function getControl(sPropName) { let window = ui.getView(self); if (!window) { return null; } let control = window[sPropName]; if (!control) { return null; } return control; }
Prop Type PH
En este caso se habilita un control cámara definiendo a través de un prop type PH, tiene como atributos las imágenes asociadas para lanzar la cámara. Se lanza por defecto la cámara del Sistema Operativo del dispositivo.
Ejemplo:
<frame name="group2Frame" width="100%" height="100%" xalign="center"> <prop name="MAP_LABEL4" type="TL" align="center" class="classtl" title="CONTROL HACER FOTO" /> <prop name="MAP_FOTO" type="PH" width="96%" height="35%" ximg-width="96p" ximg-height="90p" title="Foto" lmargin="2%" /> <prop name="MAP_LABEL5" type="TL" class="classtl" title="CONTROL VER FOTO" tmargin="6%"/> <prop name="MAP_FOTOVER" type="PH" locked="true" width="96%" height="35%" title="foto" lmargin="2%" /> </frame> </frame>
Prop Type PH con atributo
En este caso es similar al anterior, pero si se define el atributo use-internal-camera=“true” que permite lanzar la cámara interna del framework. Esta opción es recomendable para usar en dispositivos de bajas prestaciones donde el sistema operativo pudiera cerrar aplicaciones en segundo plano.
Ejemplo:
<frame name="group2Frame" width="100%" height="100%" xalign="center"> <prop name="MAP_LABEL4" type="TL" align="center" class="classtl" title="CONTROL HACER FOTO" /> <prop name="MAP_FOTO" type="PH" width="96%" height="55%" use-internal-camera="true" img-width="96p" img-height="90p" title="Foto" lmargin="2%" rotate-button="true" img- rotate="bt_rotate.png" /> <xprop name="MAP_LABEL5" type="TL" class="classtl" title="CONTROL VER FOTO" tmargin="6%" /> <xprop name="MAP_FOTOVER" type="PH" locked="true" width="96%" height="35%" title="foto" lmargin="2%" /> </frame> </frame>