2017-04-23 7 views
0

私は、イメージのピクセルを数えてイメージ内の5つの色の相対的な領域を取得するアプリケーションを持っています。更新されたSwift 3のバージョンは、アプリケーションのサポートファイルにある宣言されたイメージで動作しますが、ドキュメントディレクトリからの可変イメージでは動作しません。私は何が欠けていますか?Swiftのピクセルカウント3

このバージョンでは動作します:

import UIKit 
import CoreGraphics 

class ComputeAreaViewController: UIViewController { 

var redValue: String! 
var blueValue: String! 
var greenValue: String! 
var whiteValue: String! 
var yellowValue: String! 
var totalValue: String! 

//var image: UIImage! 

let image = UIImage(named: "test_image.png")! 

override func viewDidLoad() { 
    super.viewDidLoad() 

    /* 
    let fm = FileManager.default 
    let docsurl = try! fm.url(for: .documentDirectory, in:  .userDomainMask, appropriateFor: nil, create: false) 
    let myurl = docsurl.appendingPathComponent("tmp.png") 
    image = UIImage(contentsOfFile: myurl.path)! 
    */ 

    view.layer.contents = image.cgImage! 

    computeArea() 
} 

func classifyPixel(_ r: UInt8, _ g: UInt8, _ b: UInt8, _ coverRed: inout UInt, _ coverGreen: inout UInt, _ coverYellow: inout UInt, _ coverBlue: inout UInt, _ coverWhite: inout UInt) { 
    if r == 255 && g == 0 && b == 0 { coverRed += 1 } 
    if r == 0 && g == 255 && b == 0 { coverGreen += 1 } 
    if r == 255 && g == 255 && b == 0 { coverYellow += 1 } 
    if r == 0 && g == 0 && b == 255 { coverBlue += 1 } 
    if r == 255 && g == 255 && b == 255 { coverWhite += 1 } 
} 

func computeArea() { 

    var coverRed: UInt = 0 
    var coverGreen: UInt = 0 
    var coverYellow: UInt = 0 
    var coverBlue: UInt = 0 
    var coverWhite: UInt = 0 
    var coverTotal = 0 

    let imageWidth = Int(image.size.width) 
    let imageHeight = Int(image.size.height) 

    let bitsPerComponent = 8 
    let bytesPerPixel = 4 
    let bytesPerRow = bytesPerPixel * imageWidth 

    let bufferSize = bytesPerRow * imageHeight 
    var bytesPointer = UnsafeMutableRawPointer.allocate(bytes: bufferSize, alignedTo: 1) 
    let bytesPointerSaved = bytesPointer 

    if let bitmapContext = CGContext(data: bytesPointer, width: imageWidth, height: imageHeight, bitsPerComponent: bitsPerComponent, bytesPerRow: bytesPerRow, space: CGColorSpaceCreateDeviceRGB(), bitmapInfo: CGImageAlphaInfo.premultipliedLast.rawValue) { 

     bitmapContext.draw((image.cgImage!), in: CGRect(x: 0, y: 0, width: imageWidth, height: imageHeight), byTiling: false) 

     for _ in 0..<imageHeight { 
      for _ in 0..<imageWidth { 
       var r: UInt8 = 0, g: UInt8 = 0, b: UInt8 = 0 
       r = bytesPointer.load(as: UInt8.self) 
       bytesPointer += 1 
       g = bytesPointer.load(as: UInt8.self) 
       bytesPointer += 1 
       b = bytesPointer.load(as: UInt8.self) 
       bytesPointer += 2 
       classifyPixel(r, g, b, &coverRed, &coverGreen, &coverYellow, &coverBlue, &coverWhite) 
       coverTotal += 1 
      } 
     } 

    } else { 
     print(#file + " " + #function + " failed to create bitmap context ") 
    } 
    bytesPointerSaved.deallocate(bytes: bufferSize, alignedTo: 1) 
    let fTotal = Float(coverTotal) 
    print("coverRed: \(100.0*Float(coverRed)/fTotal), coverGreen: \ (100.0*Float(coverGreen)/fTotal), coverYellow: \(100.0*Float(coverYellow)/fTotal), coverBlue: \(100.0*Float(coverBlue)/fTotal), coverWhite: \(100.0*Float(coverWhite)/fTotal), coverTotal: \(coverTotal), #ofPixels: \(bufferSize/bytesPerPixel)") 

    greenValue = String(describing: (100.0*Float(coverGreen)/fTotal)) 
    yellowValue = String(describing: (100.0*Float(coverYellow)/fTotal)) 
    redValue = String(describing: (100.0*Float(coverRed)/fTotal)) 
    blueValue = String(describing: (100.0*Float(coverBlue)/fTotal)) 
    whiteValue = String(describing: (100.0*Float(coverWhite)/fTotal)) 
} 

override func didReceiveMemoryWarning() { 
    super.didReceiveMemoryWarning() 
} 

override func prepare(for segue: UIStoryboardSegue, sender: Any?) { 

    if segue.identifier == "computeResult" { 

     let areaController = segue.destination as! AreaPercentViewController 
     areaController.redValue = redValue 
     areaController.blueValue = blueValue 
     areaController.greenValue = greenValue 
     areaController.whiteValue = whiteValue 
     areaController.yellowValue = yellowValue 
     areaController.totalValue = totalValue 
    } 
} 
} 

このバージョンでは動作しません:

import UIKit 
import CoreGraphics 

class ComputeAreaViewController: UIViewController { 

var redValue: String! 
var blueValue: String! 
var greenValue: String! 
var whiteValue: String! 
var yellowValue: String! 
var totalValue: String! 

var image: UIImage! 

//let image = UIImage(named: "test_image.png")! 

override func viewDidLoad() { 
    super.viewDidLoad() 

    let fm = FileManager.default 
    let docsurl = try! fm.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false) 
    let myurl = docsurl.appendingPathComponent("tmp.png") 
    image = UIImage(contentsOfFile: myurl.path)! 

