简体   繁体   English

线程1:EXC_BAD_ACCESS(代码= EXC_I386_GPFLT)

[英]Thread 1: EXC_BAD_ACCESS (code=EXC_I386_GPFLT)

In my swift project, I have two classes that work together to hold Pixel values of an image to be able to modify red, green, blue and alpha values. 在我的快速项目中,我有两个类一起工作,以保存图像的像素值,以便能够修改红色,绿色,蓝色和Alpha值。 An UnsafeMutableBufferPointer holds lots of bites that are comprised of the Pixel class objects. UnsafeMutableBufferPointer包含由Pixel类对象组成的许多位。

I can interact with that the class that holds the UnsafeMutableBufferPointer<Pixel> property. 我可以与拥有UnsafeMutableBufferPointer<Pixel>属性的类进行交互。 I can access all of the properties on that object and that all works fine. 我可以访问该对象的所有属性,并且一切正常。 The only problem I'm having with the UnsafeMutableBufferPoint<Pixel> is trying to loop through it with my Pixel object and it keeps crashing with the Thread 1: EXC_BAD_ACCESS (code=EXC_I386_GPFLT) exception. 我对UnsafeMutableBufferPoint<Pixel>遇到的唯一问题是试图通过我的Pixel对象遍历它,并且它一直在线程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)
}

This function is the part that is crashing the program. 该功能是导致程序崩溃的部分。 The exact part that is crashing is the for loop that is looping through the rgba.pixels. 崩溃的确切部分是循环通过rgba.pixels的for循环。 rgba.pixels is the UnsafeMutableBufferPointer. rgba.pixels是UnsafeMutableBufferPointer。

func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any])
{
    let image: UIImage = info[UIImagePickerControllerEditedImage] as! UIImage!

    let rgba = RGBA(image: image)!

    for pixel in rgba.pixels
    {
        print(pixel.red)
    }

    self.dismiss(animated: true, completion: nil);
}

This is the constructor where I create the UnsafeMutableBufferPointer<Pixel> . 这是我在其中创建UnsafeMutableBufferPointer<Pixel>的构造函数。 Is there an easier way to do this and still be able to get the RBGA values and change them easily. 有没有更简单的方法可以做到这一点,并且仍然能够获取并轻松更改RBGA值。

The Pixel class is a UInt32 value this is split into four UInt 8 values. Pixel类是一个UInt32值,它分为四个UInt 8值。

Am I using the wrong construct to hold those values and if so, is there a safer or easier construct to use? 我是否使用了错误的构造来保存这些值,如果是,是否有更安全或更容易使用的构造? Or am I doing something wrong when accessing the Pixel values? 还是访问像素值时我做错了什么?

This is how I got the pixels of an image - 这就是我获得图像像素的方式-

// 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)

Keep in mind this is not Swift 3 syntax incase that's what you're using, but that's the basic algorithm. 请记住,这不是Swift 3语法,这是您正在使用的语法,但这是基本算法。 Now to grab the individual color values of each pixel, you will have to implement these functions - 现在要获取每个像素的各个颜色值,您将必须实现以下功能-

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

To create a completely new color after processing the RGBA values, you use this function - 要在处理RGBA值后创建全新的颜色,请使用此功能-

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

To iterate through the pixels array, you do it as so - 要遍历pixels数组,您可以这样做-

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 加载AVPlayer时出现错误线程1:EXC_BAD_ACCESS(code = EXC_I386_GPFLT) - Getting error Thread 1: EXC_BAD_ACCESS (code=EXC_I386_GPFLT) when loading AVPlayer 得到错误:“线程1:SOAP请求期间EXC_BAD_ACCESS(Code = EXC_I386_GPFLT) - Getting error: "Thread 1: EXC_BAD_ACCESS(Code=EXC_I386_GPFLT) during SOAP request 错误:“线程 1:EXC_BAD_ACCESS(代码=EXC_I386_GPFLT) - error: "Thread 1: EXC_BAD_ACCESS(Code=EXC_I386_GPFLT) 在向我的结构添加属性后获取线程 10:EXC_BAD_ACCESS (code=EXC_I386_GPFLT) - Getting Thread 10: EXC_BAD_ACCESS (code=EXC_I386_GPFLT) after adding property to my struct UIAlertView EXC_BAD_ACCESS(代码=EXC_I386_GPFLT) - UIAlertView EXC_BAD_ACCESS(code=EXC_I386_GPFLT) GPPSignIn sharedInstance-&gt; EXC_BAD_ACCESS(代码= EXC_I386_GPFLT) - GPPSignIn sharedInstance -> EXC_BAD_ACCESS (code = EXC_I386_GPFLT) 如何在swift编程中解决这个EXC_BAD_ACCESS(代码= EXC_i386_GPFLT) - How to solve this EXC_BAD_ACCESS(code=EXC_i386_GPFLT )in swift programming 当deleteRows时为EXC_BAD_ACCESS(代码为EXC_I386_GPFLT)(在[IndexPath]) - EXC_BAD_ACCESS (code=EXC_I386_GPFLT) when deleteRows(at: [IndexPath]) iOS Swift:EXC_BAD_ACCESS(code = EXC_i386_GPFLT)关于单例 - iOS Swift : EXC_BAD_ACCESS(code=EXC_i386_GPFLT ) regarding a singleton IOS:NavigationController切换UIViewcontrollers,EXC_BAD_ACCESS EXC_I386_GPFLT错误 - IOS: NavigationController switch UIViewcontrollers , EXC_BAD_ACCESS EXC_I386_GPFLT error
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM