从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,我会得到以下结果......
水平瑕疵是由我的屏幕捕获(不是在实际图像中)创建的,但是那些将图像分成3个相同部分的2条垂直线是问题所在!什么可能导致图像重复3次,并有2个垂直不连续?!更奇怪的是,如果我手动渲染perlin噪声而不创建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而不是直接将其绘制到上下文中会产生破坏图像的奇怪视觉问题。我需要能够在应用程序启动时生成一系列这些图像,并且无法手动绘制它们以获得良好的结果。任何人都知道什么可能导致这样的问题???
答案 0 :(得分: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++;
}
}