J'essaie de créer une application de caméra IP pour iPhone en utilisant le toucher mono. Pour obtenir le flux de la caméra, j'appelle la méthode CGImage.ScreenImage en continu et convertis le UIImage résultant en un tableau d'octets qui est ensuite transmis au navigateur. L'alimentation de la caméra est affiché à l'aide d'une classe UIImagePickerController en définissant lesProblème de mémoire avec CGImage.ScreenImage et UIImagePickerController Mono Touch
SourceType = UIImagePickerControllerSourceType.Camera;
Voici le code complet pour la classe ImageController:
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;
}
}
}
Le problème que je vais avoir est que je reçois un avertissement de mémoire après environ 20 secondes de streaming et un second après 5 secondes, puis l'application se bloque.
2010-11-08 13: 12: 56.457 MonoTouchCGImageScreenImageTest [2251: 307] Avertissement de mémoire reçu. Niveau = 1
2010-11-08 13: 13: 11.059 MonoTouchCGImageScreenImageTest [2251: 307] Avertissement de mémoire reçue. Niveau = 2
Toutes les images affichées ont été éliminées dans l'instruction using et la variable imageData est également définie sur null une fois transmise. Existe-t-il une méthode qui doit être appelée ou existe-t-il une meilleure solution à mon problème? Toute aide serait appréciée.
Merci
J'ai réussi à réduire à UIImage.FromImage comme le coupable. La raison pour laquelle j'utilise cette méthode est de convertir l'image en tableau d'octets afin que je puisse le transmettre. Y a-t-un autre moyen de faire ça? – leonardo