WP 8.1:开发如何处理摄像头翻转的问题

移动开发
模拟器就像我们儿时的梦境,在其上运行应用程序时,一切总是那么美好的;而真机测试如同我们这个纷乱无章的现实世界,你会遇到各种小人和畜生,常常会遭受莫名的挫折。面对挫折,有人迎难而上,或不予理采,走自己的路;有的人则打退堂鼓。

模拟器就像我们儿时的梦境,在其上运行应用程序时,一切总是那么美好的;而真机测试如同我们这个纷乱无章的现实世界,你会遇到各种小人和畜生,常常会遭受莫名的挫折。面对挫折,有人迎难而上,或不予理采,走自己的路;有的人则打退堂鼓。

面对摄像头翻转的问题,有些人也会选择逃避。我为什么不喜欢现在的某些程序员,就是因为这些人只会逃避和制造问题,遇到问题不是去寻找解决方案,而是坐在那里喊爹骂娘。虽然不可能所有问题都可以解决,但是,有许多问题是可以解决的,而这些人总心浮气躁,不愿意静下心来好好思考。

N+6年前我曾经读过一本好书,名叫《方法总比问题多》,捧着这个心念,我认为摄像头翻转的问题是可以解决的。

通常,我们很少会调用前置摄像头,多数情况下用到的是后置摄像头。当然了,解决方法是类似的,因此,为了简单易懂,本文我就以后置摄像头为例,分享一下我的解决方案,如果你有更好的方法,也不妨让大伙儿一起参考参考。

一般而言,真机上的摄像头是与手机横放时的角度一致,即偏了90度(手机逆时针旋转)。

也就是说,当手机逆时针旋转90度后,机器的方向就与摄像头一致了。针对这一情况,我们只要能做到一件事,那就可以解决摄像头翻转的问题了。

锁定页面的方向,即当手机方向改变时,禁止页面跟着旋转就可以了。

此处以Silverlight框架为例,Runtime App比较好办,直接在清单文件中把屏幕方向强制为横向即可。但Silverlight程序就需要一些步骤。

1、设置页面的SupportedOrientations="Landscape",Orientation="LandscapeLeft",如下面XAML所示。

<phone:PhoneApplicationPage 
    x:Class="AppCamera.MainPage" 
    …… 
    SupportedOrientations="Landscape" Orientation="LandscapeLeft" 
    shell:SystemTray.IsVisible="False"
…… 
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.

这样做就把页面所支持的方向限制为横向,页面的默认方向也改为LandscapeLeft,即手机逆时针旋转90,如果是LandscapeRight,v那就是手机逆时针旋转270度。

2、光是把页面强制为横向还不行,因为横向有两个方向——90度和270度,当手机转动90度后,其方向正好与摄像头吻合,但是,一旦手机旋转 270度后,就正好与摄像头的方向相反,即转了180度,这时候,你在手机屏幕上看到的摄像预览是倒过来的,而拍出来的照片当然也是倒立的,关于保存照片 的问题,稍后再说。

因此,我们必须想办法,阻止页面更改方向,正好,页面类有一个虚方法叫OnOrientationChanged,当页面的方向发生改变后,会调用 该方法。我们只要重写这个方法,并且不要加入任何代码,就能阻止页面基类调用该方法,也就达到了阻止页面改变方向了,“搜狐拍客”就是用这种方法来解决翻 转问题的。

protected override void OnOrientationChanged ( OrientationChangedEventArgs e ) 
       { 
           // 把下面的代码注释掉,页面的方向就会锁定 
           //base.OnOrientationChanged(e); 
       } 
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.

注意。base.OnOrientationChanged(e);这行代码必须去掉,不然基类会调用

3、通过上述步骤,是解决了摄像头预览翻转的问题,但又引出另一个新问题:如果屏幕方向与摄像头的方向不一致,那么拍照出来的照片也会反过来的。这个问题就必须在图像文件上做功夫了,也就是把图像的方向调整过来再保存。

我的示例是使用MediaCapture类来拍摄的,拍到的图片是直接保存到文件或流中了,那我们如何修改图片呢?

在Windows.Graphics.Imaging命名空间下,BitmapDecoder类可以用来对图像进行解码,并可以提取图像的像素数据;BitmapEncoder类可以对图像的像素数据进行编码为图像文件。

对,我们就是利用这两个类,先将摄像头拍到的照片解码,然后利用旋转变换来修改图像的方向,最后将修改后的图像重新编码就可以了。至于要把图像向哪个方向旋转,大家不妨自己试一试,对比一下就能知道了。

以下是参考代码:

#region 图像解码与编码 
 
