Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/codeigniter/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
SWIFT-UIImage(contentsOfFile:”比UIImage(imageLiteralResourceName:”慢)为什么?_Swift_Performance_Uiimage_Cpu_Draw - Fatal编程技术网

SWIFT-UIImage(contentsOfFile:”比UIImage(imageLiteralResourceName:”慢)为什么?

SWIFT-UIImage(contentsOfFile:”比UIImage(imageLiteralResourceName:”慢)为什么?,swift,performance,uiimage,cpu,draw,Swift,Performance,Uiimage,Cpu,Draw,当UIImage(contentsOfFile:)比UIImage(imageLiteralResourceName:)慢时,面临一个奇怪的问题。 override public func draw(in ctx: CGContext) { ... //here we draw this image... nothing special for _ in 0...99{ ctx.draw(img.cgImage!, in: randomPositionRect)

当UIImage(contentsOfFile:)比UIImage(imageLiteralResourceName:)慢时,面临一个奇怪的问题。

override public func draw(in ctx: CGContext) {
...

   //here we draw this image... nothing special
   for _ in 0...99{
      ctx.draw(img.cgImage!, in: randomPositionRect)
   }

...
}
在CALayer中,我有一个全局变量

let img:UIImage? = nil
…如果viewDidLoad使用“contentsOfFile”加载img,则它绘制此图像的速度非常慢。(例如在touchMove+刷新CPU时,低于99-100%和FPS 5-10)

但是。。。如果在viewDidLoad中,我使用“imageLiteralResourceName”或UIImage(数据:NSDATA)”加载相同的img,那么它工作得非常完美!CPU负载低,FPS40-60为什么

img = UIImage(cgImage: UIImage(imageLiteralResourceName: "line.png").cgImage!, scale: 2.0, orientation: UIImage.Orientation.up).cgImage
在屏幕上绘制100份此图像的代码:

override public func draw(in ctx: CGContext) {
...

   //here we draw this image... nothing special
   for _ in 0...99{
      ctx.draw(img.cgImage!, in: randomPositionRect)
   }

...
}
刷新屏幕:

  override public func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
    super.touchesMoved(touches, with: event)
    ....

    myLayer.setNeedsDisplay()
}
override public func touchsmoved(touch:Set,带有事件:UIEvent?){
super.touchesMoved(touches,with:event)
....
myLayer.setNeedsDisplay()文件
}
PS>在目标c中,它在两种情况下都能快速工作。仅使用SWIFT发行

全图代码:

var value = self.frame.size.height/2.0  //this value is changing in touchMove

override public func draw(in ctx: CGContext) {

    let height:CGFloat = self.frame.size.height-paddingTop!-paddingBottom!

    //rotate screen
    ctx.translateBy(x: +(frame.size.width / 2), y: +(frame.size.height / 2))
    ctx.rotate(by: degreesToRadians(x: 180))
    ctx.scaleBy(x: -1.0, y: 1.0)
    ctx.translateBy(x: -(frame.size.width / 2), y: -(frame.size.height / 2))

    ////
    ctx.translateBy(x: 0.0, y: 110)

    //Define the degrees needed for each plane to create a circle
    let degForPlane = Float(360.0 / CGFloat(panelsCount!))
    let radius: CGFloat = height / 2.0


    //The current angle offset (initially it is 0... it will change through the pan function)
    let vv: CGFloat = ((160.0 / frame.size.height) * (self.value)) + 10
    var degX: CGFloat = vv
    degX -= 90
    degX += 360

    /////DRAW Carousel ////

    let rect = CGRect(x: 0, y: 0 - (originalPanelSize!.height / 2.0), width: originalPanelSize!.width, height: originalPanelSize!.height)

    for i in 0...panelsCount!-1 {

        //Create the Matrix identity
        var t: CATransform3D = CATransform3DIdentity

        //Perform rotate on the matrix identity
        t = CATransform3DRotate(t, degreesToRadians(x: degX), 1.0, 0.0, 0.0)

        //Perform translate on the current transform matrix (identity + rotate)
        t = CATransform3DTranslate(t, 0.0, 0.0, radius)

        if i > -1 && ((degX >= -180 && degX <= 90) || (degX >= 270 && degX <= 450)) {
            let affine = CGAffineTransform(a: t.m11, b: t.m12, c: t.m21, d: t.m22, tx: t.m41, ty: t.m42)

            ctx.saveGState()
            ctx.concatenate(affine)


            ctx.draw(img!, in: rect)

            ctx.restoreGState()

        }

        degX -= CGFloat(degForPlane)

    }
}
var value=self.frame.size.height/2.0//此值在touchMove中更改
覆盖公共函数绘图(在ctx:CGContext中){
让高度:CGFloat=self.frame.size.height paddingTop!-paddingBottom!
//旋转筛
ctx.translateBy(x:+(frame.size.width/2),y:+(frame.size.height/2))
ctx.旋转(角度:度弧度(x:180))
ctx.scaleBy(x:-1.0,y:1.0)
ctx.translateBy(x:-(frame.size.width/2),y:-(frame.size.height/2))
////
ctx.translateBy(x:0.0,y:110)
//定义每个平面创建圆所需的度数
让degForPlane=浮动(360.0/CGFloat(PanelScont!))
允许半径:CGFloat=高度/2.0
//当前角度偏移(最初为0…将通过平移功能更改)
设vv:CGFloat=((160.0/帧大小.高度)*(self.value))+10
var degX:CGFloat=vv
degX-=90
degX+=360
/////牵引转盘////
设rect=CGRect(x:0,y:0-(originalPanelSize!.height/2.0),width:originalPanelSize!。width,height:originalPanelSize!.height)
因为我在0…PanelScont!-1{
//创建矩阵标识
变量t:CATTransferM3D=CATTransferM3D实体
//对矩阵恒等式执行旋转
t=CATTransferorm3drotate(t,度弧度(x:degX),1.0,0.0,0.0)
//对当前变换矩阵执行平移(标识+旋转)
t=CATTransformerM3D传输(t,0.0,0.0,半径)

如果i>-1&&((degX>=-180&°X=270&°X我目前的解决方案是使用通过NSData加载图像的自定义扩展:

创建文件UIImage+ext.swift

import Foundation
import UIKit

extension UIImage{

static func fromFile (path:String)->UIImage? {

    if let data = NSData(contentsOfFile: path) {
        return UIImage(cgImage: UIImage(data: data as Data)!.cgImage!, scale: UIScreen.main.scale, orientation: UIImage.Orientation.up)
    }

    return nil
}
}

使用:


请显示整个绘图代码。如果您在
draw
函数中加载图像,则说明您做得不对。也不需要访问
CGImage
来绘制图像。另外请注意,这两种方法不太可能加载相同的图像,因为
contentsOfFile:
实际上不会加载带有corr的图像ect比例。没问题。添加了完整的ctx.draw代码。我正在viewDidLoad()中加载img。UIImage(imageLiteralResourceName:)
UIImage(命名:)
都在缓存加载的图像,因此第二次加载时应该总是更快。创建-有趣,到目前为止,我看这两种方法没有区别。您有什么Xcode和iOS版本?为什么要将
UIImage
转换为
cgImage
,以便立即转换为
UIImage
?其他WIse,带有视网膜的屏幕上的图像看起来很差。比例将是1.0而不是2.0。您可以将比例设置为第二个参数:或者,您可以只在图像文件名中添加
@2x
。或者将图像放在
资产.xcsets
并在那里设置其比例。什么?只需将您拥有的文件添加
@2x
。不要再添加两个文件,只需更改现有文件的名称。如果您到处指定
scale:2.0
,它们肯定是
@2x
图像。只需让系统知道它,而不是让它认为它是
@1x
,然后手动重新缩放它。
let img = UIImage.fromFile(path: "MyFoler1/MyFolder2/File.png")