2016-12-09 10 views
0

私はスウィフトでディザリング機能を作成しようとしていましたが、問題は続いています。私が選択したランダムな画像の最初の9000ピクセルほどでコードループがうまくいくことに気付きました。しかし、それは私にランタイムエラーを与える、私はどこでも見てきたと私は問題を解決するように見えることはできません。助けてください。EXC_BAD_INSTRUCTIONスウィフトディザリング機能

file:///Users/jeffn/Desktop/MyPlayground34.playground/:エラー:再生が中断されました:エラー:実行が中断されました。理由:EXC_BAD_INSTRUCTION(コード= EXC_I386_INVOP、サブコード= 0x0)。 プロセスが中断された時点でプロセスが放置されました。「thread return -x」を使用して、式の評価前の状態に戻ります。

import UIKit 





struct Pixel { 
var value: UInt32 
var red: UInt8 { 
    get { return UInt8(value & 0xFF) } 
    set { value = UInt32(newValue) | (value & 0xFFFFFF00) } 
} 
var green: UInt8 { 
    get { return UInt8((value >> 8) & 0xFF) } 
    set { value = (UInt32(newValue) << 8) | (value & 0xFFFF00FF) } 
} 
var blue: UInt8 { 
    get { return UInt8((value >> 16) & 0xFF) } 
    set { value = (UInt32(newValue) << 16) | (value & 0xFF00FFFF) } 
} 
var alpha: UInt8 { 
    get { return UInt8((value >> 24) & 0xFF) } 
    set { value = (UInt32(newValue) << 24) | (value & 0x00FFFFFF) } 
}} 

public struct RGBA { 
var pixels: UnsafeMutableBufferPointer<Pixel> 
var width: Int 
var height: Int 

init?(image: UIImage) { 
    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(x: 0,y :0), size: image.size)) 
    pixels = UnsafeMutableBufferPointer<Pixel>(start: imageData, count: width * height) 
} 

public func toUIImage() -> UIImage? { 
    let bitsPerComponent = 8 
    let bytesPerPixel = 4 
    let bytesPerRow = width * bytesPerPixel 
    let colorSpace = CGColorSpaceCreateDeviceRGB() 
    var bitmapInfo: UInt32 = CGBitmapInfo.byteOrder32Big.rawValue 
    bitmapInfo |= CGImageAlphaInfo.premultipliedLast.rawValue & CGBitmapInfo.alphaInfoMask.rawValue 
    let imageContext = CGContext(data: pixels.baseAddress, width: width, height: height, bitsPerComponent: bitsPerComponent, bytesPerRow: bytesPerRow, space: colorSpace, bitmapInfo: bitmapInfo, releaseCallback: nil, releaseInfo: nil) 
    guard let cgImage = imageContext!.makeImage() else {return nil} 
    let image = UIImage(cgImage: cgImage) 
    return image 
} 
} 

public func contrast(image: UIImage) -> RGBA { 
let rgba = RGBA(image: image)! 

var new_red: UInt8 = 0 
var new_green = 0 
var new_blue = 0 
var new_alpha = 0 

var error_red: UInt8 = 0 
var error_green = 0 
var error_blue = 0 
var error_alpha = 0 

var pixel_1_red: UInt8 = 0 

var output_red: UInt8 = 0 

let w1: Double = 7.00/16.00 
let w2: Double = 3.00/16.00 
let w3: Double = 5.00/16.00 
let w4: Double = 1.00/16.00 


for y in 0..<rgba.height-1{ 
    for x in 0..<rgba.width-1{ 
     var index = y * rgba.width + x 
     var index_1 = y*rgba.width + x + 1 

     var pixel = rgba.pixels[index] 
     var pixel_1 = rgba.pixels[index_1] 
     pixel_1_red = pixel_1.red 



     if(pixel.red < 128){new_red = 0} else {new_red = 255} 
     error_red = new_red - pixel.red 


     var double_error_red = Double(error_red)*w1 
     var int_error_red = UInt8(double_error_red) 

     output_red = pixel_1_red + int_error_red 


     pixel_1.red = output_red 
     rgba.pixels[index_1] = pixel_1 


    } 
} 

return rgba 
} 




let image = UIImage(named: "newlowpassfilter.jpg")! 
let rgba = contrast(image: image) 
let newImage = rgba.toUIImage() 
image 

newImage 
+0

エラーの原因となるのは、どのラインですか? – rmaddy

+0

コントラスト機能を使用する行。 – jnaljo1

答えて

0

多分整数オーバーフローが問題です。私のサンプルのjpg - 画像の一つとテストと

、この行はオーバーフローを引き起こした:

output_red = pixel_1_red + int_error_red 

あなたはこのような何かに行を変更する必要があるかもしれません:スウィフトで

let temp_red = Int(pixel_1_red) + Int(int_error_red) 
output_red = temp_red > 255 ? 255 : UInt8(temp_red) 

+オペレータがオーバーフローを検出してアプリクラッシュを引き起こし、オーバフロー無視のオペレータ&+は画像処理に適していません。コード内の各操作の結果範囲に注意する必要があります。

+0

私はそのようなものを試しましたが、9500回のループの後にアプリケーションがクラッシュします。奇妙な。 – jnaljo1

+0

@ jnaljo1、あなたの実際のコードと実際のイメージを見ることなく、もう言い難いです。あなたのテストイメージをどこかに公開してWeb上に公開できますか? – OOPer

+0

。テスト画像。ここにURLがあります。 https://www.petinsurance.com/images/dog-bone.png – jnaljo1

関連する問題