    view.layer.contents = image.cgImage! 

    computeArea() 
} 

func classifyPixel(_ r: UInt8, _ g: UInt8, _ b: UInt8, _ coverRed: inout UInt, _ coverGreen: inout UInt, _ coverYellow: inout UInt, _ coverBlue: inout UInt, _ coverWhite: inout UInt) { 
    if r == 255 && g == 0 && b == 0 { coverRed += 1 } 
    if r == 0 && g == 255 && b == 0 { coverGreen += 1 } 
    if r == 255 && g == 255 && b == 0 { coverYellow += 1 } 
    if r == 0 && g == 0 && b == 255 { coverBlue += 1 } 
    if r == 255 && g == 255 && b == 255 { coverWhite += 1 } 
} 

func computeArea() { 

    var coverRed: UInt = 0 
    var coverGreen: UInt = 0 
    var coverYellow: UInt = 0 
    var coverBlue: UInt = 0 
    var coverWhite: UInt = 0 
    var coverTotal = 0 

    let imageWidth = Int(image.size.width) 
    let imageHeight = Int(image.size.height) 

    let bitsPerComponent = 8 
    let bytesPerPixel = 4 
    let bytesPerRow = bytesPerPixel * imageWidth 

    let bufferSize = bytesPerRow * imageHeight 
    var bytesPointer = UnsafeMutableRawPointer.allocate(bytes: bufferSize, alignedTo: 1) 
    let bytesPointerSaved = bytesPointer 

    if let bitmapContext = CGContext(data: bytesPointer, width: imageWidth, height: imageHeight, bitsPerComponent: bitsPerComponent, bytesPerRow: bytesPerRow, space: CGColorSpaceCreateDeviceRGB(), bitmapInfo: CGImageAlphaInfo.premultipliedLast.rawValue) { 

     bitmapContext.draw((image.cgImage!), in: CGRect(x: 0, y: 0, width: imageWidth, height: imageHeight), byTiling: false) 

     for _ in 0..<imageHeight { 
      for _ in 0..<imageWidth { 
       var r: UInt8 = 0, g: UInt8 = 0, b: UInt8 = 0 
       r = bytesPointer.load(as: UInt8.self) 
       bytesPointer += 1 
       g = bytesPointer.load(as: UInt8.self) 
       bytesPointer += 1 
       b = bytesPointer.load(as: UInt8.self) 
       bytesPointer += 2 
       classifyPixel(r, g, b, &coverRed, &coverGreen, &coverYellow, &coverBlue, &coverWhite) 
       coverTotal += 1 
      } 
     } 

    } else { 
     print(#file + " " + #function + " failed to create bitmap context ") 
    } 
    bytesPointerSaved.deallocate(bytes: bufferSize, alignedTo: 1) 
    let fTotal = Float(coverTotal) 
    print("coverRed: \(100.0*Float(coverRed)/fTotal), coverGreen: \(100.0*Float(coverGreen)/fTotal), coverYellow: \(100.0*Float(coverYellow)/fTotal), coverBlue: \(100.0*Float(coverBlue)/fTotal), coverWhite: \(100.0*Float(coverWhite)/fTotal), coverTotal: \(coverTotal), #ofPixels: \(bufferSize/bytesPerPixel)") 

    greenValue = String(describing: (100.0*Float(coverGreen)/fTotal)) 
    yellowValue = String(describing: (100.0*Float(coverYellow)/fTotal)) 
    redValue = String(describing: (100.0*Float(coverRed)/fTotal)) 
    blueValue = String(describing: (100.0*Float(coverBlue)/fTotal)) 
    whiteValue = String(describing: (100.0*Float(coverWhite)/fTotal)) 
} 

override func didReceiveMemoryWarning() { 
    super.didReceiveMemoryWarning() 
} 

override func prepare(for segue: UIStoryboardSegue, sender: Any?) { 

    if segue.identifier == "computeResult" { 

     let areaController = segue.destination as! AreaPercentViewController 
     areaController.redValue = redValue 
     areaController.blueValue = blueValue 
     areaController.greenValue = greenValue 
     areaController.whiteValue = whiteValue 
     areaController.yellowValue = yellowValue 
     areaController.totalValue = totalValue 
    } 
} 
} 
+0

'ComputeAreaViewController'クラスの何が正しく動作しませんか?それがうまくいかないことが分かっていれば役に立ちます。 – KSigWyatt

+0

誠実な質問 - これをHD画像で試しましたか?大きな画像?パフォーマンス上の問題?代わりにCIAreaHistogramを使用することについての考えはありますか? – dfd

+0

"let image = UIImage(名前:" test-image.png ")を含むバージョンでは、computeArea関数が完全に機能し、結果が得られるピクセル数がカウントされます。" var image:UIImage! "私はそれが "view.layer.contents = image:cgImage!"と何か関係があると思う。 – user1698875

答えて

0

答えが渡されている画像のアルファチャンネルです。これは1.0未満で、1.0にリセットするとカウントの問題が修正されました。