2016-05-07 12 views
4

Ich bekomme Pixel durch OpenGLES-Methode (glReadPixels) oder andere Weise, dann erstellen CVPixelBuffer (mit oder ohne CGImage) für die Videoaufnahme, aber das endgültige Bild ist verzerrt. Dies geschieht auf iPhone6 ​​wenn ich testen, auf dem iPhone 5c, 5 und 6.Erstellen CVPixelBuffer mit Pixeldaten, aber das endgültige Bild ist verzerrt

Es sieht aus wie:

enter image description here

Hier ist der Code:

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

Auch dieses Problem auftritt ... :( – jamesfzhang

+0

konnte ich dieses Problem beheben, indem sichergestellt wird, dass jeder Rahmen genau die gleichen Dimensionen Einige der Frames hatten eine etwas andere Größe, was zu Verzerrungen führte – jamesfzhang

Antwort

0

Hinweis - diese Antwort bezieht sich die Gesamtproblem mit dem Bild und nicht mit dem spezifischen Code.

Diese Art von Problem ist in der Regel die ‚stride‘ und bezieht sich auf das Speicherlayout verwendet, um das Bild zu halten, wobei jede Zeile von Pixeln nicht dicht zusammengepackt

Als Beispiel das Quellbild 240 Pixel breit sein kann, . Der CMPixelBuffer kann 320 Pixel für jede Zeile zuweisen, wobei die ersten 240 Pixel das Bild halten und die zusätzlichen 80 Pixel auffüllen. In diesem Fall beträgt die Breite 240 Pixel, die Schrittweite beträgt 320 Pixel.

Strides in der Regel meinen Sie über jede Zeile von Pixeln in einer Schleife zu kopieren haben

+0

Irgendwelche anderen Tipps Können Sie "Schritt" erklären und wie es sich auf den CGContext-Code bezieht? – jamesfzhang