2016-05-07 5 views
4

OpenGLESメソッド(glReadPixels)などでピクセルを取得し、ビデオ録画用にCVPixelBuffer(CGImageを使用するかどうか)を作成します。これは私がiPhone 5cの上でテストしたときに、iPhone6に起こる5Sと6ピクセルデータを含むCVPixelBufferを作成しますが、最終イメージが歪みます

それは次のようになります。

CGSize viewSize=self.glView.bounds.size; 
NSInteger myDataLength = viewSize.width * viewSize.height * 4; 

// allocate array and read pixels into it. 
GLubyte *buffer = (GLubyte *) malloc(myDataLength); 
glReadPixels(0, 0, viewSize.width, viewSize.height, GL_RGBA, GL_UNSIGNED_BYTE, buffer); 

// gl renders "upside down" so swap top to bottom into new array. 
// there's gotta be a better way, but this works. 
GLubyte *buffer2 = (GLubyte *) malloc(myDataLength); 
for(int y = 0; y < viewSize.height; y++) 
{ 
    for(int x = 0; x < viewSize.width* 4; x++) 
    { 
     buffer2[(int)((viewSize.height-1 - y) * viewSize.width * 4 + x)] = buffer[(int)(y * 4 * viewSize.width + x)]; 
    } 
} 

free(buffer); 

// make data provider with data. 
CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, buffer2, myDataLength, NULL); 

// prep the ingredients 
int bitsPerComponent = 8; 
int bitsPerPixel = 32; 
int bytesPerRow = 4 * viewSize.width; 
CGBitmapInfo bitmapInfo = kCGBitmapByteOrderDefault; 
CGColorRenderingIntent renderingIntent = kCGRenderingIntentDefault; 

// make the cgimage 
CGColorSpaceRef colorSpaceRef = CGColorSpaceCreateDeviceRGB(); 
CGImageRef imageRef = CGImageCreate(viewSize.width , viewSize.height, bitsPerComponent, bitsPerPixel, bytesPerRow, colorSpaceRef, bitmapInfo, provider, NULL, NO, renderingIntent); 

//UIImage *photo = [UIImage imageWithCGImage:imageRef]; 

int width = CGImageGetWidth(imageRef); 
int height = CGImageGetHeight(imageRef); 

CVPixelBufferRef pixelBuffer = NULL; 
CVReturn status = CVPixelBufferPoolCreatePixelBuffer(NULL, _recorder.pixelBufferAdaptor.pixelBufferPool, &pixelBuffer); 

NSAssert((status == kCVReturnSuccess && pixelBuffer != NULL), @"create pixel buffer failed."); 

CVPixelBufferLockBaseAddress(pixelBuffer, 0); 
void *pxdata = CVPixelBufferGetBaseAddress(pixelBuffer); 
NSParameterAssert(pxdata != NULL);//CGContextRef 
CGContextRef context = CGBitmapContextCreate(pxdata, 
              width, 
              height, 
              CGImageGetBitsPerComponent(imageRef), 
              CGImageGetBytesPerRow(imageRef), 
              colorSpaceRef, 
              kCGImageAlphaPremultipliedLast); 
NSParameterAssert(context); 

CGContextDrawImage(context, CGRectMake(0, 0, width, height), imageRef); 

CVPixelBufferUnlockBaseAddress(pixelBuffer, 0); 

CGColorSpaceRelease(colorSpaceRef); 
CGContextRelease(context); 
CGImageRelease(imageRef); 

free(buffer2); 

//CIImage *image = [CIImage imageWithCVPixelBuffer:pixelBuffer]; 

// ... 

CVPixelBufferRelease(pixelBuffer); 
+0

また、この問題が発生して... :( – jamesfzhang

+0

は、私はすべてのフレームがまったく同じ寸法であることを確実にすることによってこの問題を解決することができましたいくつかのフレームのサイズが少し違っていて、歪みが生じました。 – jamesfzhang

答えて

0

NOTE - この答えはに関し

enter image description here

ここでは、コードです特定のコードではなく画像全体の問題。

問題のこの種は、通常、「ストライド」であり、画素の各列は、一例として緊密に一緒に

を充填されていない元画像が240個のピクセル幅とすることができる画像を保持するために使用されるメモリレイアウトに関する。 CMPixelBufferは、最初の240ピクセルがイメージを保持し、余分な80ピクセルがパディングされている行ごとに320ピクセルを割り当てることができます。 この場合、幅は240ピクセル、ストライドは320ピクセルです。

ストライドは通常、あなたがループの中で、画素1のそれぞれの行の上にコピーする必要が意味

+0

他のヒント?「ストライド」とそのCGContextコードとの関係について説明できますか? – jamesfzhang

関連する問題