0

iphone で生データから CGImageRef を作成すると、かなり奇妙な問題が発生します。x、y、z、および t を取り、-1 と 1 の間の値を返すパーリン ノイズ生成関数から CGImageRef を作成しようとしています。各ピクセルについて、-1 と 1 の間のノイズ値を取得し、変換します。これを 0 ~ 255 の char に変換し、次の方法でデータから 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 を作成せずに手動でパーリン ノイズをレンダリングすると...

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 へのキャストが問題を引き起こしていないことを確認するために、意図的に char にキャストしてから 255.0 で割ったことに注意してください。とにかく、私は次の結果を得ます...

手動でノイズを描画する

したがって、上記の両方のアプローチでまったく同じノイズを作成しているように見えます。また、各メソッドの値を並べて出力して、それらが同一であることを確認しました! そのため、コンテキストに直接描画するのではなく、何らかの方法でデータから 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 に答える