Titanium JIRA Archive
Titanium SDK/CLI (TIMOB)

[TIMOB-25314] iOS: camera with overlay view is zoomed

GitHub Issuen/a
TypeBug
PriorityCritical
StatusClosed
ResolutionFixed
Resolution Date2018-05-23T09:52:44.000+0000
Affected Version/sn/a
Fix Version/sRelease 7.3.0
ComponentsiOS
Labelscamera, iOS, zoomscale
ReporterZakhar Zhuravlev
AssigneeVijay Singh
Created2017-09-18T08:48:39.000+0000
Updated2018-06-12T17:52:38.000+0000

Description

If I add overlayView to camera, then camera view becomes zoomed. Without overlayView camera has another zoom value. I prepared test project. *index.js:*
var overlay = Ti.UI.createView({});
var closeBtn = Ti.UI.createButton({
    width: "40dp",
    height: "40dp",
    backgroundColor: "red",
    opacity: 0.3,
    bottom: "10dp",
    left: "10dp"
});
closeBtn.addEventListener("click", function() {
    Ti.Media.hideCamera();
});
overlay.add(closeBtn);

function onGallery() {
    Ti.Media.showCamera({
        mediaTypes: [Ti.Media.MEDIA_TYPE_VIDEO],
        showControls: true,
        success:function(e) {
            console.log("\n success");
        },
        cancel: function() {
            console.log("cancel");
        },
        error:function(error) {
            console.log("error");
        }
    });
}

function onGalleryOverlay() {
    Ti.Media.showCamera({
        mediaTypes: [Ti.Media.MEDIA_TYPE_VIDEO],
        showControls: false,
        overlay: overlay,
        success:function(e) {
            console.log("\n success");
        },
        cancel: function() {
            console.log("cancel");
        },
        error:function(error) {
            console.log("error");
        }
    });
}

function onGalleryWithoutControls() {
    Ti.Media.showCamera({
        mediaTypes: [Ti.Media.MEDIA_TYPE_VIDEO],
        showControls: false,
        success:function(e) {
            console.log("\n success");
        },
        cancel: function() {
            console.log("cancel");
        },
        error:function(error) {
            console.log("error");
        }
    });
}

$.win.open();
*index.html:*
<Alloy>
	<Window id='win' backgroundColor="white">
		<Button bottom="10dp" width="80%" height="50dp" title="Gallery" onClick="onGallery" />
		<Button bottom="70dp" width="80%" height="50dp" title="Gallery with overlay" onClick="onGalleryOverlay" />
		<Button bottom="130dp" width="80%" height="50dp" title="Gallery without controls" onClick="onGalleryWithoutControls" />
	</Window>
</Alloy>

