内存问题使用CGImage.ScreenImage和UIImagePickerController Mono Touch [英] Memory issue using CGImage.ScreenImage and UIImagePickerController Mono Touch

查看:179
本文介绍了内存问题使用CGImage.ScreenImage和UIImagePickerController Mono Touch的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用单键触摸为iPhone创建IP摄像头应用程序。要获取相机Feed,请调用 CGImage.ScreenImage 方法,并将生成的UIImage转换为字节数组,然后传输到浏览器。通过设置

I'm trying to create an IP Camera application for iPhone using mono touch. To get the camera feed, I call the CGImage.ScreenImage method continuously and convert the resulting UIImage into a byte array which is then transmitted across to the browser. The camera feed is displayed using a UIImagePickerController class by setting the

SourceType = UIImagePickerControllerSourceType.Camera;

以下是ImageController类的完整代码:

Here are the complete code for the ImageController class:

public class ImageController : UIImagePickerController
{
    private HttpListener listener;

    public ImageController ()
    {
        SourceType = UIImagePickerControllerSourceType.Camera;
        start();
    }

    void start()
    {
        listener = new HttpListener();
        listener.Prefixes.Add( "http://+:8001/" );
        listener.Prefixes.Add( "http://+:8001/current.jpg/" );
        listener.Start();
        listener.BeginGetContext( HandleRequest, listener );
    }

    public override void DidReceiveMemoryWarning ()
    {
        GC.Collect();
    }


    private void HandleRequest(IAsyncResult result)
    {
        HttpListenerContext context = listener.EndGetContext( result );
        listener.BeginGetContext( HandleRequest, listener );
        if ( context.Request.RawUrl.Contains( "current.jpg" ) )
        {
            context.Response.StatusCode = (int) HttpStatusCode.OK;
            context.Response.ContentType = @"multipart/x-mixed-replace;boundary=--myboundary";
            context.Response.KeepAlive = true;
            byte [] imageData;
            byte [] boundary;

            while ( true )
            {
                imageData = worker();
                boundary =
                    Encoding.UTF8.GetBytes(
                        "\r\n--myboundary\r\nContent-Type: image/jpeg\r\nContent-Length: " +
                        imageData.Length + "\r\n\r\n" );
                context.Response.OutputStream.Write( boundary, 0, boundary.Length );
                context.Response.OutputStream.Write( imageData, 0, imageData.Length );
                imageData = null;
                boundary = null;
            }
        }
        else
        {
            string responseString = @"<html xmlns=""http://www.w3.org/1999/xhtml""> <body bgcolor=""#fffffff"">"+
                        @"<img name=""current"" src=""current.jpg"" border=""0"" id=""current"" /></body></html>";

            byte [] responseByte = Encoding.UTF8.GetBytes( responseString );
            context.Response.ContentType = "text/html";
            context.Response.KeepAlive = true;
            context.Response.StatusCode = (int) HttpStatusCode.OK;
            context.Response.ContentLength64 = responseByte.Length;
            context.Response.OutputStream.Write( responseByte, 0, responseByte.Length );
            context.Response.OutputStream.Close();
         }
     }

     private byte [] worker()
     {
         byte [] imageArray;
         using ( var screenImage = CGImage.ScreenImage )
         {
             using ( var image = UIImage.FromImage(screenImage) )
             {
                 using ( NSData imageData = image.AsJPEG())
                 {
                     imageArray = new byte[imageData.Length];
                     Marshal.Copy(imageData.Bytes, imageArray, 0, Convert.ToInt32(imageData.Length));
                 }
             }
         }
         return imageArray;
      }
   }
}

是我在大约20秒的流式传输后收到一条内存警告,5秒后又收到一条内存警告,然后应用程序崩溃。

The problem I'm having is that I receive a memory warning after about 20 seconds of streaming and a second one after 5 seconds, then the application crashes.

2010-11-08 13:12: 56.457 MonoTouchCGImageScreenImageTest [2251:307]接收到内存警告。 Level = 1

2010-11-08 13:12:56.457 MonoTouchCGImageScreenImageTest[2251:307] Received memory warning. Level=1

2010-11-08 13:13:11.059 MonoTouchCGImageScreenImageTest [2251:307]接收到内存警告。 Level = 2

2010-11-08 13:13:11.059 MonoTouchCGImageScreenImageTest[2251:307] Received memory warning. Level=2

所有显示的图像已在使用语句中处理,并且imageData变量在传输后也设置为null。
是否有一些方法需要调用或有一个更好的解决我的问题?

All of the images that were displayed have been disposed of within the using statement and the imageData variable is also been set to null once it is transmitted. Is there some method that needs to be called or is there a better solution to my problem? Any help would be appreciated.

感谢

推荐答案

worker()在一个永无止境的循环中:

You are calling worker() in a never ending loop:

        while ( true )
        {
            imageData = worker();
            boundary =
                Encoding.UTF8.GetBytes(
                    "\r\n--myboundary\r\nContent-Type: image/jpeg\r\nContent-Length: " +
                    imageData.Length + "\r\n\r\n" );
            context.Response.OutputStream.Write( boundary, 0, boundary.Length );
            context.Response.OutputStream.Write( imageData, 0, imageData.Length );
            imageData = null;
            boundary = null;
        }

这意味着即使你被处置,

Which means that even tho you are disposing, you're in a tight allocation loop which will put a lot of pressure on the GC.

此外,您使用的UIImage.FromImage()从obj-c运行时返回一个自动释放的对象,但是因为你永远不会屈服于主循环,NSAutoreleasePool不能释放这个对象。

Additionally, you are using UIImage.FromImage() which returns an autoreleased object from the obj-c runtime, but since you never yield to the main loop, the NSAutoreleasePool cannot release this object.

这篇关于内存问题使用CGImage.ScreenImage和UIImagePickerController Mono Touch的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