简体   繁体   English

CVPixelBuffer在设备上产生垃圾图像,同时在模拟器上按预期工作

[英]CVPixelBuffer resulting into garbage image on the device, while working as expected on the simulator

I am trying to create an image out of artificially created data and want to use CVPixelBuffer : 我试图用人工创建的数据创建一个图像,并想使用CVPixelBuffer

    private func RGBAImage(width w: Int, height h: Int) -> UIImage? {

        let width = w * Int(UIScreen.main.scale)
        let height = h * Int(UIScreen.main.scale)

        // Prepare artificial data

        let dataPtr = UnsafeMutablePointer<UInt8>.allocate(capacity: width * height * 4)

        for i in 0..<width {
            for j in 0..<height {
                dataPtr[4 * (i + j * width)] = UInt8(sin(Double(i) * 0.01 * .pi / Double(UIScreen.main.scale)) * 127 + 127)
                dataPtr[4 * (i + j * width) + 1] = UInt8(255)
                dataPtr[4 * (i + j * width) + 2] = UInt8(0)
                dataPtr[4 * (i + j * width) + 3] = UInt8(0)
            }
        }

        // Convert data into CVPixelBuffer

        var pxBuffer: CVPixelBuffer?

        CVPixelBufferCreateWithBytes(
            kCFAllocatorDefault,
            width,
            height,
            kCVPixelFormatType_32ARGB,
            dataPtr,
            width * 4,
            nil,
            nil,
            [kCVPixelBufferIOSurfacePropertiesKey: [:]] as CFDictionary,
            &pxBuffer
        )

        dataPtr.deallocate()

        guard let cvPxBuffer = pxBuffer else {
            return nil
        }

        // Generate image from CVPixelBuffer

        let ciImage = CIImage(cvImageBuffer: cvPxBuffer)

        return UIImage(ciImage: ciImage, scale: UIScreen.main.scale, orientation: .up)
    }

The code works fine on simulator and shows as this : 代码在模拟器上工作正常并显示如下:

在此输入图像描述

But the same code shows garbage results on the device : 但是相同的代码显示设备上的垃圾结果:

在此输入图像描述

What am I missing here? 我在这里错过了什么? Any suggestion is welcome. 任何建议都是受欢迎的。

Figured out myself. 弄清楚自己。 I still don't know why CVPixelBufferCreateWithBytes doesn't work, but I was able to make it work by creating the pixel buffer with CVPixelBufferCreate and setting value of each RGB address one by one. 我仍然不知道为什么CVPixelBufferCreateWithBytes不起作用,但我能够通过使用CVPixelBufferCreate创建像素缓冲区并CVPixelBufferCreate设置每个RGB地址的值来使其工作。 This should be a better approach as well since I don't need to create an array first. 这应该是一个更好的方法,因为我不需要先创建一个数组。

Here is the working code for both device and simulator: 这是设备和模拟器的工作代码:

    private func RGBAImage(width w: Int, height h: Int) -> UIImage? {

        let width = w * Int(UIScreen.main.scale)
        let height = h * Int(UIScreen.main.scale)
        let bytesPerPixel = 4

        // Create CVPixelBuffer with artificial data

        var pxBuffer: CVPixelBuffer?

        CVPixelBufferCreate(
            kCFAllocatorDefault,
            width,
            height,
            kCVPixelFormatType_32ARGB,
            nil,
            &pxBuffer)

        guard let cvPxBuffer = pxBuffer else {
            return nil
        }

        CVPixelBufferLockBaseAddress(cvPxBuffer, CVPixelBufferLockFlags(rawValue: 0))
        let bufferWidth = Int(CVPixelBufferGetWidth(cvPxBuffer))
        let bufferHeight = Int(CVPixelBufferGetHeight(cvPxBuffer))
        let bytesPerRow = CVPixelBufferGetBytesPerRow(cvPxBuffer)

        guard let baseAddress = CVPixelBufferGetBaseAddress(pxBuffer!) else {
            return nil
        }

        for row in 0..<bufferHeight {
            var pixel = baseAddress + row * bytesPerRow
            for col in 0..<bufferWidth {
                let alpha = pixel
                alpha.storeBytes(of: UInt8(sin(Double(col) * 0.01 * .pi / Double(UIScreen.main.scale)) * 127 + 127), as: UInt8.self)

                let red = pixel + 1
                red.storeBytes(of: 255, as: UInt8.self)

                let green = pixel + 2
                green.storeBytes(of: 0, as: UInt8.self)

                let blue = pixel + 3
                blue.storeBytes(of: 0, as: UInt8.self)

                pixel += bytesPerPixel;
            }
        }

        CVPixelBufferUnlockBaseAddress(cvPxBuffer, CVPixelBufferLockFlags(rawValue: 0))

        // Generate image from CVPixelBuffer
        let ciImage = CIImage(cvImageBuffer: cvPxBuffer)

        return UIImage(ciImage: ciImage, scale: UIScreen.main.scale, orientation: .up)
    }

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

相关问题 UIButton图像在模拟器上工作但不在设备上工作 - UIButton image working on simulator but not on the device 应用程序在后台处理模拟器但不在设备上时更新位置(iOS 9) - Updating locations while app in background working on simulator but not on device (iOS 9) NSnumberFormatter在模拟器上工作,但不在设备上工作 - NSnumberFormatter working on simulator but not on device 可达性在模拟器上起作用,但在设备上不起作用 - Reachability working on simulator but not on device prepareForSegue在模拟器上工作但不在设备上工作 - prepareForSegue working on simulator but not on device FileExistAtPath在模拟器上运行,但在设备上不运行 - FileExistAtPath working on Simulator, but not on Device TVOutManager 在模拟器上工作,但不在设备上? - TVOutManager working on Simulator, but not on a device? NSSearchPathForDirectoriesInDomains可在模拟器上运行,但不能在设备上运行 - NSSearchPathForDirectoriesInDomains working on simulator but not on device Facebook图像上传在页面上在模拟器中正常工作但不在设备中 - Facebook image upload on a page working properly in simulator but not in device iOS图像显示在模拟器中,而不显示在设备上 - iOS image is displayed in simulator but not on the device
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM