2016-09-29 101 views
0

在我的swift項目中,我有兩個類一起工作,以保持圖像的像素值能夠修改紅色,綠色,藍色和alpha值。 UnsafeMutableBufferPointer包含大量由Pixel類對象組成的小部件。主題1:EXC_BAD_ACCESS(code = EXC_I386_GPFLT)

我可以與持有UnsafeMutableBufferPointer<Pixel>屬性的類進行交互。我可以訪問該對象上的所有屬性,並且一切正常。我在UnsafeMutableBufferPoint<Pixel>上遇到的唯一問題是嘗試通過Pixel對象循環播放它,並且它一直與Thread 1:EXC_BAD_ACCESS (code=EXC_I386_GPFLT)異常一起崩潰。

init!(image: UIImage) 
{ 
    _width = Int(image.size.width) 
    _height = Int(image.size.height) 

    guard let cgImage = image.cgImage else { return nil } 

    _width = Int(image.size.width) 
    _height = Int(image.size.height) 
    let bitsPerComponent = 8 

    let bytesPerPixel = 4 
    let bytesPerRow = _width * bytesPerPixel 
    let imageData = UnsafeMutablePointer<Pixel>.allocate(capacity: _width * _height) 
    let colorSpace = CGColorSpaceCreateDeviceRGB() 

    var bitmapInfo: UInt32 = CGBitmapInfo.byteOrder32Big.rawValue 
    bitmapInfo |= CGImageAlphaInfo.premultipliedLast.rawValue & CGBitmapInfo.alphaInfoMask.rawValue 
    guard let imageContext = CGContext(data: imageData, width: _width, height: _height, bitsPerComponent: bitsPerComponent, bytesPerRow: bytesPerRow, space: colorSpace, bitmapInfo: bitmapInfo) else { return nil } 
    imageContext.draw(cgImage, in: CGRect(origin: CGPoint.zero, size: image.size)) 

    _pixels = UnsafeMutableBufferPointer<Pixel>(start: imageData, count: _width * _height) 
} 

此功能是崩潰程序的部分。崩潰的確切部分是循環遍歷rgba.pixels的for循環。 rgba.pixels是UnsafeMutableBufferPointer。

​​

這是我創建UnsafeMutableBufferPointer<Pixel>的構造函數。有沒有更簡單的方法來做到這一點,仍然能夠獲得RBGA值並輕鬆更改它們。

Pixel類是一個UInt32值,它被分成四個UInt 8值。

我是否使用錯誤的構造來保存這些值,如果有的話,是否有更安全或更容易使用的構造?或者當我在訪問像素值時做錯了什麼?

回答

0

我這是怎麼了圖像的像素 -

// Grab and set up variables for the original image 
    let inputCGImage = inputImage.CGImage 
    let inputWidth: Int = CGImageGetWidth(inputCGImage) 
    let inputHeight: Int = CGImageGetHeight(inputCGImage) 

    // Get the colorspace that will be used for image processing (RGB/HSV) 
    let colorSpace: CGColorSpaceRef = CGColorSpaceCreateDeviceRGB()! 

    // Hardcode memory variables 
    let bytesPerPixel = 4 // 32 bits = 4 bytes 
    let bitsPerComponent = 8 // 32 bits div. by 4 components (RGBA) = 8 bits per component 
    let inputBytesPerRow = bytesPerPixel * inputWidth 

    // Get a pointer pointing to an allocated array to hold all the pixel data of the image 
    let inputPixels = UnsafeMutablePointer<UInt32>(calloc(inputHeight * inputWidth, sizeof(UInt32))) 

    // Create a context to draw the original image in (aka put the pixel data into the above array) 
    let context: CGContextRef = CGBitmapContextCreate(inputPixels, inputWidth, inputHeight, bitsPerComponent, inputBytesPerRow, colorSpace, CGImageAlphaInfo.PremultipliedLast.rawValue | CGBitmapInfo.ByteOrder32Big.rawValue)! 

    CGContextDrawImage(context, CGRect(x: 0, y: 0, width: inputWidth, height: inputHeight), inputCGImage) 

請記住,這不是斯威夫特3語法櫃面這就是你使用的是什麼,但是這是基本的算法。我們抓住每一個像素的個別顏色值,你將不得不實現這些功能 -

func Mask8(x: UInt32) -> UInt32 
{ 
    return x & 0xFF 
} 

func R(x: UInt32) -> UInt32 
{ 
    return Mask8(x) 
} 

func G(x: UInt32) -> UInt32 
{ 
    return Mask8(x >> 8) 
} 

func B(x: UInt32) -> UInt32 
{ 
    return Mask8(x >> 16) 
} 

func A(x: UInt32) -> UInt32 
{ 
    return Mask8(x >> 24) 
} 

要處理的RGBA值之後創建一個完全新的顏色,您可以使用此功能 -

func RGBAMake(r: UInt32, g: UInt32, b: UInt32, a: UInt32) -> UInt32 
{ 
    return (Mask8(r) | Mask8(g) << 8 | Mask8(b) << 16 | Mask8(a) << 24) 
} 

爲了遍歷像素數組,你這樣做 -

var currentPixel = inputPixels 
for _ in 0..<height 
    { 
     for i in 0..<width 
     { 
      let color: UInt32 = currentPixel.memory 
      if i < width - 1 
      { 
       print(NSString(format: "%3.0f", R(x: color), terminator: " ")) 
      } 
      else 
      { 
       print(NSString(format: "%3.0f", R(x: color))) 
      } 
      currentPixel += 1 
     } 
    } 
相關問題