在ARSCNView中,有ARSession,在代码中增加ARSessionDelegate。代码如下:
- (void)session:(ARSession *)session didUpdateFrame:(ARFrame *)frame
{
CVPixelBufferRef pixelBuffer = frame.capturedImage;
self.cubeTexture=[self textureCubeWithImage:[self uiImageFromPixelBuffer:pixelBuffer width:512 height:512] device:self.device];
}
CVPixelBufferRef转成UIImage:
- (UIImage*)uiImageFromPixelBuffer:(CVPixelBufferRef)p width:(CGFloat)width height:(CGFloat)height {
CIImage* ciImage = [CIImage imageWithCVPixelBuffer:p];
CIContext* context = [CIContext contextWithOptions:@{kCIContextUseSoftwareRenderer : @(YES)}];
// CGRect rect = CGRectMake(0, 0, CVPixelBufferGetWidth(p), CVPixelBufferGetHeight(p));
// NSLog(@"width%zu",CVPixelBufferGetWidth(p));1280
//NSLog(@"height%zu",CVPixelBufferGetHeight(p));720
CGRect rect = CGRectMake(0, 0, width, height);
CGImageRef videoImage = [context createCGImage:ciImage fromRect:rect];
UIImage* image = [UIImage imageWithCGImage:videoImage];
CGImageRelease(videoImage);
return image;
}
另外两个方法:
- (id<MTLTexture>)textureCubeWithImage:(UIImage *)image device:(id<MTLDevice>)device
{
const CGFloat cubeSize = image.size.width * image.scale;
const NSUInteger bytesPerPixel = 4;
const NSUInteger bytesPerRow = bytesPerPixel * cubeSize;
const NSUInteger bytesPerImage = bytesPerRow * cubeSize;
MTLRegion region = MTLRegionMake2D(0, 0, cubeSize, cubeSize);
MTLTextureDescriptor *textureDescriptor = [MTLTextureDescriptor textureCubeDescriptorWithPixelFormat:MTLPixelFormatRGBA8Unorm
size:cubeSize
mipmapped:NO];
id<MTLTexture> texture = [device newTextureWithDescriptor:textureDescriptor];
uint8_t *imageData = [self dataForImage:image];
for (size_t slice = 0; slice < 6; ++slice)
{
NSAssert(image.size.width == cubeSize && image.size.height == cubeSize, @"Cube map images must be square and uniformly-sized");
[texture replaceRegion:region
mipmapLevel:0
slice:slice
withBytes:imageData
bytesPerRow:bytesPerRow
bytesPerImage:bytesPerImage];
}
free(imageData);
return texture;
}
- (uint8_t *)dataForImage:(UIImage *)image
{
CGImageRef imageRef = [image CGImage];
// Create a suitable bitmap context for extracting the bits of the image
const NSUInteger width = CGImageGetWidth(imageRef);
const NSUInteger height = CGImageGetHeight(imageRef);
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
uint8_t *rawData = (uint8_t *)calloc(height * width * 4, sizeof(uint8_t));
const NSUInteger bytesPerPixel = 4;
const NSUInteger bytesPerRow = bytesPerPixel * width;
const NSUInteger bitsPerComponent = 8;
CGContextRef context = CGBitmapContextCreate(rawData, width, height,
bitsPerComponent, bytesPerRow, colorSpace,
kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);
CGColorSpaceRelease(colorSpace);
CGContextDrawImage(context, CGRectMake(0, 0, width, height), imageRef);
CGContextRelease(context);
return rawData;
}