gpt4 book ai didi

ios - 使用像素数据创建 CVPixelBuffer,但最终图像失真

转载 作者:可可西里 更新时间:2023-11-01 04:56:05 26 4
gpt4 key购买 nike

我通过 OpenGLES 方法(glReadPixels)或其他方式获取像素,然后创建 CVPixelBuffer(带或不带 CGImage)用于视频录制,但最终图片失真。当我在 iPhone 5c、5s 和 6 上测试时,这发生在 iPhone6 上。

看起来像:

enter image description here

代码如下:

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

最佳答案

注意 - 此答案将整体问题与图像联系起来,而不是与特定代码联系起来。

这类问题通常是“步幅”,与用于保存图像的内存布局有关,其中每一行像素都没有紧密排列在一起

例如,源图像可能是 240 像素宽。CMPixelBuffer 可以为每行分配 320 个像素,其中前 240 个像素保存图像,额外的 80 个像素用于填充。在这种情况下,宽度为 240 像素,步幅为 320 像素。

步幅通常意味着您必须循环复制每一行像素

关于ios - 使用像素数据创建 CVPixelBuffer,但最终图像失真,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37084307/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com