ICEfaces
  1. ICEfaces
  2. ICE-10447

mobi:camera - add HTML5 getUserMedia Support

    Details

    • Type: Improvement Improvement
    • Status: Closed
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: None
    • Fix Version/s: EE-4.0.0.GA
    • Component/s: MOBI-Components
    • Labels:
      None
    • Environment:
      ICEmobile EE 1.3.1
    • Assignee Priority:
      P2
    • Affects:
      Compatibility/Configuration

      Description

      Enhancement of the ICEmobile Camera component with HTML5 getUserMedia support

          The Camera component will dynamically render JavaScript code for an HTML5 fallback mode when BridgeIt Native utility app is not available or not present
          The HTML5 fallback mode will do client-side detection of the getUserMedia API
              If the API is not present, the component will render an input file element as before
              If the API is present, the component will render a button to trigger the getUserMedia API and a simulated camera capture popup
          Simulated Camera Capture popup
              Will show the user the video capture stream from within the web application
              Will provide a capture button to take a photo
              Will provide a thumbnail of the captured image using an HTML5 canvas element
              Will allow the user to select the current image, or take another photo
              If possible, the image data may be stored in local storage until the form is posted
              The selected image will be serialized into the form so that it can be uploaded on the next form post
          The server-side mobi:camera component API will remain unchanged, if possible.

        Activity

        Ken Fyten created issue -
        Ken Fyten made changes -
        Field Original Value New Value
        Project ICEmobile [ 10060 ] ICEfaces [ 10021 ]
        Key MOBI-1122 ICE-10447
        Issue Type New Feature [ 2 ] Improvement [ 4 ]
        Affects Compatibility/Configuration [ 10002 ]
        Assignee Priority P2 [ 10011 ]
        Fix Version/s EE-4.0.0.GA [ 11171 ]
        Fix Version/s EE 1.3.1.GA_P02 [ 11970 ]
        Component/s MOBI-Components [ 10270 ]
        Component/s Faces [ 10062 ]
        Hide
        Philip Breau added a comment - - edited

        IM 1.3.1 camera rendering logic (without Shim support):

        Server

        • if BridgeIt app registered
          • render button with onclick script for BridgeIt native camera
        • else
          • render button with onclick script for dynamic getUserMedia detection (ice.mobi.fallbackCamera())

        Client button onclick handler

        • if getUserMedia supported
          • create popup with video element
          • fire getUserMedia()
          • direct video stream to video element
          • show 'take picture' button
        • else
          • render a file upload element with HTML5 accept and capture attributes,
            • eg. accept='images/*;capture=camera', capture='true'

        Client getUserMedia image capture handler

        • create canvas element
        • create img element
        • canvas.getContext('2d').drawImage(video)
        • draw img element with base64 data url
        • show 'keep' and 'redo' buttons

        Client image capture from canvas element

        • create hidden input element
        • set hidden input element value with img element data url data

        Current IF 4 Camera rendering logic:

        Server

        • render button with bridgeit.camera() handler

        BridgeIt camera onclick handler

        • call native BridgeIt utility app
        • if native call fails, call bridgeit.launchFailed() callback hook

        Proposed IF 4 Camera rendering logic:

        Server

        • render button with onclick ice.mobi.cameraBtnOnClick handler

        Client cameraBtnOnClick handler

        • call bridgeit.camera() with custom cameraLaunchFailed callback

        cameraLaunchFailed callback

        • if getUserMedia supported
          • create popup with video element
          • fire getUserMedia()
          • direct video stream to video element
          • show 'take picture' button
        • else
          • render a file upload element with HTML5 accept and capture attributes,
            • eg. accept='images/*;capture=camera', capture='true'
        Show
        Philip Breau added a comment - - edited IM 1.3.1 camera rendering logic (without Shim support): Server if BridgeIt app registered render button with onclick script for BridgeIt native camera else render button with onclick script for dynamic getUserMedia detection (ice.mobi.fallbackCamera()) Client button onclick handler if getUserMedia supported create popup with video element fire getUserMedia() direct video stream to video element show 'take picture' button else render a file upload element with HTML5 accept and capture attributes, eg. accept='images/*;capture=camera', capture='true' Client getUserMedia image capture handler create canvas element create img element canvas.getContext('2d').drawImage(video) draw img element with base64 data url show 'keep' and 'redo' buttons Client image capture from canvas element create hidden input element set hidden input element value with img element data url data Current IF 4 Camera rendering logic: Server render button with bridgeit.camera() handler BridgeIt camera onclick handler call native BridgeIt utility app if native call fails, call bridgeit.launchFailed() callback hook Proposed IF 4 Camera rendering logic: Server render button with onclick ice.mobi.cameraBtnOnClick handler Client cameraBtnOnClick handler call bridgeit.camera() with custom cameraLaunchFailed callback cameraLaunchFailed callback if getUserMedia supported create popup with video element fire getUserMedia() direct video stream to video element show 'take picture' button else render a file upload element with HTML5 accept and capture attributes, eg. accept='images/*;capture=camera', capture='true'
        Repository Revision Date User Message
        ICEsoft Public SVN Repository #43951 Mon Jan 26 08:34:18 MST 2015 philip.breau ICE-10447 mobi:camera add getUserMedia support
        Files Changed
        Commit graph ADD /icefaces4/trunk/icefaces/mobi/component/resources/org.icefaces.component.camera/camera.css
        Commit graph MODIFY /icefaces4/trunk/icefaces/mobi/component/src/org/icefaces/mobi/util/MobiJSFUtils.java
        Commit graph ADD /icefaces4/trunk/icefaces/mobi/component/resources/org.icefaces.component.camera
        Commit graph MODIFY /icefaces4/trunk/icefaces/mobi/component/src/org/icefaces/mobi/component/camera/CameraRenderer.java
        Commit graph ADD /icefaces4/trunk/icefaces/mobi/component/resources/org.icefaces.component.camera/camera.js
        Commit graph MODIFY /icefaces4/trunk/icefaces/samples/showcase/showcase/src/main/webapp/resources/examples/mobi/camera/camera-example.xhtml
        Commit graph MODIFY /icefaces4/trunk/icefaces/mobi/component/src/org/icefaces/mobi/component/thumbnail/ThumbnailRenderer.java
        Commit graph MODIFY /icefaces4/trunk/icefaces/mobi/component/src/org/icefaces/mobi/component/camera/CameraMeta.java
        Hide
        Ken Fyten added a comment -

        Note that testing in Safari (desktop) shows that the camera function fails with the attached JS error ("undefined function Navigator.getUserMedia...").

        Show
        Ken Fyten added a comment - Note that testing in Safari (desktop) shows that the camera function fails with the attached JS error ("undefined function Navigator.getUserMedia...").
        Ken Fyten made changes -
        Repository Revision Date User Message
        ICEsoft Public SVN Repository #44021 Fri Feb 06 06:37:43 MST 2015 philip.breau ICE-10447 mobi:camera add getUserMedia support
        - double check navigator.getUserMedia not undefined for Safari
        Files Changed
        Commit graph MODIFY /icefaces4/trunk/icefaces/mobi/component/build.xml
        Commit graph MODIFY /icefaces4/trunk/icefaces/mobi/component/resources/org.icefaces.component.datespinner/datespinner.css
        Commit graph MODIFY /icefaces4/trunk/icefaces/mobi/component/resources/org.icefaces.component.camera/camera.js
        Repository Revision Date User Message
        ICEsoft Public SVN Repository #44022 Fri Feb 06 08:57:37 MST 2015 philip.breau ICE-10447 mobi:camera add getUserMedia support
        - use FileReader to extract image data from file and populate thumbnail and hidden input
        Files Changed
        Commit graph MODIFY /icefaces4/trunk/icefaces/mobi/component/resources/org.icefaces.component.camera/camera.js
        Hide
        Philip Breau added a comment -

        Component no longer requires multipart form when falling back to file upload. Thumbnail is now also updated when using the file upload fallback version.

        Show
        Philip Breau added a comment - Component no longer requires multipart form when falling back to file upload. Thumbnail is now also updated when using the file upload fallback version.
        Philip Breau made changes -
        Status Open [ 1 ] Resolved [ 5 ]
        Resolution Fixed [ 1 ]
        Hide
        Ken Fyten added a comment - - edited

        Philip, my testing today identified the following apparent issues with the updated mobi:camera:

        1. Capture message label does not update on Firefox (works on Safari and Chrome). Is this just a browser support issue / known issue?
        2. Larger images fail on all browsers with Connection Interrupted (1MB+? image files). Any thoughts on why this might be (this when uploading via fileUpload mode)?
        3. Also, the thumbnail resets to an error image icon after the first captured/selected image is uploaded. Subsequent captures/selections work fine and the thumbnail continues to show the captured image after the upload. Would this be a straight thumbnail component issue, or a showcase app. issue of some kind?

        Also, is there a way style the popup camera dialog in terms of size, location, fonts, button padding, etc.?

        Show
        Ken Fyten added a comment - - edited Philip, my testing today identified the following apparent issues with the updated mobi:camera: Capture message label does not update on Firefox (works on Safari and Chrome). Is this just a browser support issue / known issue? Larger images fail on all browsers with Connection Interrupted (1MB+? image files). Any thoughts on why this might be (this when uploading via fileUpload mode)? Also, the thumbnail resets to an error image icon after the first captured/selected image is uploaded. Subsequent captures/selections work fine and the thumbnail continues to show the captured image after the upload. Would this be a straight thumbnail component issue, or a showcase app. issue of some kind? Also, is there a way style the popup camera dialog in terms of size, location, fonts, button padding, etc.?
        Ken Fyten made changes -
        Resolution Fixed [ 1 ]
        Status Resolved [ 5 ] Reopened [ 4 ]
        Repository Revision Date User Message
        ICEsoft Public SVN Repository #44033 Mon Feb 09 16:55:54 MST 2015 philip.breau ICE-10447 mobi:camera add getUserMedia support
        - fix captureLabel not being set on Firefox
        Files Changed
        Commit graph MODIFY /icefaces4/trunk/icefaces/mobi/component/resources/org.icefaces.component.camera/camera.js
        Repository Revision Date User Message
        ICEsoft Public SVN Repository #44038 Tue Feb 10 10:27:28 MST 2015 philip.breau ICE-10447 mobi:camera add getUserMedia support
        - add client-side JPEGEncoder for image file processing
        - a sliding scale of image resolution will be used for images that exceed 50k
        - note that form posts exceeding certain values may still be rejected according to the maximum allowable post size of the server, for Tomcat set the connector maxPostSize accordingly, or disable it with a value of 0.
        Files Changed
        Commit graph MODIFY /icefaces4/trunk/icefaces/mobi/component/src/org/icefaces/mobi/util/MobiJSFUtils.java
        Commit graph ADD /icefaces4/trunk/icefaces/mobi/component/resources/org.icefaces.component.camera/jpeg_encoder_basic.js
        Commit graph MODIFY /icefaces4/trunk/icefaces/samples/showcase/showcase/src/main/webapp/showcase-mobile.xhtml
        Commit graph MODIFY /icefaces4/trunk/icefaces/mobi/component/resources/org.icefaces.component.camera/camera.js
        Commit graph MODIFY /icefaces4/trunk/icefaces/mobi/component/src/org/icefaces/mobi/component/camera/CameraMeta.java
        Repository Revision Date User Message
        ICEsoft Public SVN Repository #44039 Tue Feb 10 10:43:10 MST 2015 philip.breau ICE-10447 mobi:camera add getUserMedia support
        - add client-side JPEGEncoder for image file processing
        - a sliding scale of image resolution will be used for images that exceed 50k
        - note that form posts exceeding certain values may still be rejected according to the maximum allowable post size of the server, for Tomcat set the connector maxPostSize accordingly, or disable it with a value of 0.
        Files Changed
        Commit graph MODIFY /icefaces4/trunk/icefaces/mobi/component/src/org/icefaces/mobi/util/MobiJSFUtils.java
        Repository Revision Date User Message
        ICEsoft Public SVN Repository #44040 Tue Feb 10 10:52:55 MST 2015 philip.breau ICE-10447 mobi:camera add getUserMedia support
        - fix regression with thumbnailRenderer, only render thumbnail when camera and the data attr is available
        Files Changed
        Commit graph MODIFY /icefaces4/trunk/icefaces/mobi/component/src/org/icefaces/mobi/component/thumbnail/ThumbnailRenderer.java
        Hide
        Philip Breau added a comment -
        • client side JPEG encoder added for processing image files
        • a sliding scale of image resolution is used depending on the file size
        • this dramatically shrinks down file size < 500k
        • note that form posts exceeding certain values may still be rejecte by the server. For Tomcat, set the connector maxPostSize accordingly, or disable it with a value of 0
        • the thumbnail renderer regression has also been corrected
        Show
        Philip Breau added a comment - client side JPEG encoder added for processing image files a sliding scale of image resolution is used depending on the file size this dramatically shrinks down file size < 500k note that form posts exceeding certain values may still be rejecte by the server. For Tomcat, set the connector maxPostSize accordingly, or disable it with a value of 0 the thumbnail renderer regression has also been corrected
        Philip Breau made changes -
        Status Reopened [ 4 ] Closed [ 6 ]
        Resolution Fixed [ 1 ]
        Hide
        Ken Fyten added a comment -

        Testing shows the following:

        • On Firefox, selecting a larger image to upload (>1MB) takes a long time and usually causes a long-running script error dialog to show, if you press continue it does eventually complete. However, the resulting image is generally greatly degraded to a point that would be unacceptable for most uses.
        • On Firefox only, the first time you submit a photo that was taken via the camera (not a file upload from the file system), the thumbnail is lost and replaced with a broken image icon. Subsequent image captures work fine, as do all file uploads.

        I do not think that using the client-side image processing approach is going to work as it degrades the image quality without any control or config. available to the application. So long as the server can be configured to accept larger uploads, I think we should remove it and we can document the need to configure the server accordingly. This way the image quality will remain that of the original upload.

        Show
        Ken Fyten added a comment - Testing shows the following: On Firefox, selecting a larger image to upload (>1MB) takes a long time and usually causes a long-running script error dialog to show, if you press continue it does eventually complete. However, the resulting image is generally greatly degraded to a point that would be unacceptable for most uses. On Firefox only, the first time you submit a photo that was taken via the camera (not a file upload from the file system), the thumbnail is lost and replaced with a broken image icon. Subsequent image captures work fine, as do all file uploads. I do not think that using the client-side image processing approach is going to work as it degrades the image quality without any control or config. available to the application. So long as the server can be configured to accept larger uploads, I think we should remove it and we can document the need to configure the server accordingly. This way the image quality will remain that of the original upload.
        Ken Fyten made changes -
        Resolution Fixed [ 1 ]
        Status Closed [ 6 ] Reopened [ 4 ]
        Hide
        Ken Fyten added a comment -

        QA has found the following issues on the iOS Safari browser with this version of the component as well:

        The image cannot be uploaded. Fails with "The uploaded image file could not be correctly processed.".

        Show
        Ken Fyten added a comment - QA has found the following issues on the iOS Safari browser with this version of the component as well: The image cannot be uploaded. Fails with "The uploaded image file could not be correctly processed.".
        Repository Revision Date User Message
        ICEsoft Public SVN Repository #44093 Thu Feb 19 12:36:03 MST 2015 philip.breau ICE-10447 mobi:camera add getUserMedia support
        - remove jpeg encoder
        - scale image files larger than 1mb
        Files Changed
        Commit graph DEL /icefaces4/trunk/icefaces/mobi/component/resources/org.icefaces.component.camera/jpeg_encoder_basic.js
        Commit graph MODIFY /icefaces4/trunk/icefaces/mobi/component/resources/org.icefaces.component.camera/camera.js
        Commit graph MODIFY /icefaces4/trunk/icefaces/mobi/component/src/org/icefaces/mobi/component/camera/CameraMeta.java
        Hide
        Philip Breau added a comment -

        I removed the client side JPEG encoder and retested on all browsers. The image processing is now faster. On Chrome I recorded the following times for a jpg image of ~3.2mb:

        • load image file 28ms
        • create Image object 1000ms
        • create data URLs for thumbnail and image upload with canvs 8500ms

        This is noticably faster than using the jpeg encoder.

        But this creates a worse problem. The Canvas.toDataURL() implementations on all browsers default to creating an png file, and ignore the directive to encode to jpg, which would a reductiion in resolution for the thumbnail and a much smaller image file overall. The resulting png data url is approximately 10X the size of a jpg file. So a 3mb original jpg file will result in a 30mb png file. And uploading the 30mb png then locks up almost all browsers.

        So I don't think we have a choice but to scale larger image files. I've checked in a version that uses a scaling factor for images larger than 1mb and this seems to work well with reasonable performance on all desktop browsers. Scaling is done with Canvas and little loss of effective screen resolution is seen.

        Show
        Philip Breau added a comment - I removed the client side JPEG encoder and retested on all browsers. The image processing is now faster. On Chrome I recorded the following times for a jpg image of ~3.2mb: load image file 28ms create Image object 1000ms create data URLs for thumbnail and image upload with canvs 8500ms This is noticably faster than using the jpeg encoder. But this creates a worse problem. The Canvas.toDataURL() implementations on all browsers default to creating an png file, and ignore the directive to encode to jpg, which would a reductiion in resolution for the thumbnail and a much smaller image file overall. The resulting png data url is approximately 10X the size of a jpg file. So a 3mb original jpg file will result in a 30mb png file. And uploading the 30mb png then locks up almost all browsers. So I don't think we have a choice but to scale larger image files. I've checked in a version that uses a scaling factor for images larger than 1mb and this seems to work well with reasonable performance on all desktop browsers. Scaling is done with Canvas and little loss of effective screen resolution is seen.
        Philip Breau made changes -
        Status Reopened [ 4 ] Resolved [ 5 ]
        Resolution Fixed [ 1 ]
        Hide
        Ken Fyten added a comment -

        Sorry Philip, testing on svn rvn# 44097 I'm seeing the following failures:

        1. On desktop browsers, any file larger than 1MB fails immediately upon upload with a Network Connection Interrupted error. Smaller files work correctly.
        2. On iphone 5 / iOS8.1.3, taking a picture works (via BridgeIt), the thumbnail shows up, but uploading fails with "The uploaded image file could not be correctly processed."
        Show
        Ken Fyten added a comment - Sorry Philip, testing on svn rvn# 44097 I'm seeing the following failures: On desktop browsers, any file larger than 1MB fails immediately upon upload with a Network Connection Interrupted error. Smaller files work correctly. On iphone 5 / iOS8.1.3, taking a picture works (via BridgeIt), the thumbnail shows up, but uploading fails with "The uploaded image file could not be correctly processed."
        Ken Fyten made changes -
        Resolution Fixed [ 1 ]
        Status Resolved [ 5 ] Reopened [ 4 ]
        Hide
        Philip Breau added a comment -

        Ken,
        I can't reproduce the issue with the file upload. I've tested jenkins build #182 with Tomcat 7.0.42 (with post size limit increased) and Win 7 (Chrome 40, FF 35, IE 11), and Mac (Chrome 40 and Safari 8.0.3) and all them succeed processing and posting a 3.2mb jpg file. Have you tried different image files?

        I did notice that the post is including a large thumbnail data url. I'll fix that which should reduce the the post size by about half.

        Show
        Philip Breau added a comment - Ken, I can't reproduce the issue with the file upload. I've tested jenkins build #182 with Tomcat 7.0.42 (with post size limit increased) and Win 7 (Chrome 40, FF 35, IE 11), and Mac (Chrome 40 and Safari 8.0.3) and all them succeed processing and posting a 3.2mb jpg file. Have you tried different image files? I did notice that the post is including a large thumbnail data url. I'll fix that which should reduce the the post size by about half.
        Repository Revision Date User Message
        ICEsoft Public SVN Repository #44099 Fri Feb 20 12:38:02 MST 2015 philip.breau ICE-10447 mobi:camera add getUserMedia support
        - ensure thumbnail dataURL is small
        Files Changed
        Commit graph MODIFY /icefaces4/trunk/icefaces/mobi/component/resources/org.icefaces.component.camera/camera.js
        Repository Revision Date User Message
        ICEsoft Public SVN Repository #44100 Fri Feb 20 18:27:12 MST 2015 philip.breau ICE-10447 mobi:camera add getUserMedia support
        - fix broken bridgeit upload, a change in the function signature was losing the jsessionid, so the image could not be correctly posted to the correct session by the bridgeit utility
        Files Changed
        Commit graph MODIFY /icefaces4/trunk/icefaces/mobi/component/resources/org.icefaces.component.camera/camera.js
        Hide
        Ken Fyten added a comment -

        Testing using Jenkins ICEfaces 4 continuous build (http://dev.icesoft.com/jenkins/job/ICEfaces%204%20Trunk%20(Continuous)/1075/ / svn rvn# 44100)

        1. On desktop browsers, any file larger than 1MB fails immediately upon upload with a Network Connection Interrupted error. Smaller files work correctly.
          • The following JS errors are seen in the console:
            14:27:09.117 "[window] [Mon, 23 Feb 2015 21:27:09 GMT] the response does not contain XML data" bridge-support.js.jsf:1817
            14:27:09.118 "[window] [Mon, 23 Feb 2015 21:27:09 GMT] HTTP error [code: 0]: The Http Transport returned a 0 status code.  This is usually the result of mixing ajax and full requests.  This is usually undesired, for both performance and data integrity reasons." bridge-support.js.jsf:1817 
        2. On iphone 5 / iOS8.1.3, taking a picture works (via BridgeIt), the thumbnail shows, the upload works, but then the thumbnail is immediately cleared. If I recall correctly, I think it was needing to submit the thumbnail to the server so it could be rendered back out to the client after the submit. This is an app. developer choice. I think it is just as valid to clear the thumbnail after a successful submit, so we can leave it like this. As you mentioned in your commit log, it results in a much smaller sized submit to upload the photo without the thumbnail data.
        Show
        Ken Fyten added a comment - Testing using Jenkins ICEfaces 4 continuous build ( http://dev.icesoft.com/jenkins/job/ICEfaces%204%20Trunk%20(Continuous)/1075/ / svn rvn# 44100) On desktop browsers, any file larger than 1MB fails immediately upon upload with a Network Connection Interrupted error. Smaller files work correctly. The following JS errors are seen in the console: 14:27:09.117 "[window] [Mon, 23 Feb 2015 21:27:09 GMT] the response does not contain XML data" bridge-support.js.jsf:1817 14:27:09.118 "[window] [Mon, 23 Feb 2015 21:27:09 GMT] HTTP error [code: 0]: The Http Transport returned a 0 status code. This is usually the result of mixing ajax and full requests. This is usually undesired, for both performance and data integrity reasons." bridge-support.js.jsf:1817 On iphone 5 / iOS8.1.3, taking a picture works (via BridgeIt), the thumbnail shows, the upload works, but then the thumbnail is immediately cleared. If I recall correctly, I think it was needing to submit the thumbnail to the server so it could be rendered back out to the client after the submit. This is an app. developer choice. I think it is just as valid to clear the thumbnail after a successful submit, so we can leave it like this. As you mentioned in your commit log, it results in a much smaller sized submit to upload the photo without the thumbnail data.
        Repository Revision Date User Message
        ICEsoft Public SVN Repository #44110 Tue Feb 24 10:26:33 MST 2015 philip.breau ICE-10447 mobi:camera add getUserMedia support
        - change file and canvas uploads to use FormData and submit to Auxillary upload post url.
        Files Changed
        Commit graph MODIFY /icefaces4/trunk/icefaces/mobi/component/resources/org.icefaces.component.camera/camera.js
        Hide
        Ken Fyten added a comment - - edited

        From Philip's commit log:

        Change file and canvas uploads to use FormData and submit to Auxillary upload post url.

        Show
        Ken Fyten added a comment - - edited From Philip's commit log: Change file and canvas uploads to use FormData and submit to Auxillary upload post url.
        Ken Fyten made changes -
        Status Reopened [ 4 ] Resolved [ 5 ]
        Resolution Fixed [ 1 ]
        Ken Fyten made changes -
        Status Resolved [ 5 ] Closed [ 6 ]

          People

          • Assignee:
            Philip Breau
            Reporter:
            Philip Breau
          • Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: