Iphone 为什么我在编辑图像时会得到这些奇怪的结果?

Iphone 为什么我在编辑图像时会得到这些奇怪的结果?,iphone,ios,ipad,memory-management,core-graphics,Iphone,Ios,Ipad,Memory Management,Core Graphics,我试着做一些非常简单的事情: 1) 将UIImage绘制到CG位图上下文中 2) 获取指向图像数据的指针 3) 迭代所有像素,只需将所有RGB组件设置为0,将alpha设置为255。结果应该显示为纯黑色 这是我使用的原始图像。200 x 40像素,PNG-24 ARGB预乘alpha(所有alpha值==255): void *data = CGBitmapContextGetData(bitmapContext); size_t bytesPerRow = CGImageGetBytesP

我试着做一些非常简单的事情:

1) 将UIImage绘制到CG位图上下文中

2) 获取指向图像数据的指针

3) 迭代所有像素,只需将所有RGB组件设置为0,将alpha设置为255。结果应该显示为纯黑色


这是我使用的原始图像。200 x 40像素,PNG-24 ARGB预乘alpha(所有alpha值==255):

void *data = CGBitmapContextGetData(bitmapContext);
size_t bytesPerRow = CGImageGetBytesPerRow(img);

NSInteger modifiedPixels = 0;
for (int y = 0; y < height; y++) {
    for (int x = 0; x < width; x++) {
        long int offset = bytesPerRow * y + 4 * x;

        // ARGB
        unsigned char alpha = data[offset];
        unsigned char red = data[offset+1];
        unsigned char green = data[offset+2];
        unsigned char blue = data[offset+3];

        data[offset] = 255;
        data[offset+1] = 0;
        data[offset+2] = 0;
        data[offset+3] = 0;

        modifiedPixels++;
    }
}
CGImageRef imageRef = CGBitmapContextCreateImage(bitmapContext);
UIImage *img = [[UIImage alloc] initWithCGImage:imageRef];


这是我不修改像素时的结果(来自模拟器的屏幕截图)。看起来不错:

void *data = CGBitmapContextGetData(bitmapContext);
size_t bytesPerRow = CGImageGetBytesPerRow(img);

NSInteger modifiedPixels = 0;
for (int y = 0; y < height; y++) {
    for (int x = 0; x < width; x++) {
        long int offset = bytesPerRow * y + 4 * x;

        // ARGB
        unsigned char alpha = data[offset];
        unsigned char red = data[offset+1];
        unsigned char green = data[offset+2];
        unsigned char blue = data[offset+3];

        data[offset] = 255;
        data[offset+1] = 0;
        data[offset+2] = 0;
        data[offset+3] = 0;

        modifiedPixels++;
    }
}
CGImageRef imageRef = CGBitmapContextCreateImage(bitmapContext);
UIImage *img = [[UIImage alloc] initWithCGImage:imageRef];


当我进行修改时,这就是结果!看起来修改不完整。但是for循环覆盖了每个像素。计数器证明了这一点:控制台报告modifiedPixels=8000,正好是200 x 40像素。它看起来总是一模一样的

注意:我使用的PNG图像没有alpha<255。所以没有透明像素


这就是我创建上下文的方式。没什么特别的…

int bitmapBytesPerRow = (width * 4);
int bitmapByteCount = (bitmapBytesPerRow * imageHeight);

colorSpace = CGColorSpaceCreateDeviceRGB();

bitmapData = malloc(bitmapByteCount);
bitmapContext = CGBitmapContextCreate(bitmapData,
                width,
                height,
                8, // bits per component
                bitmapBytesPerRow,
                colorSpace,
                CGImageAlphaPremultipliedFirst);

接下来,我将图像绘制到
位图上下文中,并获得如下数据:

void *data = CGBitmapContextGetData(bitmapContext);
size_t bytesPerRow = CGImageGetBytesPerRow(img);

NSInteger modifiedPixels = 0;
for (int y = 0; y < height; y++) {
    for (int x = 0; x < width; x++) {
        long int offset = bytesPerRow * y + 4 * x;

        // ARGB
        unsigned char alpha = data[offset];
        unsigned char red = data[offset+1];
        unsigned char green = data[offset+2];
        unsigned char blue = data[offset+3];

        data[offset] = 255;
        data[offset+1] = 0;
        data[offset+2] = 0;
        data[offset+3] = 0;

        modifiedPixels++;
    }
}
CGImageRef imageRef = CGBitmapContextCreateImage(bitmapContext);
UIImage *img = [[UIImage alloc] initWithCGImage:imageRef];

这是迭代像素以修改它们的代码:

void *data = CGBitmapContextGetData(bitmapContext);
size_t bytesPerRow = CGImageGetBytesPerRow(img);

NSInteger modifiedPixels = 0;
for (int y = 0; y < height; y++) {
    for (int x = 0; x < width; x++) {
        long int offset = bytesPerRow * y + 4 * x;

        // ARGB
        unsigned char alpha = data[offset];
        unsigned char red = data[offset+1];
        unsigned char green = data[offset+2];
        unsigned char blue = data[offset+3];

        data[offset] = 255;
        data[offset+1] = 0;
        data[offset+2] = 0;
        data[offset+3] = 0;

        modifiedPixels++;
    }
}
CGImageRef imageRef = CGBitmapContextCreateImage(bitmapContext);
UIImage *img = [[UIImage alloc] initWithCGImage:imageRef];

问题: 我做错了什么


发生这种情况是因为我在遍历数据时修改了数据吗?我必须复制它吗?

可能您的高度或宽度有误。。。。顺便说一句,240x40=9600而不是8000,这样可以确保您没有对每个像素进行迭代。

使用CGBitmapContextGetBytesPerRow(bitmapContext)获取bytesPerRow,而不是从图像获取(如果图像没有alpha信息,则每个像素只有3个字节)

您确定这是正确的代码吗?它将所有设置为255,应该显示为白色。是的,正确的代码。我只是忘了在这里编辑这些值。之前我尝试将图像设置为白色,但是在白色背景下很难看到示例图像。代码使用malloc()中的空白内存,但是示例中预先填充了一个图像,我想知道图像是否不是您认为的正确格式,我已经更新了问题。希望现在清楚了。malloc()仅用于创建上下文。然后图像被画进去,然后我从上下文中获取数据指针。听起来像是一个填充问题该死,这是我问题中的一个输入错误。它是200 x 40。