Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/93.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 将UIImage像素数据存储到c数组中,无法确定数组';s元素计数_Ios_Objective C_C_Arrays_Pixel - Fatal编程技术网

Ios 将UIImage像素数据存储到c数组中,无法确定数组';s元素计数

Ios 将UIImage像素数据存储到c数组中,无法确定数组';s元素计数,ios,objective-c,c,arrays,pixel,Ios,Objective C,C,Arrays,Pixel,我像这样初始化了数组 CGImageRef imageRef = CGImageCreateWithImageInRect(image.CGImage, bounds); CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); NSUInteger width = CGImageGetWidth(imageRef); NSUInteger height = CGImageGetHeight(imageRef); unsigned c

我像这样初始化了数组

CGImageRef imageRef = CGImageCreateWithImageInRect(image.CGImage, bounds);
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
NSUInteger width = CGImageGetWidth(imageRef);
NSUInteger height = CGImageGetHeight(imageRef);
unsigned char *rawData = malloc(height * width * 4);
NSUInteger bytesPerPixel = 4;
NSUInteger bytesPerRow = bytesPerPixel * width;
NSUInteger bitsPerComponent = 8;
CGContextRef context = CGBitmapContextCreate(rawData, width, height, bitsPerComponent, bytesPerRow, colorSpace, kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);
但是,当我尝试通过NSLog检查计数时,我总是得到4(特别是4/1)

然而,当我记录单个元素的值时,它返回非零值

例如
CGFloat f1=rawData[15]

CGFloat f2=rawData[n]
,其中
n
图像宽度*高度*4

//我没想到这会起作用,因为最后一个元素应该是n-1

最后,我试了一下

int n = lipBorder.size.width *lipBorder.size.height*4*2; //lipBorder holds the image's dimensions, I tried multiplying by 2 because there are 2 pixels for every CGPoint in retina
CGFloat f = rawData[n];
这将为同一图像每次返回不同的值(例如0.000、115.000、38.000)


如何确定计数/如何将值存储到数组中?

rawData
是指向无符号字符的指针,因此其大小为32位(4字节)[1]
rawData[0]
是一个无符号字符,因此其大小为8位(1字节)。因此,
4/1

您以前可能见过使用阵列实现此功能,它的工作原理与您预期的一样:

unsigned char temp[10] = {0};
NSLog(@"%d", sizeof(temp)/sizeof(temp[0])); // Prints 10
但是,请注意,您处理的是指向无符号字符的指针,而不是无符号字符的数组-语义是不同的,因此在您的情况下这不起作用

如果您想要缓冲区的大小,只需使用
height*width*4
就更好了,因为这是传递给
malloc
的内容。如果确实需要,可以将其除以
sizeof(char)
sizeof(rawData[0])
得到元素数,但由于它们是char,所以无论如何都会得到相同的数

现在,
rawData
只是某个地方的一块内存。在它之前和之后还有其他的记忆。因此,如果您尝试执行类似于
rawData[height*width*4]
的操作,那么实际上您正在尝试访问分配给
rawData
的块之后内存的下一个字节。这是未定义的行为,可能导致返回随机垃圾值[2](如您所观察到的),返回一些“未分配内存”标记值,或者发生分段错误


[1] :iOS是32位平台

[2] :可能是上次合法使用时放入该内存位置的任何值。

malloc返回的指针是void*指针,意味着它返回指向内存中地址的指针。似乎返回的宽度和高度为0。这将解释为什么只为阵列分配4个字节

你还说你试过了

int n = lipBorder.size.width *lipBorder.size.height*4*2; //lipBorder holds the image's dimensions, I tried multiplying by 2 because there are 2 pixels for every CGPoint in retina
    CGFloat f = rawData[n];    
每次都会收到不同的值。考虑到您的数组只有4字节长,并且您正在访问的内存区域在内存中遥遥领先,这种行为是可以预料的。该值发生变化的原因是,您正在访问的内存不在数组中,而是在一个
lipBorder.size.width*lipBorder.size.height*4*2-4
从数组末尾传递的字节数。C绝不会阻止您访问程序中的任何内存。如果您访问了程序禁止访问的内存,您将收到一个分段错误

因此,您可以访问
n+1
n+2
n+任何元素。这只意味着您正在访问传递到数组末尾的内存


增加指针rawdata会将内存地址移动一个字节。递增和int指针会将内存地址递增4个字节(sizeof(int))。

好的,但为什么我会得到width*height*4的值?@Mahir:我不确定我是否会这样做。调用带有参数的
malloc
,例如,
n
意味着“分配给我
n
字节的内存”。如果您从
malloc
返回一个有效指针,您可以确信它指向(至少)一块
n
字节的内存。在本例中,您使用
height*width*4
n
调用
malloc
,并返回一个有效指针,因此您知道
rawData
的长度必须是
height*width*4
字节。不需要任何其他间接方法来确定它的大小。对不起,我以为参数是元素的数量,而不是内存大小。但是,如果每个元素都是1字节,它们不是像你提到的那样都是一样的吗?我假设如果我是
malloc[n]
,我会收到一个数组,它可以容纳
n
个元素,这意味着最后一个元素将是
rawData[n-1]
,显然不是这样的情况,
malloc
只返回一个通用指针(即
void*
)到一个大小为
n
字节的内存块。在您的例子中,您的“元素”的大小也是1字节,因此新内存块恰好也是
n
元素的大小。
int n = lipBorder.size.width *lipBorder.size.height*4*2; //lipBorder holds the image's dimensions, I tried multiplying by 2 because there are 2 pixels for every CGPoint in retina
    CGFloat f = rawData[n];