草庐IT

ios - 在 Swift 中绘制图像需要很长时间

coder 2023-07-16 原文

在我的应用程序中,我正在创建一个图像映射 float 到一个像素值,并将其用作 Google map 上的叠加层,但这需要很长时间才能完成,同样的事情在 Android 中几乎是即时的。我的代码如下所示:

private func imageFromPixels(pixels: [PixelData], width: Int, height: Int) -> UIImage? {

    let bitsPerComponent = 8
    let bitsPerPixel = bitsPerComponent * 4
    let bytesPerRow = bitsPerPixel * width / 8

    let providerRef = CGDataProvider(
        data: NSData(bytes: pixels, length: height * width * 4) 
    )

    let cgimage = CGImage(
        width: width,
        height: height,
        bitsPerComponent: bitsPerComponent,
        bitsPerPixel: bitsPerPixel,
        bytesPerRow: bytesPerRow,
        space: CGColorSpaceCreateDeviceRGB(),
        bitmapInfo: CGBitmapInfo(rawValue: CGImageAlphaInfo.premultipliedFirst.rawValue),
        provider: providerRef!,
        decode: nil,
        shouldInterpolate: true,
        intent: .defaultIntent
    )

    if cgimage == nil {
        print("CGImage is not supposed to be nil")
        return nil
    }
    return UIImage(cgImage: cgimage!)
}

关于这怎么会花这么长时间,有什么建议吗?我可以看到它使用了大约 96% 的 CPU 功率。

func fromData(pair: AllocationPair) -> UIImage? {

    let table = pair.table
    let data = pair.data

    prepareColors(allocations: table.allocations)

    let height = data.count
    let width = data[0].count

    var colors = [PixelData]()

    for row in data {
        for val in row {

            if (val == 0.0) {
                colors.append(PixelData(a: 0, r: 0, g: 0, b: 0))
                continue
            }

            if let interval = findInterval(table: table, value: val) {
                if let color = intervalColorDict[interval] {
                    colors.append(PixelData(a: color.a, r: color.r, g: color.g, b: color.b))
                } 
            }
        }
    }

    return imageFromPixels(pixels: colors, width: width, height: height)
}

我已经尝试对它进行时间分析,这是需要时间的输出。

最佳答案

我尝试了您的代码,发现问题不在于您的函数。

我认为您应该使用基于 UInt8 的像素结构,而不是基于 CGFloat 的结构。

我为一个 Cocoa 应用程序翻译了您的代码,结果如下:

public struct PixelData {
    var a: UInt8
    var r: UInt8
    var g: UInt8
    var b: UInt8
}

func imageFromPixels(pixels: [PixelData], width: Int, height: Int) -> NSImage? {

    let bitsPerComponent = 8
    let bitsPerPixel = bitsPerComponent * 4
    let bytesPerRow = bitsPerPixel * width / 8

    let providerRef = CGDataProvider(
        data: NSData(bytes: pixels, length: height * width * 4)
    )

    let cgimage = CGImage(
        width: width,
        height: height,
        bitsPerComponent: bitsPerComponent,
        bitsPerPixel: bitsPerPixel,
        bytesPerRow: bytesPerRow,
        space: CGColorSpaceCreateDeviceRGB(),
        bitmapInfo: CGBitmapInfo(rawValue: CGImageAlphaInfo.premultipliedFirst.rawValue),
        provider: providerRef!,
        decode: nil,
        shouldInterpolate: true,
        intent: .defaultIntent
    )

    if cgimage == nil {
        print("CGImage is not supposed to be nil")
        return nil
    }
    return NSImage(cgImage: cgimage!, size: NSSize(width: width, height: height))
}

var img = [PixelData]()

for i: UInt8 in 0 ..< 20 {
    for j: UInt8 in 0 ..< 20 {
        // Creating a red 20x20 image.
        img.append(PixelData(a: 255, r: 255, g: 0, b: 0))
    }
}

var ns = imageFromPixels(pixels: img, width: 20, height: 20)

此代码快速且轻便,这是调试系统影响值:

我认为问题出在加载像素数据的部分,检查它并确保它正常工作。

关于ios - 在 Swift 中绘制图像需要很长时间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42353250/

