[英]Memory consumption of BitmapImage/Image control in Windows Phone 8
[英]Out of Memory exception BitMapImage for Windows Phone 8
单击图片两次或三遍后,appCapImg.SetSource中出现内存不足异常。 我尝试使用一些内存工具进行分析,但是找不到问题。 难道我做错了什么
byte[] data = null;
public PhotoCamera cam;
fnInitializeCamera();
private void fnInitializeCamera()
{
gobject.txtMessage.Text = "Tap the screen to capture a photo.";
if (PhotoCamera.IsCameraTypeSupported(CameraType.Primary) == true)
{
cam = new PhotoCamera(CameraType.Primary);
cam.CaptureImageAvailable += new EventHandler<Microsoft.Devices.ContentReadyEventArgs>(cam_CaptureImageAvailable);
gobject.viewfinderBrush.SetSource(cam);
if (gobject.Orientation == PageOrientation.PortraitUp)
{
gobject.viewfinderTransform.Rotation = 90.0;
}
}
else
{
gobject.txtMessage.Text = "A Camera is not available on this device.";
}
}
public void viewfinder_Tapped(object sender, GestureEventArgs e)
{
gobject.txtMessage.Text = "Saving Image..";
if (cam != null)
{
try
{
cam.CaptureImage();
}
catch (Exception ex)
{
Deployment.Current.Dispatcher.BeginInvoke(delegate()
{
gobject.txtMessage.Text = ex.Message;
});
}
}
}
private void RotateStream(Stream stream, int angle)
{
stream.Position = 0;
if (angle % 90 != 0 || angle < 0) throw new ArgumentException();
if (angle % 360 == 0) data= ((MemoryStream)stream).ToArray();
BitmapImage bitmap = new BitmapImage();
bitmap.DecodePixelWidth = 480;
bitmap.SetSource(stream);
stream.Dispose();
WriteableBitmap wbSource = new WriteableBitmap(bitmap);
bitmap.UriSource = null;
WriteableBitmap wbTarget = null;
if (angle % 180 == 0)
{
wbTarget = new WriteableBitmap(wbSource.PixelWidth, wbSource.PixelHeight);
}
else
{
wbTarget = new WriteableBitmap(wbSource.PixelHeight, wbSource.PixelWidth);
}
int width = wbSource.PixelWidth;
int height = wbSource.PixelHeight;
int targetWidth = wbTarget.PixelWidth;
int[] sourcePixels = wbSource.Pixels;
int[] targetPixels = wbTarget.Pixels;
for (int x = 0; x < width; x++)
{
for (int y = 0; y < height; y++)
{
switch (angle % 360)
{
case 90:
targetPixels[(height - y - 1) + x * targetWidth] = sourcePixels[x + y * width];
break;
case 180:
targetPixels[(width - x - 1) + (height - y - 1) * width] = sourcePixels[x + y * width];
break;
case 270:
targetPixels[y + (width - x - 1) * targetWidth] = sourcePixels[x + y * width];
break;
}
}
}
using (MemoryStream targetStream = new MemoryStream())
{
wbTarget.SaveJpeg(targetStream, width, height, 0, 100);
data = targetStream.ToArray();
}
}
void cam_CaptureImageAvailable(object sender, Microsoft.Devices.ContentReadyEventArgs e)
{
cam.Dispose();
Deployment.Current.Dispatcher.BeginInvoke(delegate()
{
gobject.disableCameraPlugin();
gobject.enableWebBrowser();
BitmapImage appCapImg = new BitmapImage();
if (gobject.Orientation == PageOrientation.PortraitUp)
{
RotateStream(e.ImageStream, 90);
// Stream stream = new MemoryStream(data1);
using (MemoryStream streamT = new MemoryStream(data))
{
appCapImg.SetSource(streamT);
}
data = null;
}
else
{
RotateStream(e.ImageStream, 180);
e.ImageStream.Dispose();
using (MemoryStream streamT = new MemoryStream(data))
{
appCapImg.SetSource(streamT);
}
data = null;
}
using (MemoryStream stream = new MemoryStream())
{
WriteableBitmap wBitmap = new WriteableBitmap(appCapImg);
appCapImg.UriSource = null;
wBitmap.SaveJpeg(stream, wBitmap.PixelWidth, wBitmap.PixelHeight, 0, 40);
stream.Seek(0, SeekOrigin.Begin);
data = stream.ToArray();
}
string base64 = Convert.ToBase64String(data);
string[] invokeparam1 = { htmlid, base64 };
invokeScript("showimage", invokeparam1);
}
正如我一直说的,MemoryStream应该小心处理。 使用它之后,您始终可以认为必须在MemoryStream对象上调用dispose。 在以下代码中,您已经很好地处理了此问题,
using (MemoryStream stream = new MemoryStream()) { .... }
您永远不要直接从方法返回任何流。 它没有什么错,除了它违反了您先前应用的原理以在所有Stream对象上手动调用Dispose()。 因此,您可以尝试从方法中返回byte []而不是Stream。
private Stream RotateStream(Stream stream, int angle)
并且始终将所有流对象包括在using {...}块中。 同样,您的代码看起来不完整。 就像变量“ e”代表什么一样。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.