6

OpenGLES メソッド (glReadPixels) またはその他の方法でピクセルを取得し、ビデオ録画用に CVPixelBuffer (CGImage の有無にかかわらず) を作成しますが、最終的な画像は歪んでいます。これは、iPhone 5c、5s、および 6 でテストしたときに iPhone6 で発生します。

次のようになります。

ここに画像の説明を入力

コードは次のとおりです。

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);
4

3 に答える 3

1

私は同じ問題を抱えていましたが、解決策は次のとおりだと思います: CGBitmapContextCreate 呼び出しでに変更CGImageGetBytesPerRow(imageRef)してみてください。CVPixelBufferGetBytesPerRow(pxbuffer)その理由は、描画している CGImage ではなく、作成したピクセル バッファーの生データでコンテキストがサポートされているためです。CVPixelBuffer の 1 行あたりのバイト数は、1 ピクセルあたりのバイト数 * ピクセル バッファー幅よりも大きくなる場合があります。

于 2019-02-28T17:02:57.833 に答える