Странная проблема создания CGImage

Я сталкиваюсь с довольно странной проблемой при создании CGImageRef из необработанных данных на iphone. Я пытаюсь создать CGImageRef из функции генерации шума Перлина, которая принимает x, y, z и t и возвращает значение от -1 до 1. Для каждого пикселя я получаю значение шума от -1 до 1, конвертирую this на char от 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 создан из данных

Горизонтальные артефакты были созданы моим снимком экрана (а не на самом изображении), однако проблема заключается в тех 2 вертикальных линиях, которые разделяют изображение на 3 идентичных участка! Что может привести к тому, что изображение будет повторяться 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, а затем разделил на 255.0, чтобы убедиться, что преобразование в char не вызывает проблемы. В любом случае, я получаю следующий результат ...

Рисование шума вручную

Итак, вам кажется, что я создаю одинаковый шум в обоих вышеупомянутых подходах, и я даже напечатал значения из каждого метода рядом, чтобы подтвердить, что они идентичны! Итак, каким-то образом создание CGImageRef из данных вместо того, чтобы рисовать его прямо в контексте, создает странные визуальные проблемы, которые разрушают изображение. Мне нужно иметь возможность сгенерировать серию этих изображений при запуске приложения и я не могу рисовать их вручную, чтобы получить хорошие результаты. Кто-нибудь знает, что могло вызвать такие проблемы ???


person Nitrex88    schedule 22.06.2011    source источник


Ответы (1)


Поскольку 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++;
    }
}
person DHamrick    schedule 22.06.2011
comment
Твое право! Простая ошибка ... спасибо, что заметили! А поскольку другой рендеринг выполнялся попиксельно, порядок циклов for не имел значения. классно - person Nitrex88; 22.06.2011