2016-01-24 68 views
3

我對Swift非常陌生。我正在嘗試使用均值方法創建灰度濾鏡。在創建RGB圖像的灰度濾鏡時,執行在Swift中被中斷

這是我使用的RGBAImage.swift文件:

import UIKit 

public struct Pixel { 
    public var value: UInt32 

    public var red: UInt8 { 
     get { 
      return UInt8(value & 0xFF) 
     } 
     set { 
      value = UInt32(newValue) | (value & 0xFFFFFF00) 
     } 
    } 

    public var green: UInt8 { 
     get { 
      return UInt8((value >> 8) & 0xFF) 
     } 
     set { 
      value = (UInt32(newValue) << 8) | (value & 0xFFFF00FF) 
     } 
    } 

    public var blue: UInt8 { 
     get { 
      return UInt8((value >> 16) & 0xFF) 
     } 
     set { 
      value = (UInt32(newValue) << 16) | (value & 0xFF00FFFF) 
     } 
    } 

    public var alpha: UInt8 { 
     get { 
      return UInt8((value >> 24) & 0xFF) 
     } 
     set { 
      value = (UInt32(newValue) << 24) | (value & 0x00FFFFFF) 
     } 
    } 
} 

public struct RGBAImage { 
    public var pixels: UnsafeMutableBufferPointer<Pixel> 

    public var width: Int 
    public var height: Int 

    public init?(image: UIImage) { 
     guard let cgImage = image.CGImage else { return nil } 

     // Redraw image for correct pixel format 
     let colorSpace = CGColorSpaceCreateDeviceRGB() 

     var bitmapInfo: UInt32 = CGBitmapInfo.ByteOrder32Big.rawValue 
     bitmapInfo |= CGImageAlphaInfo.PremultipliedLast.rawValue & CGBitmapInfo.AlphaInfoMask.rawValue 

     width = Int(image.size.width) 
     height = Int(image.size.height) 
     let bytesPerRow = width * 4 

     let imageData = UnsafeMutablePointer<Pixel>.alloc(width * height) 

     guard let imageContext = CGBitmapContextCreate(imageData, width, height, 8, bytesPerRow, colorSpace, bitmapInfo) else { return nil } 
     CGContextDrawImage(imageContext, CGRect(origin: CGPointZero, size: image.size), cgImage) 

     pixels = UnsafeMutableBufferPointer<Pixel>(start: imageData, count: width * height) 
    } 

    public func toUIImage() -> UIImage? { 
     let colorSpace = CGColorSpaceCreateDeviceRGB() 
     var bitmapInfo: UInt32 = CGBitmapInfo.ByteOrder32Big.rawValue 
     bitmapInfo |= CGImageAlphaInfo.PremultipliedLast.rawValue & CGBitmapInfo.AlphaInfoMask.rawValue 

     let bytesPerRow = width * 4 

     let imageContext = CGBitmapContextCreateWithData(pixels.baseAddress, width, height, 8, bytesPerRow, colorSpace, bitmapInfo, nil, nil) 

     guard let cgImage = CGBitmapContextCreateImage(imageContext) else {return nil} 
     let image = UIImage(CGImage: cgImage) 

     return image 
    } 
} 

這是我的代碼:

import UIKit 

let image = UIImage(named: "sample")! 
let myRGBA = RGBAImage(image: image)! 

struct grayscale_mean_method { 
    var result: UIImage { 
     for y in 0..<myRGBA.height { 
      for x in 0..<myRGBA.width { 
       let index = y * myRGBA.width + x 
       var pixel = myRGBA.pixels[index] 
       let intensity = (pixel.blue + pixel.green + pixel.red)/3 
       let gray = UInt8(max(0,min(255, intensity))) 
       pixel.red = gray 
       pixel.green = gray 
       pixel.blue = gray 
       myRGBA.pixels[index] = pixel 
      } 
     } 
     return myRGBA.toUIImage()! 
    } 
} 

var newImage = grayscale_mean_method.init().result 

但我得到一個錯誤分配

let intensity = (pixel.blue + pixel.green + pixel.red)/3 

Execution was interrupted, reason = EXC_BAD_INSTRUCTION (code =EXC_l386_INVOP, subcode=0x0) 

時我搜索了但沒有找到解決方案。任何想法我做錯了什麼?

回答

2

let intensity = (pixel.blue + pixel.green + pixel.red)/3 

加入所有操作數具有類型UInt8,並增設 溢出(與運行時異常)如果結果不符合 成UInt8的範圍內。要解決此問題,請在計算平均值之前將所有值 轉換爲Int

let intensity = (Int(pixel.blue) + Int(pixel.green) + Int(pixel.red))/3