CGImageRef宽度与每行字节数不一致

时间:2014-09-07 01:50:50

标签: macos cocoa framebuffer cgimageref

我正在尝试从屏幕缓冲区中读取像素,我正在使用CGImageRef创建CGDisplayCreateImage,但是CGImageGetWidthCGImageGetBytesPerRow Don'的值t有意义,将每行的字节数除以每个像素的字节数,得到每行1376个像素,但图像的宽度为1366。

这里发生了什么?图像中是否有某种填充?我如何安全地读取数据,并获得正确的结果?

编辑:重现此操作所需的最小代码如下:

#import <Foundation/Foundation.h>
#import <ApplicationServices/ApplicationServices.h>

int main(int argc, const char * argv[])
{

    @autoreleasepool {
        CGImageRef image = CGDisplayCreateImage(CGMainDisplayID());

        size_t width = CGImageGetWidth(image);
        size_t bpr = CGImageGetBytesPerRow(image);
        size_t bpp = CGImageGetBitsPerPixel(image);
        size_t bpc = CGImageGetBitsPerComponent(image);
        size_t bytes_per_pixel = bpp / bpc;

        NSLog(@"%li %li", bpr/bytes_per_pixel, width);

        CGImageRelease(image);

    }
    return 0;
}

1 个答案:

答案 0 :(得分:13)

每行的字节数(也称为“步幅”)可以大于图像的宽度。简单地忽略每行末尾的额外字节。 (x, y)处像素的字节从偏移y * bpr + x * bpp开始(其中bpr是每行字节数,bpp是每像素字节数。)

请注意,1376可以被32整除(并且所有较小的幂都是2),而1366则不是。现代Mac中的CPU具有一次操作16或32或64字节的指令,因此如果图像的步幅是16或32或64的倍数,则CGImage算法可以更有效。{{1}是由知道这一点的人写的。