0

从 iphone 上的原始数据创建 CGImageRef 时,我遇到了一个非常奇怪的问题。我正在尝试从 perlin 噪声生成函数创建一个 CGImageRef,该函数采用 x、y、z 和 t 并返回一个介于 -1 和 1 之间的值。对于每个像素,我得到介于 -1 和 1 之间的噪声值,转换将其转换为 0 到 255 之间的字符,并通过以下方式从数据中创建 CGImageRef ...

int width = (int)frame.size.width;
int height = (int)frame.size.height;
char* rgba = (char*)malloc(width * height * 4);

//set pixel data
int i = 0;
for(float x = 0.0; x < width; x+=1.0) {
    for (float y = 0.0; y < height; y+=1.0) {
        float perlinF = ABS([perlinGenerator perlinNoiseX:x y:y z:0.0 t:0.0]);
        char perlin = (char)( perlinF * 255.0 );

        rgba[4*i] = perlin;
        rgba[4*i+1] = perlin;
        rgba[4*i+2] = perlin;
        rgba[4*i+3] = 255;
        i++;
    }
}

CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef bitmapContext = CGBitmapContextCreate(
                                                   rgba,
                                                   width,
                                                   height,
                                                   8, // bitsPerComponent
                                                   4*width, // bytesPerRow
                                                   colorSpace,
                                                   kCGImageAlphaNoneSkipLast);

CGImageRef cgImage = CGBitmapContextCreateImage(bitmapContext);

如果我然后将此 CGImageRef 绘制到 CALayer,我会得到以下结果...

从数据创建的 CGImageRef

水平伪影是由我的屏幕截图创建的(不是在实际图像中),但是将图像分成 3 个相同部分的那 2 条垂直线是问题所在!什么可能导致图像重复 3 次并具有这 2 个垂直不连续性?!更奇怪的是,如果我在不创建 CGImageRef 的情况下手动渲染 perlin 噪声,就像这样......

for (CGFloat x = 0.0; x<size.width; x+=1.0) {
    for (CGFloat y=0.0; y< size.height; y+=1.0) {
        float perlinF = ABS([perlinGenerator perlinNoiseX:x y:y z:0.0 t:0.0]);
        char perlin = (char)( perlinF * 255.0 );

        CGContextSetRGBFillColor(context, 1.0, 1.0, 1.0, (float)perlin / 255.0);
        CGContextFillRect(context, CGRectMake(x, y, 1.0, 1.0));
    }
}

请注意,我故意转换为 char 然后除以 255.0 以确保转换为 char 不会导致问题。无论如何,我得到以下结果......

手动绘制噪音

所以你似乎在上述两种方法中产生的噪音完全相同,我什至并排打印了每种方法的值以确认它们是相同的!因此,不知何故,从数据中创建 CGImageRef 而不是直接将其绘制到上下文中会产生奇怪的视觉问题,从而破坏图像。我需要能够在应用程序启动时生成一系列这些图像,并且不能手动绘制它们以获得良好的结果。任何人都知道什么会导致这样的问题???

4

1 回答 1

0

由于 CGBitmapContextCreate 假定您的图像缓冲区是按行而不是按列索引的,因此您需要将 x 和 y 交换为循环。

int i = 0;
for (float y = 0.0; y < height; y+=1.0) {
    for(float x = 0.0; x < width; x+=1.0) {
        float perlinF = ABS([perlinGenerator perlinNoiseX:x y:y z:0.0 t:0.0]);
        char perlin = (char)( perlinF * 255.0 );

        rgba[4*i] = perlin;
        rgba[4*i+1] = perlin;
        rgba[4*i+2] = perlin;
        rgba[4*i+3] = 255;
        i++;
    }
}
于 2011-06-22T02:47:11.027 回答