gpt4 book ai didi

Swift 版本获取错误的像素数据,但 Object-c 版本使用方法 "CGBitmapContextCreate"从同一图像获取正确的像素数据

转载 作者:行者123 更新时间:2023-11-28 05:40:54 24 4
gpt4 key购买 nike

简直不敢相信自己的眼睛,它们基本上是相同的代码,只是将Object-c代码转换为swift代码而已,但是Object-c代码总是得到正确答案,但是swift代码有时会得到正确答案, 有时会出错。

Swift 版本:

class ImageProcessor1 {
class func processImage(image: UIImage) {
guard let cgImage = image.cgImage else {
return
}
let width = Int(image.size.width)
let height = Int(image.size.height)
let bytesPerRow = width * 4
let imageData = UnsafeMutablePointer<UInt32>.allocate(capacity: width * height)
let colorSpace = CGColorSpaceCreateDeviceRGB()

let bitmapInfo: UInt32 = CGBitmapInfo.byteOrder32Big.rawValue | CGImageAlphaInfo.premultipliedLast.rawValue
guard let imageContext = CGContext(data: imageData, width: width, height: height, bitsPerComponent: 8, bytesPerRow: bytesPerRow, space: colorSpace, bitmapInfo: bitmapInfo) else {
return
}
imageContext.draw(cgImage, in: CGRect(origin: .zero, size: image.size))
print("---------data from Swift version----------")
for i in 0..<width * height {
print(imageData[i])
}
}
}

Objective-C 版本:

- (UIImage *)processUsingPixels:(UIImage*)inputImage {

// 1. Get the raw pixels of the image
UInt32 * inputPixels;

CGImageRef inputCGImage = [inputImage CGImage];
NSUInteger inputWidth = CGImageGetWidth(inputCGImage);
NSUInteger inputHeight = CGImageGetHeight(inputCGImage);

CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();

NSUInteger bytesPerPixel = 4;
NSUInteger bitsPerComponent = 8;

NSUInteger inputBytesPerRow = bytesPerPixel * inputWidth;

inputPixels = (UInt32 *)calloc(inputHeight * inputWidth, sizeof(UInt32));

CGContextRef context = CGBitmapContextCreate(inputPixels, inputWidth, inputHeight,
bitsPerComponent, inputBytesPerRow, colorSpace,
kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);

CGContextDrawImage(context, CGRectMake(0, 0, inputWidth, inputHeight), inputCGImage);

NSLog(@"---------data from Object-c version----------");
UInt32 * currentPixel = inputPixels;
for (NSUInteger j = 0; j < inputHeight; j++) {
for (NSUInteger i = 0; i < inputWidth; i++) {
UInt32 color = *currentPixel;
NSLog(@"%u", color);
currentPixel++;
}
}
return inputImage;
}

可在 https://github.com/tuchangwei/Pixel 获得

如果你得到相同的答案,请多运行几次。

最佳答案

您的 Objective-C 和 Swift 代码 have leaks .此外,您的 Swift 代码未初始化分配的内存。当我initialized内存,我没有看到任何差异:

imageData.initialize(repeating: 0, count: width * height)

FWIW,虽然 allocate 不会初始化内存缓冲区,但 calloc 会:

... The allocated memory is filled with bytes of value zero.

但就个人而言,我建议您完全摆脱分配内存的工作,为 data 参数传递 nil,然后使用 bindMemory 访问该缓冲区。如果你这样做,如 the documentation说:

Pass NULL if you want this function to allocate memory for the bitmap. This frees you from managing your own memory, which reduces memory leak issues.

因此,也许:

class func processImage(image: UIImage) {
guard let cgImage = image.cgImage else {
return
}
let width = cgImage.width
let height = cgImage.height
let bytesPerRow = width * 4

let colorSpace = CGColorSpaceCreateDeviceRGB()

let bitmapInfo: UInt32 = CGBitmapInfo.byteOrder32Big.rawValue | CGImageAlphaInfo.premultipliedLast.rawValue
guard
let imageContext = CGContext(data: nil, width: width, height: height, bitsPerComponent: 8, bytesPerRow: bytesPerRow, space: colorSpace, bitmapInfo: bitmapInfo),
let rawPointer = imageContext.data
else {
return
}

let pixelBuffer = rawPointer.bindMemory(to: UInt32.self, capacity: width * height)

imageContext.draw(cgImage, in: CGRect(origin: .zero, size: CGSize(width: width, height: height)))
print("---------data from Swift version----------")
for i in 0..<width * height {
print(pixelBuffer[i])
}
}

关于Swift 版本获取错误的像素数据,但 Object-c 版本使用方法 "CGBitmapContextCreate"从同一图像获取正确的像素数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56801083/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com