jjzjj

ios - UIImageView 性能不佳(对于本地镜像)

coder 2024-01-20 原文

我正在开发一个带有图库的应用程序。 所有图像都在设备光盘(文档目录)上,但我无法流畅显示。

由于有些图像很大 (2000px * 2000px),我在后台线程中加载它们,缩小它们,然后在主线程中显示它们。

这是我的 UIImageView 扩展:

@implementation UIImageView (BackgroundResize) 

- (void)localImageFromPath: (NSString *) path scaledTo: (CGSize) size {
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0);
    dispatch_async(queue, ^{
        //Load image
        NSData * imgData = [[NSData alloc] initWithContentsOfFile:path];
        UIImage * original = [[[UIImage alloc]  initWithData:imgData] autorelease];
        [imgData release];
        CGSize imgSize = original.size;
        float widthScale = size.width / imgSize.width;
        float heightScale = size.height / imgSize.height;
        float scaleFactor = widthScale;
        if (heightScale < scaleFactor) {
            scaleFactor = heightScale;
        }
        UIImage * result = nil;
        //Scale if necessary
        if (scaleFactor < 1.0) {
            result = [[UIImage alloc] initWithCGImage:original.CGImage scale:1/scaleFactor orientation:original.imageOrientation];
        } else {
            result = [original retain];
        }
        NSLog(@"Image prepeared on backgroud thread, update ui image on main..");
        dispatch_async(dispatch_get_main_queue(), ^{
            NSLog(@"Begin updating image on main thread");
            self.image = result;
            [result release];
            [[NSNotificationCenter defaultCenter] postNotificationName:NTF_IMG_LOADED object:self];
            NSLog(@"Updated");
        });

    });
    dispatch_release(queue);

}
@end

在控制台输出中,一切看起来都很完美,所有调试字符串都在不到 1 秒内显示(对于 6 个非常大的图像),但 UI 被阻止并且图像延迟 10 秒显示。

在 iOS 上显示大型本地镜像的正确方法是什么?

应用程序是为 iOS5+ 构建的..

谢谢,

最佳答案

您实际上并没有调整图像大小。 -initWithCGImage:scale:scale参数设置图像像素与屏幕坐标点的比例;它不会对底层图像做任何事情。您需要实际将图像绘制到 CGContext 以缩小它:

    //Load image
    UIImage * original = [[[UIImage alloc] initWithContentsOfFile:path] autorelease];

    CGSize imgSize = original.size;
    float widthScale = size.width / imgSize.width;
    float heightScale = size.height / imgSize.height;
    float scaleFactor = widthScale;
    if (heightScale < scaleFactor) {
        scaleFactor = heightScale;
    }

    UIImage * result = nil;
    //Scale if necessary
    if (scaleFactor < 1.0) {
        CGSize newSize = CGSizeMake(floorf(imgSize.width * scaleFactor),
                                    floorf(imgSize.height * scaleFactor));
        UIGraphicsBeginImageContextWithOptions(newSize, NO, 0);
        CGContextRef context = UIGraphicsGetCurrentContext();
        CGContextSetInterpolationQuality(context, kCGInterpolationHigh);
        [original drawInRect:CGRectMake(0, 0, newSize.width, newSize.height)];
        result = UIGraphicsGetImageFromCurrentImageContext();
        [result retain];
        UIGraphicsEndImageContext();
    } else {
        result = [original retain];
    }

关于ios - UIImageView 性能不佳(对于本地镜像),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15852820/

