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

Posted

技术标签:

【中文标题】CGImageRef 宽度与每行字节数不一致【英文标题】:CGImageRef width doesn't agree with bytes-per-row 【发布时间】:2014-09-07 01:50:49 【问题描述】:

我正在尝试从屏幕缓冲区中读取像素,我正在创建一个带有 CGDisplayCreateImageCGImageRef,但 CGImageGetWidthCGImageGetBytesPerRow 的值放在一起没有意义,将字节分开每行每像素的字节数给我每行 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;

【问题讨论】:

我只是从显示缓冲区中获取图像。 图像尺寸应该是多少? 这里真正唯一重要的是数据的宽度与内容的宽度不同。我不应该得到 1376 的行中像素数,并且图像的宽度为 1366。 【参考方案1】:

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

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

【讨论】:

谢谢,这正是我所需要的,也非常欢迎解释为什么这样做。 像往常一样。 Rob 给出了惊人的答案。

以上是关于CGImageRef 宽度与每行字节数不一致的主要内容,如果未能解决你的问题,请参考以下文章

位图存储图像数据每行字节数为4的倍数

图像跨距的概念

006.显示变量所占字节数

C++基本数据类型的字节数与范围大小

数据类型

C/C++基本数据类型所占字节数