从另一个线程将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 );
                    }
                } 
            } 
        } 
    } 
}

从另一个线程将UIImage另存为png

对于循环中实现IDisposable的所有内容,您需要扩展我的建议(来自邮件列表)(因为它可以比GC收集内存更快地分配内存)。

正如@Rolf所说,在评论中,img.AsPNG()返回一个实现IDisposableNSData

同时调用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 );
                    }
                }
             }
        }
    }
}