从另一个线程将UIImage另存为png
本文关键字:另存为 png UIImage 另一个 线程 | 更新日期: 2023-09-27 18:21:54
代码非常简单,它必须从设置文件加载所有现有的图像引用,将它们缩放到250x250,然后用另一个名称保存。
问题是,在该设备(在iPhone 3g和iPad上测试)上,它在一段时间后崩溃,并出现内存警告。在模拟器上,它运行得很完美。
我有一个UIViewController,它在ViewDidPear上有这个代码:
ThreadPool.QueueUserWorkItem( delegate{
make_thumbs();
});
make_thumbs函数为:
void make_thumbs()
{
using( var ns = new NSAutoreleasePool() )
{
foreach( var c in Settings.Instance.Categories )
{
for( var i = 0; i < c.Pictures.Count; i++ )
{
//this is the existing bundled image path
string path = c.Pictures[i].PicturePath;
string folder = Environment.GetFolderPath( Environment.SpecialFolder.Personal );
//this is the destination image file name
string filename = Path.Combine( folder, c.Name + i + ".png");
if( !File.Exists( filename ) )
{
NSError err;
using(UIImage img = UIImage.FromFile( path ).Scale( 250,250 ))
{
img.AsPNG().Save( filename, true, out err );
}
}
}
}
}
}
对于循环中实现IDisposable
的所有内容,您需要扩展我的建议(来自邮件列表)(因为它可以比GC收集内存更快地分配内存)。
正如@Rolf所说,在评论中,img.AsPNG()
返回一个实现IDisposable
的NSData
。
同时调用Scale
方法也返回一个新的UIImage
。
using(UIImage img = UIImage.FromFile( path )) {
using (var scaled_img = img.Scale( 250,250 )) {
using (var data = img.AsPNG ()) {
data.Save( filename, true, out err );
}
}
}
这应该涵盖这个块,即确保尽快回收所有内存,这应该有助于您的设备(其中没有太多可用内存)。
Thx@poupou,你的答案几乎很好,有一点完成:我必须把在for循环中使用(var ns=new NSAutoreleasePool())。所以我的代码现在是这样的,它正在工作:
if( !File.Exists( filename ) )
{
using( var ns = new NSAutoreleasePool() )
{
NSError err;
using(UIImage img = UIImage.FromFile( path )) {
using (var scaled_img = img.Scale( 250,250 ))
{
//i also add a reflection effect
using( var reflected_img = scaled_img.AddImageReflection( 0.6f ) )
{
using (var data = reflected_img.AsPNG ())
{
data.Save( filename, true, out err );
}
}
}
}
}
}