Reputation: 8608
I'm iterating through an array of UIImages
that all need to be rotated by 90 degrees. This works...sometimes.
I'll randomly get a case where 2 or 3 of the images failed to rotate but I can't consistently reproduce so debugging has been troublesome.
Here is how I'm looping through my array:
func processPhotosForRotation(completion:() -> Void) {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)) {
for (index,image) in self.frameImages.enumerate() {
let flippedImage = image.imageRotatedByDegrees(90, flip: false)
self.frameImages[index] = flippedImage
}
//I need the images forwards, then backwards
self.frameImages.appendContentsOf(self.frameImages.reverse())
dispatch_async(dispatch_get_main_queue()) {
completion()
}
}
}
Here is how I'm rotating the images:
extension UIImage {
public func imageRotatedByDegrees(degrees: CGFloat, flip: Bool) -> UIImage {
let degreesToRadians: (CGFloat) -> CGFloat = {
return $0 / 180.0 * CGFloat(M_PI)
}
// calculate the size of the rotated view's containing box for our drawing space
let rotatedViewBox = UIView(frame: CGRect(origin: CGPointZero, size: size))
let t = CGAffineTransformMakeRotation(degreesToRadians(degrees));
rotatedViewBox.transform = t
let rotatedSize = rotatedViewBox.frame.size
// Create the bitmap context
UIGraphicsBeginImageContext(rotatedSize)
let bitmap = UIGraphicsGetCurrentContext()
// Move the origin to the middle of the image so we will rotate and scale around the center.
CGContextTranslateCTM(bitmap, rotatedSize.width / 2.0, rotatedSize.height / 2.0);
// // Rotate the image context
CGContextRotateCTM(bitmap, degreesToRadians(degrees));
// Now, draw the rotated/scaled image into the context
var yFlip: CGFloat
if(flip){
yFlip = CGFloat(-1.0)
} else {
yFlip = CGFloat(1.0)
}
CGContextScaleCTM(bitmap, yFlip, -1.0)
CGContextDrawImage(bitmap, CGRectMake(-size.width / 2, -size.height / 2, size.width, size.height), CGImage)
let newImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return newImage
}
}
Like I said, for ever 1-3 times it works perfectly, then every now and then a few images won't be rotated.
I've tried iterating through the array checking the image.imageOrientation
. Which returns the same results Up
, even if it's not Up
.
Upvotes: 0
Views: 49
Reputation: 114836
You are mutating the array from multiple threads at the same time as you are enumerating it. Access to an array is not thread safe so sometimes the change made by one thread is overwritten by another thread.
You should store your update image references in a temporary arrays and assign this to your property when you are done. This will avoid modifying the array as it is enumerated.
I also recommend that the updates to the temporary array are dispatched synchronously on a serial queue to avoid concurrent updates.
Upvotes: 1