async Task EncodeImage ( IRandomAccessStream inStream, IRandomAccessStream outStream ) 

    Guid jpegIDen = BitmapEncoder.JpegEncoderId; //编码器ID 
    Guid jpegIDde = BitmapDecoder.JpegDecoderId; //获取解码器ID 
    BitmapDecoder decoder = await BitmapDecoder.CreateAsync(jpegIDde, inStream); 
 
    byte[] buffer= ( await decoder.GetPixelDataAsync()).DetachPixelData(); 
 
    BitmapEncoder encoder = await BitmapEncoder.CreateAsync(jpegIDen, outStream); 
    // 判断手机方向,以改变图像方向 
    var ort = ortsensor.GetCurrentOrientation(); 
    switch (ort) 
    { 
        case SimpleOrientation.NotRotated: 
            encoder.BitmapTransform.Rotation = BitmapRotation.Clockwise90Degrees; 
            break
        case SimpleOrientation.Rotated180DegreesCounterclockwise: 
            encoder.BitmapTransform.Rotation = BitmapRotation.Clockwise270Degrees; 
            break
        case SimpleOrientation.Rotated270DegreesCounterclockwise: 
            encoder.BitmapTransform.Rotation = BitmapRotation.Clockwise180Degrees; 
            break
        case SimpleOrientation.Rotated90DegreesCounterclockwise: 
            encoder.BitmapTransform.Rotation = BitmapRotation.None; 
            break
    } 
    // 设置像素数据 
    encoder.SetPixelData(BitmapPixelFormat.Bgra8, BitmapAlphaMode.Straight, decoder.PixelWidth, decoder.PixelHeight, decoder.DpiX, decoder.DpiY, buffer); 
    await encoder.FlushAsync(); 

#endregion 
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.

由于在确认图像旋转方向前,我们必须知道手机的当前方向。比较简单的方法是直接访问 Windows.Graphics.Display.DisplayProperties类的CurrentOrientation属性,不过这个类在新 版本中可能会被删除,所以我就不用这个方法。我于是选用了一个稍稍复杂点的方法——使用方向传感器。这种方法有点装逼,不过正好我们可以发挥一下传感器的 用处,其实屏幕方向也是通过方向(重力)传感器来识别的。

为了让开发者可以轻松识别出手机的几个特殊方向,以SimpleOrientation枚举定义了几个比较通用的方向。这些值的含义如下表所示。

对应地,在Windows.Devices.Sensors命名空间下,有一个SimpleOrientationSensor类,它表示方向传感器,它可以提供上表所示的几个特殊方向的值的实时报告,这样我们就不用自己来计算坐标值了。

声明SimpleOrientationSensor实例,处理OrientationChanged事件。

 if (ortsensor == null
            { 
                ortsensor = SimpleOrientationSensor.GetDefault(); 
            } 
     …… 
ortsensor.OrientationChanged += ortsensor_OrientationChanged; 
 
.............. 
 
        void ortsensor_OrientationChanged ( SimpleOrientationSensor sender, SimpleOrientationSensorOrientationChangedEventArgs args ) 
        { 
            // 根据方向旋转拍摄图标 
            var o = args.Orientation; 
            System.Diagnostics.Debug.WriteLine("方向:{0}", o); 
            Dispatcher.BeginInvoke(() => 
                { 
                    UpdateOrientation(o); 
                }); 
        } 
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.

在上面对图像进行编码的代码中,是通过SimpleOrientationSensor对象的GetCurrentOrientation方法来获取手机当前所处的方向,进而判断出图像应该旋转的方向。

switch (ort) 
           { 
               case SimpleOrientation.NotRotated: 
                   encoder.BitmapTransform.Rotation = BitmapRotation.Clockwise90Degrees; 
                   break
               case SimpleOrientation.Rotated180DegreesCounterclockwise: 
                   encoder.BitmapTransform.Rotation = BitmapRotation.Clockwise270Degrees; 
                   break
               case SimpleOrientation.Rotated270DegreesCounterclockwise: 
                   encoder.BitmapTransform.Rotation = BitmapRotation.Clockwise180Degrees; 
                   break
               case SimpleOrientation.Rotated90DegreesCounterclockwise: 
                   encoder.BitmapTransform.Rotation = BitmapRotation.None; 
                   break
           } 
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.

好了,经过以上几个步骤,摄像头翻转的问题可以得到解决了

 本文链接:http://www.cnblogs.com/tcjiaan/p/3944948.html

责任编辑:chenqingxiang 来源: oschina
相关推荐

2011-09-08 13:53:20

Linux摄像头

2013-03-21 09:56:09

2017-06-20 11:45:52

2021-03-11 10:21:55

特斯拉黑客网络攻击

2018-06-20 11:54:54

2014-07-16 13:36:30

MotionLinux监控

2020-06-04 10:59:10

JavaScript开发技术

2009-08-21 17:17:49

C#摄像头编程

2024-11-29 16:51:18

2023-03-24 10:28:27

2011-04-25 09:16:10

Windows 8

2012-06-23 20:13:44

HTML5

2012-08-29 10:12:13

人才创业硅谷

2022-05-12 09:25:19

Python播放视频摄像头

2023-01-13 08:00:00

人工智能摄像头人脸识别

2009-06-17 11:52:01

Linux

2009-08-21 17:24:18

C#控制摄像头

2021-01-26 14:27:21

鸿蒙HarmonyOS应用

2010-05-17 10:04:45

2013-11-06 11:31:28

Android游戏
点赞
收藏

51CTO技术栈公众号