有关ios - UIImageView 性能不佳(对于本地镜像)的更多相关文章

  1. ruby - 使用 C 扩展开发 ruby​​gem 时,如何使用 Rspec 在本地进行测试? - 2

    我正在编写一个包含C扩展的gem。通常当我写一个gem时,我会遵循TDD的过程,我会写一个失败的规范,然后处理代码直到它通过,等等......在“ext/mygem/mygem.c”中我的C扩展和在gemspec的“扩展”中配置的有效extconf.rb,如何运行我的规范并仍然加载我的C扩展?当我更改C代码时,我需要采取哪些步骤来重新编译代码?这可能是个愚蠢的问题,但是从我的gem的开发源代码树中输入“bundleinstall”不会构建任何native扩展。当我手动运行rubyext/mygem/extconf.rb时,我确实得到了一个Makefile(在整个项目的根目录中),然后当

  2. ruby - 如何验证 IO.copy_stream 是否成功 - 2

    这里有一个很好的答案解释了如何在Ruby中下载文件而不将其加载到内存中:https://stackoverflow.com/a/29743394/4852737require'open-uri'download=open('http://example.com/image.png')IO.copy_stream(download,'~/image.png')我如何验证下载文件的IO.copy_stream调用是否真的成功——这意味着下载的文件与我打算下载的文件完全相同,而不是下载一半的损坏文件?documentation说IO.copy_stream返回它复制的字节数,但是当我还没有下

  3. ruby - 是否可以覆盖 gemfile 进行本地开发? - 2

    我们的git存储库中目前有一个Gemfile。但是,有一个gem我只在我的环境中本地使用(我的团队不使用它)。为了使用它,我必须将它添加到我们的Gemfile中,但每次我checkout到我们的master/dev主分支时,由于与跟踪的gemfile冲突,我必须删除它。我想要的是类似Gemfile.local的东西,它将继承从Gemfile导入的gems,但也允许在那里导入新的gems以供使用只有我的机器。此文件将在.gitignore中被忽略。这可能吗? 最佳答案 设置BUNDLE_GEMFILE环境变量:BUNDLE_GEMFI

  4. Ruby 文件 IO 定界符? - 2

    我正在尝试解析一个文本文件,该文件每行包含可变数量的单词和数字,如下所示:foo4.500bar3.001.33foobar如何读取由空格而不是换行符分隔的文件?有什么方法可以设置File("file.txt").foreach方法以使用空格而不是换行符作为分隔符? 最佳答案 接受的答案将slurp文件,这可能是大文本文件的问题。更好的解决方案是IO.foreach.它是惯用的,将按字符流式传输文件:File.foreach(filename,""){|string|putsstring}包含“thisisanexample”结果的

  5. Get https://registry-1.docker.io/v2/: net/http: request canceled while waiting - 2

    1.错误信息:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:requestcanceledwhilewaitingforconnection(Client.Timeoutexceededwhileawaitingheaders)或者:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:TLShandshaketimeout2.报错原因:docker使用的镜像网址默认为国外,下载容易超时,需要修改成国内镜像地址(首先阿里

  6. ruby - 为什么不能使用类IO的实例方法noecho? - 2

    print"Enteryourpassword:"pass=STDIN.noecho(&:gets)puts"Yourpasswordis#{pass}!"输出:Enteryourpassword:input.rb:2:in`':undefinedmethod`noecho'for#>(NoMethodError) 最佳答案 一开始require'io/console'后来的Ruby1.9.3 关于ruby-为什么不能使用类IO的实例方法noecho?,我们在StackOverflow上

  7. ruby - 在 Rails 项目中测试本地版本的 gem - 2

    我的Rails站点使用了一个确实不是很好的gem。每次我需要做一些新的事情时,我最终不得不花费与向实际Rails项目添加代码一样多的时间来为gem添加功能。但我不介意,我将我的Gemfile设置为指向我的gem的GitHub分支(我尝试提交PR,但维护者似乎已经下台)。问题是我真的没有找到一种合理的方法来测试我添加到gem的新东西。在railsc中测试它会特别好,但我能想到的唯一方法是a)更改~/.rvm/gems/.../foo。rb,这看起来不对或者b)升级版本,推送到Github,然后运行​​bundleup,这除了耗时之外显然是一场灾难,因为我不确定我所做的promise是否正

  8. Ruby 的数字方法性能 - 2

    我正在使用Ruby解决一些ProjectEuler问题,特别是这里我要讨论的问题25(Fibonacci数列中包含1000位数字的第一项的索引是多少?)。起初,我使用的是Ruby2.2.3,我将问题编码为:number=3a=1b=2whileb.to_s.length但后来我发现2.4.2版本有一个名为digits的方法,这正是我需要的。我转换为代码:whileb.digits.length当我比较这两种方法时,digits慢得多。时间./025/problem025.rb0.13s用户0.02s系统80%cpu0.190总计./025/problem025.rb2.19s用户0.0

  9. ruby - Ruby 性能中的计时器 - 2

    我正在寻找一个用ruby​​演示计时器的在线示例,并发现了下面的代码。它按预期工作,但这个简单的程序使用30Mo内存(如Windows任务管理器中所示)和太多CPU有意义吗?非常感谢deftime_blockstart_time=Time.nowThread.new{yield}Time.now-start_timeenddefrepeat_every(seconds)whiletruedotime_spent=time_block{yield}#Tohandle-vesleepinteravalsleep(seconds-time_spent)iftime_spent

  10. ruby-on-rails - 如果条件与 &&,是否有任何性能提升 - 2

    如果用户是所有者,我有一个条件来检查说删除和文章。delete_articleifuser.owner?另一种方式是user.owner?&&delete_article选择它有什么好处还是它只是一种写作风格 最佳答案 性能不太可能成为该声明的问题。第一个要好得多-它更容易阅读。您future的自己和其他将开始编写代码的人会为此感谢您。 关于ruby-on-rails-如果条件与&&,是否有任何性能提升,我们在StackOverflow上找到一个类似的问题:

随机推荐