Comments

  1. Hans Knöchel 2017-09-18

    Did this only happen since 6.1.1 or before as well?
  2. Zakhar Zhuravlev 2017-09-18

    I don't know, I implemented it recently and tested only with these two sdks.
  3. Hans Knöchel 2017-09-18

    Ok, here is the issue: The code goes into [here](https://github.com/appcelerator/titanium_mobile/blob/master/iphone/Classes/MediaModule.m#L1632-L1646) suspecting the view is inside a popover ( = a feature for the iPad to show the camera inside a popover without the 4:3 black edges) and it's there since forever. It's the unusual of a camera, an overlay and no transform applied. The convenient workaround that will fix your issue immediately is to add the transform: Ti.UI.create2DMatrix({ scale: 1}) to your picker options. Here is your example fixed (Ti-Classic to drop-in):
       var overlay = Ti.UI.createView({width: Ti.UI.FILL, height: Ti.UI.FILL});
       var closeBtn = Ti.UI.createButton({
           width: 40,
           height: 40,
           backgroundColor: "red",
       });
       closeBtn.addEventListener("click", function() {
           Ti.Media.hideCamera();
       });
       overlay.add(closeBtn);
        
       function onGallery() {
           Ti.Media.showCamera({
               mediaTypes: [Ti.Media.MEDIA_TYPE_VIDEO],
               showControls: true,
               success:function(e) {
                   console.log("\n success");
               },
               cancel: function() {
                   console.log("cancel");
               },
               error:function(error) {
                   console.log("error");
               }
           });
       }
        
       function onGalleryOverlay() {
           Ti.Media.showCamera({
               mediaTypes: [Ti.Media.MEDIA_TYPE_VIDEO],
               showControls: false,
               overlay: overlay,
               transform: Ti.UI.create2DMatrix({scale: 1}),
               success:function(e) {
                   console.log("\n success");
               },
               cancel: function() {
                   console.log("cancel");
               },
               error:function(error) {
                   console.log("error");
               }
           });
       }
        
       function onGalleryWithoutControls() {
           Ti.Media.showCamera({
               mediaTypes: [Ti.Media.MEDIA_TYPE_VIDEO],
               showControls: false,
               success:function(e) {
                   console.log("\n success");
               },
               cancel: function() {
                   console.log("cancel");
               },
               error:function(error) {
                   console.log("error");
               }
           });
       }
       
       var win = Ti.UI.createWindow({
         backgroundColor: '#fff',
         layout: 'vertical'
       });
       
       var btn1 = Ti.UI.createButton({
         title: 'Show Camera',
         top: 50
       });
       var btn2 = Ti.UI.createButton({
         title: 'Show Camera with Overlay',
         top: 50
       });
       var btn3 = Ti.UI.createButton({
         title: 'Show Camera with Overlay w.o. controls',
         top: 50
       });
       
       btn1.addEventListener('click', onGallery);
       btn2.addEventListener('click', onGalleryOverlay);
       btn3.addEventListener('click', onGalleryWithoutControls);
       
       win.add(btn1);
       win.add(btn2);
       win.add(btn3); 
       win.open();
       
    Scheduling for 7.0.0. *EDIT*: This is actually per design (see TIMOB-17627), so if the user does explicitly want the black stripes, a transform to scale = 1 is applied. Keeping open for now to be discussed internally, but you should be unblocked anyway!
  4. Zakhar Zhuravlev 2017-09-18

    Great, your workaround helped me. Thank you
  5. Eric Merriman 2017-11-01

    Due to the schedule for 7.0.0 versus the remaining work, moving to 7.1.0
  6. Vijay Singh 2018-01-22

    [~hknoechel] As you have mentioned, it is as per design. In my view - 1. If camera controls are there, then no need to scale it irrespective of overlay view. Reason is if we are showing the camera control, it is expected to capture image/video (and other camera operations) from camera controls. 2. If camera controls are not visible and there is overlay view, it is expected to capture image/video (and other camera operations) using overlay view. In this case black area should be removed and we should scale camera preview. 3. If neither camera controls nor overlay view is there, then there is no need to scale. In this case we can not predict developer's intention. In our SDK point 2 and 3 are already implemented as part of TIMOB-17627. For point 1 if there is overlay and camera controls are visible, in that case also it is scaling the camera preview. We can apply a condition for this - if (overlayview != nil && showControls == false) { Scale camera preview. } else { Do not scale camera preview. } [~hknoechel] If you agree on this, I'll create PR for same. Thanks!
  7. Vijay Singh 2018-02-13

    PR- https://github.com/appcelerator/titanium_mobile/pull/9818 Test Case -
       var overlay = Ti.UI.createView({width: Ti.UI.FILL, height: Ti.UI.FILL});
       var closeBtn = Ti.UI.createButton({
           width: 40,
           height: 40,
           backgroundColor: "red",
       });
       closeBtn.addEventListener("click", function() {
           Ti.Media.hideCamera();
       });
       overlay.add(closeBtn);
        
       function onGallery() {
           Ti.Media.showCamera({
               mediaTypes: [Ti.Media.MEDIA_TYPE_VIDEO],
               showControls: false,
               overlay: overlay,
               success:function(e) {
                   console.log("\n success");
               },
               cancel: function() {
                   console.log("cancel");
               },
               error:function(error) {
                   console.log("error");
               }
           });
       }
        
       function onGalleryOverlay() {
           Ti.Media.showCamera({
               mediaTypes: [Ti.Media.MEDIA_TYPE_VIDEO],
               showControls: true,
               overlay: overlay,
               //transform: Ti.UI.create2DMatrix({scale: 1}),
               success:function(e) {
                   console.log("\n success");
               },
               cancel: function() {
                   console.log("cancel");
               },
               error:function(error) {
                   console.log("error");
               }
           });
       }
        
       function onGalleryWithoutControls() {
           Ti.Media.showCamera({
               mediaTypes: [Ti.Media.MEDIA_TYPE_VIDEO],
               showControls: false,
               success:function(e) {
                   console.log("\n success");
               },
               cancel: function() {
                   console.log("cancel");
               },
               error:function(error) {
                   console.log("error");
               }
           });
       }
        
       var win = Ti.UI.createWindow({
         backgroundColor: '#fff',
         layout: 'vertical'
       });
        
       var btn1 = Ti.UI.createButton({
         title: 'Show Camera with overlay w.o. controls',
         top: 50
       });
       var btn2 = Ti.UI.createButton({
         title: 'Show Camera with Overlay with controls',
         top: 50
       });
       var btn3 = Ti.UI.createButton({
         title: 'Show Camera w.o Overlay w.o. controls',
         top: 50
       });
        
       btn1.addEventListener('click', onGallery);
       btn2.addEventListener('click', onGalleryOverlay);
       btn3.addEventListener('click', onGalleryWithoutControls);
        
       win.add(btn1);
       win.add(btn2);
       win.add(btn3); 
       win.open();
       
    Note - In second case, zoom should not happen.
  8. Samir Mohammed 2018-05-22

    FR Passed, waiting on Jenkins build to pass.
  9. Samir Mohammed 2018-06-12

    Closing ticket. Fix can be seen in SDK Version: 7.3.0.v20180607210411 Test and other information can be found at: https://github.com/appcelerator/titanium_mobile/pull/9818

JSON Source