从另一个类访问一个类:不能在类型上使用实例成员

时间:2015-11-16 17:11:13

标签: swift swift2

我使用Xcode Playground进入Swift,并且我正在关注简单图像过滤的在线课程。

到目前为止,这是我的代码:

import UIKit

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

class ImageInfo {
    let rgbaImage = RGBAImage(image: image)
    func getAvgCols() -> [String:Int] {
        var totalRed = 0
        var totalGreen = 0
        var totalBlue = 0
        var avgCol = [String:Int]()

        for y in 0..<rgbaImage!.height{
            for x in 0..<rgbaImage!.width{
                let index = y * rgbaImage!.width + x
                let pixel = rgbaImage!.pixels[index]

                totalRed += Int(pixel.red)
                totalGreen += Int(pixel.green)
                totalBlue += Int(pixel.blue)
            }
        }

        let pixelCount = rgbaImage!.width * rgbaImage!.height

        avgCol["Red"] = (totalRed / pixelCount)
        avgCol["Green"] = (totalGreen / pixelCount)
        avgCol["Blue"] = (totalBlue / pixelCount)
        return avgCol
    }
}


let imageInfo = ImageInfo()
var avgRed = imageInfo.getAvgCols()["Red"]!
var avgGreen = imageInfo.getAvgCols()["Green"]!
var avgBlue = imageInfo.getAvgCols()["Blue"]!

var modifier = 20
// IMAGE EDITING LOOP
for y in 0..<rgbaImage!.height{
    for x in 0..<rgbaImage!.width{
        let index = y * rgbaImage!.width + x
        var pixel = rgbaImage!.pixels[index]

        let redDelta = Int(pixel.red) - avgRed
        let greenDelta = Int(pixel.green) - avgGreen
        let blueDelta = Int(pixel.blue) - avgBlue

        let redModifier = Double(modifier) * 0.49
        let greenModifier = Double(modifier) * 0.25
        let blueModifier = Double(modifier) * 0.07

        pixel.red = UInt8(max(min(255, avgRed + Int(redModifier) * redDelta),0))
        pixel.green = UInt8(max(min(255, avgGreen + Int(greenModifier) * greenDelta),0))
        pixel.blue = UInt8(max(min(255, avgBlue + Int(blueModifier) * blueDelta),0))
        rgbaImage!.pixels[index] = pixel
    }
}
let newImage = rgbaImage!.toUIImage()!

到目前为止,效果很好。最后一段代码基于每个像素修改图像,最终结果是一个穷人尝试一些棕褐色。

然而,问题在于我将整个图像编辑循环粘贴到另一个类中,如下所示:

class ImageEdit {
    let imageInfo = ImageInfo()
    var avgRed = imageInfo.getAvgCols()["Red"]!
    var avgGreen = imageInfo.getAvgCols()["Green"]!
    var avgBlue = imageInfo.getAvgCols()["Blue"]!
    func applyFilter(filter: String, modifier: Int) -> UIImage{
        for y in 0..<rgbaImage!.height{
            for x in 0..<rgbaImage!.width{
                let index = y * rgbaImage!.width + x
                var pixel = rgbaImage!.pixels[index]

                let redDelta = Int(pixel.red) - avgRed
                let greenDelta = Int(pixel.green) - avgGreen
                let blueDelta = Int(pixel.blue) - avgBlue

                let redModifier = Double(modifier) * 0.49
                let greenModifier = Double(modifier) * 0.25
                let blueModifier = Double(modifier) * 0.07

                pixel.red = UInt8(max(min(255, avgRed + Int(redModifier) * redDelta),0))
                pixel.green = UInt8(max(min(255, avgGreen + Int(greenModifier) * greenDelta),0))
                pixel.blue = UInt8(max(min(255, avgBlue + Int(blueModifier) * blueDelta),0))
                rgbaImage!.pixels[index] = pixel
            }
        }
        let newImage = rgbaImage!.toUIImage()!
        return newImage
    }
}

注意:由于我使用的是游戏场,因此两个类都在同一个文件中。为了澄清,只需使用我之前的代码,并将下面的下的所有内容ImageInfo替换为ImageEdit

我需要访问avgRed,avgGreen和avgBlue,但我得到的只是

  

实例成员&#39; imageInfo&#39;不能在类型&#39; ImageEdit&#39;

上使用

由于我是Swift的菜鸟,我不确定如何修复它。

我错过了什么吗?

编辑:这里的RGBAImage。我没有写这个代码,可以免费下载给参加在线课程的任何人。

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
    }
}

1 个答案:

答案 0 :(得分:1)

问题是您在初始化课程之前在imageInfo内调用属性ImageEdit

只有在调用初始化时,一切都变成了某种东西。因此,avgRed无法从imageInfo函数中获取值,因为它尚未构建。

在函数内部执行此操作(init()基本上是一个函数)只是找到。在课堂上这样做是行不通的。

这不起作用:

class A {

    let attribute : Int = 0

    init() {

    }

}

class B {

    let attributeA = A()
    let attributeB = attributeA.attribute // this is your problem

}

这样做:

对于依赖于构建其他属性的所有属性,使用 late init 。所有依赖外部输入的属性,可用功能,......您声明为可选

  • 晚期初始版:var / let attrName : Type
  • 可选:var / let attrName : Type ? / !
class B {

    let attributeA = A()
    let attributeB : Int
    var attributeC : Int?

    init () {
        attributeB = attributeA.attribute
        attributeC = somethingOptional()
    }
    func somethingOptional() -> Int? {
        return 0 // not really optional, but just illustration
    }
}

所以对你来说就是这样:

class ImageEdit {

    let imageInfo = ImageInfo()
    let dict : [String:Int]

    init () {

        dict = imageInfo.getAvgCols()

    }
}