2017-08-07 5 views
1

Y at-il un moyen d'améliorer la vitesse/performance de dessiner pixel par pixel dans un UIView?amélioration de la vitesse rapide dans UIView pixel par dessin pixel

L'implémentation actuelle d'un UIView 500x500 pixels est terriblement lente.

class CustomView: UIView { 

public var context = UIGraphicsGetCurrentContext() 

public var redvalues = [[CGFloat]](repeating: [CGFloat](repeating: 1.0, count: 500), count: 500) 

public var start = 0 
{ 
didSet{ 
    self.setNeedsDisplay() 
} 
} 

override func draw(_ rect: CGRect 
{ 
super.draw(rect) 
context = UIGraphicsGetCurrentContext() 
for yindex in 0...499{ 
    for xindex in 0...499 { 
     context?.setStrokeColor(UIColor(red: redvalues[xindex][yindex], green: 0.0, blue: 0.0, alpha: 1.0).cgColor) 

     context?.setLineWidth(2) 
     context?.beginPath() 
     context?.move(to: CGPoint(x: CGFloat(xindex), y: CGFloat(yindex))) 
     context?.addLine(to: CGPoint(x: CGFloat(xindex)+1.0, y: CGFloat(yindex))) 
     context?.strokePath() 
    } 
} 
} 
} 

Merci beaucoup

+1

Je voudrais essayer de créer une image à partir des valeurs, puis dessiner l'image – dan

Répondre

1

Lorsque le dessin des pixels individuels, vous pouvez utiliser a bitmap context. Un contexte bitmap prend les données brutes des pixels en entrée.

Le contexte copie vos données de pixels bruts pour que vous n'ayez pas à utiliser de chemins, qui sont probablement beaucoup plus lents. Vous pouvez ensuite obtenir un CGImage en utilisant context.makeImage().

L'image peut ensuite être utilisée dans une vue d'image, ce qui élimine le besoin de redessiner le tout à chaque image.

Si vous ne voulez pas créer manuellement un contexte bitmap, vous pouvez utiliser

UIGraphicsBeginImageContext(size) 
let context = UIGraphicsGetCurrentContext() 
// draw everything into the context 
let image = UIGraphicsGetImageFromCurrentImageContext() 
UIGraphicsEndImageContext() 

Ensuite, vous pouvez utiliser un UIImageView pour afficher l'image rendue.

Il est également possible de dessiner dans un CALayer, qui n'a pas besoin d'être redessiné à chaque image mais uniquement lors d'un redimensionnement.

+0

droite, ce sont les 250.000 chemins qui ralentissent les choses ici. Le système de dessin n'est simplement pas fait pour cela. C'est juste fou. Le titre de votre question fait référence au dessin au pixel, mais vous n'êtes pas un dessin au pixel près. Vous êtes en train de dessiner. Faites un dessin au pixel. Juste courir à travers un tampon de pixels et les définir, kaboom. – matt

+0

Merci beaucoup! J'ai maintenant essayé de le faire comme vieux moi. S'il vous plaît voir mon nouveau code, il est maintenant extrêmement rapide, mais la charge du processeur est également très élevé, avez-vous d'autres suggestions pour le rendre meilleur, ou est-ce la voie à suivre? – Manuel

0

Voilà à quoi cela ressemble maintenant, y a-t-il des optimisations possibles ou non?

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

public let imageview = UIImageView() 

override func viewDidLoad() { 

    super.viewDidLoad()   

    let width_input = 500 
    let height_input = 500 

    let redPixel = rgba(r:255, g:0, b:0, a:255) 
    let greenPixel = rgba(r:0, g:255, b:0, a:255) 
    let bluePixel = rgba(r:0, g:0, b:255, a:255 

    var pixelData = [rgba](repeating: redPixel, count: Int(width_input*height_input)) 

    pixelData[1] = greenPixel 
    pixelData[3] = bluePixel 

    self.view.addSubview(imageview) 

    imageview.frame = CGRect(x: 100,y: 100,width: 600,height: 600) 
    imageview.image = draw(pixel: pixelData,width: width_input,height: height_input) 
} 


func draw(pixel:[rgba],width:Int,height:Int) -> UIImage 
{ 
    let colorSpace = CGColorSpaceCreateDeviceRGB() 
    let data = UnsafeMutableRawPointer(mutating: pixel) 

    let bitmapContext = CGContext(data: data, 
            width: width, 
            height: height, 
            bitsPerComponent: 8, 
            bytesPerRow: 4*width, 
            space: colorSpace, 
            bitmapInfo: CGImageAlphaInfo.premultipliedLast.rawValue) 

    let image = bitmapContext?.makeImage() 
    return UIImage(cgImage: image!) 
} 
+0

L'avez-vous essayé dans un build de version et si oui, avez-vous encore des problèmes de performances? Si oui, vous pouvez essayer de décharger le travail dans un thread d'arrière-plan et définir uniquement la propriété d'image vues vues sur le thread principal. – Palle