有关ios - 在 Swift 中绘制图像需要很长时间的更多相关文章

  1. ruby - 我需要将 Bundler 本身添加到 Gemfile 中吗? - 2

    当我使用Bundler时,是否需要在我的Gemfile中将其列为依赖项?毕竟,我的代码中有些地方需要它。例如,当我进行Bundler设置时:require"bundler/setup" 最佳答案 没有。您可以尝试,但首先您必须用鞋带将自己抬离地面。 关于ruby-我需要将Bundler本身添加到Gemfile中吗?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/4758609/

  2. ruby - rspec 需要 .rspec 文件中的 spec_helper - 2

    我注意到像bundler这样的项目在每个specfile中执行requirespec_helper我还注意到rspec使用选项--require,它允许您在引导rspec时要求一个文件。您还可以将其添加到.rspec文件中,因此只要您运行不带参数的rspec就会添加它。使用上述方法有什么缺点可以解释为什么像bundler这样的项目选择在每个规范文件中都需要spec_helper吗? 最佳答案 我不在Bundler上工作,所以我不能直接谈论他们的做法。并非所有项目都checkin.rspec文件。原因是这个文件,通常按照当前的惯例,只

  3. ruby - 如何在 Lion 上安装 Xcode 4.6,需要用 RVM 升级 ruby - 2

    我实际上是在尝试使用RVM在我的OSX10.7.5上更新ruby,并在输入以下命令后:rvminstallruby我得到了以下回复:Searchingforbinaryrubies,thismighttakesometime.Checkingrequirementsforosx.Installingrequirementsforosx.Updatingsystem.......Errorrunning'requirements_osx_brew_update_systemruby-2.0.0-p247',pleaseread/Users/username/.rvm/log/138121

  4. 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返回它复制的字节数,但是当我还没有下

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

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

  6. ruby-on-rails - 添加回形针新样式不影响旧上传的图像 - 2

    我有带有Logo图像的公司模型has_attached_file:logo我用他们的Logo创建了许多公司。现在,我需要添加新样式has_attached_file:logo,:styles=>{:small=>"30x15>",:medium=>"155x85>"}我是否应该重新上传所有旧数据以重新生成新样式?我不这么认为……或者有什么rake任务可以重新生成样式吗? 最佳答案 参见Thumbnail-Generation.如果rake任务不适合你,你应该能够在控制台中使用一个片段来调用重新处理!关于相关公司

  7. ruby - 为什么在 ruby​​ 中创建 Rational 不需要新方法 - 2

    这个问题在这里已经有了答案:关闭10年前。PossibleDuplicate:Rubysyntaxquestion:Rational(a,b)andRational.new!(a,b)我正在阅读ruby镐书,我对创建有理数的语法感到困惑。Rational(3,4)*Rational(1,2)产生=>3/8为什么Rational不需要new方法(我还注意到例如我可以在没有new方法的情况下创建字符串)?

  8. 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使用的镜像网址默认为国外,下载容易超时,需要修改成国内镜像地址(首先阿里

  9. ruby-on-rails - 在 Ruby (on Rails) 中使用 imgur API 获取图像 - 2

    我正在尝试使用Ruby2.0.0和Rails4.0.0提供的API从imgur中提取图像。我已尝试按照Ruby2.0.0文档中列出的各种方式构建http请求,但均无济于事。代码如下:require'net/http'require'net/https'defimgurheaders={"Authorization"=>"Client-ID"+my_client_id}path="/3/gallery/image/#{img_id}.json"uri=URI("https://api.imgur.com"+path)request,data=Net::HTTP::Get.new(path

  10. python ffmpeg 使用 pyav 转换 一组图像 到 视频 - 2

    2022/8/4更新支持加入水印水印必须包含透明图像,并且水印图像大小要等于原图像的大小pythonconvert_image_to_video.py-f30-mwatermark.pngim_dirout.mkv2022/6/21更新让命令行参数更加易用新的命令行使用方法pythonconvert_image_to_video.py-f30im_dirout.mkvFFMPEG命令行转换一组JPG图像到视频时,是将这组图像视为MJPG流。我需要转换一组PNG图像到视频,FFMPEG就不认了。pyav内置了ffmpeg库,不需要系统带有ffmpeg工具因此我使用ffmpeg的python包装p

随机推荐