5

我正在尝试从屏幕缓冲区中读取像素,我正在创建一个CGImageRefwith CGDisplayCreateImage,但是 和 的值CGImageGetWidth一起CGImageGetBytesPerRow没有意义,将每行的字节数除以每像素的字节数给我每行 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;
}
4

1 回答 1

18

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

请注意,1376 可以被 32 整除(以及 2 的所有较小幂),而 1366 则不能。现代 Mac 中的 CPU 具有一次在 16 或 32 或 64 字节上运行的指令,因此CGImage如果图像的步幅是 16 或 32 或 64 的倍数,则算法会更有效。 CGDisplayCreateImage由知道这一点的人编写。

于 2014-09-07T02:26:12.520 回答