Reputation: 415
I'm drawing a colorWheel in my app. I do this by generating a CGImage in a separate function and using CGContextDrawImage in drawRect to put it onscreen.
On the initial presentation it looks fine, but after I call setNeedsDisplay (or setNeedsDisplayInRect) the image turns black/distorted. I must be doing something stupid, but can't see what.
DrawRect code looks like:
override func drawRect(rect: CGRect) {
if let context = UIGraphicsGetCurrentContext() {
let wheelFrame = CGRectMake(0,0,circleRadius*2,circleRadius*2)
CGContextSaveGState(context)
//create clipping mask for circular wheel
CGContextAddEllipseInRect(context, wheelFrame)
CGContextClip(context)
//draw the wheel
if colorWheelImage != nil { CGContextDrawImage(context, CGRectMake(0,0,circleRadius*2,circleRadius*2), colorWheelImage) }
CGContextRestoreGState(context)
//draw a selector element
self.drawSliderElement(context)
}
}
CGimage generation function:
func generateColorWheelImage() {
let width = Int(circleRadius*2)
let height = Int(circleRadius*2)
var pixels = [PixelData]()
for yIndex in 0..<width {
for xIndex in 0..<height {
pixels.append(colorAtPoint(CGPoint(x: xIndex, y: yIndex)))
}
}
let rgbColorSpace = CGColorSpaceCreateDeviceRGB()
let bitmapInfo = CGBitmapInfo.ByteOrderDefault
let bitsPerComponent: Int = 8
let bitsPerPixel: Int = 24
let renderingIntent = CGColorRenderingIntent.RenderingIntentDefault
assert(pixels.count == Int(width * height))
var data = pixels
let providerRef = CGDataProviderCreateWithData(nil, data, data.count * sizeof(PixelData), nil)
colorWheelImage = CGImageCreate(width, height, bitsPerComponent, bitsPerPixel, width * Int(sizeof(PixelData)), rgbColorSpace, bitmapInfo, providerRef, nil, true,renderingIntent)
}
Upvotes: 2
Views: 129
Reputation: 415
I finally found the answer (here: https://stackoverflow.com/a/10798750/5233176) to this problem when I started running the code on ipad rather than simulator and received a BAD_ACCESS_ERROR, rather seeing a distorted image.
As the answer explains: '[The] CMSampleBuffer is used directly to create a CGImageRef, so [the] CGImageRef will become invalid once the buffer is released.'
Hence the problem was with this line:
let providerRef = CGDataProviderCreateWithData(nil, data, data.count * sizeof(PixelData), nil)
And the problem can be fixed by using a copy of the buffer, like so:
let providerData = NSData(bytes: data, length: data.count * sizeof(PixelData))
let provider = CGDataProviderCreateWithCFData(providerData)
Upvotes: 0