我用的是前置摄像头,当我捕捉到画面时,它们会逆时针旋转90度。我想在CGContext中旋转捕获的图像(因为我读核心图形比其他框架快得多)。
这是我的代码:
func captureOutput(_ captureOutput: AVCaptureOutput!, didOutputSampleBuffer sampleBuffer: CMSampleBuffer!, from connection: AVCaptureConnection!) {
let imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer)
CVPixelBufferLockBaseAddress(imageBuffer!, CVPixelBufferLockFlags(rawValue: 0))
let width = CVPixelBufferGetWidthOfPlane(imageBuffer!, 0)
let height = CVPixelBufferGetHeightOfPlane(imageBuffer!, 0)
let bytesPerRow = CVPixelBufferGetBytesPerRowOfPlane(imageBuffer!, 0)
let lumaBuffer = CVPixelBufferGetBaseAddressOfPlane(imageBuffer!, 0)
let grayColorSpace = CGColorSpaceCreateDeviceGray()
let context = CGContext(data: lumaBuffer,
width: width,
height: height,
bitsPerComponent: 8,
bytesPerRow: bytesPerRow,
space: grayColorSpace,
bitmapInfo: CGImageAlphaInfo.none.rawValue);
let transform1 = CGAffineTransform(rotationAngle: CGFloat(M_PI_2))
context!.concatenate(transform1)
//context!.rotate(by: CGFloat(M_PI_2)) // also not working!
let dstImage = context!.makeImage()
detect(image: dstImage!)
}
最佳答案
对于任何正在寻找如何以任何角度实际旋转缓冲区的人,这里是您可以做的。将此添加到文件顶部:
static double radians (double degrees) {return degrees * M_PI/180;}
static double ScalingFactorForAngle(double angle, CGSize originalSize) {
double oriWidth = originalSize.height;
double oriHeight = originalSize.width;
double horizontalSpace = fabs( oriWidth*cos(angle) ) + fabs( oriHeight*sin(angle) );
double scalingFactor = oriWidth / horizontalSpace ;
return scalingFactor;
}
CGColorSpaceRef rgbColorSpace = NULL;
CIContext *context = nil;
CIImage *ci_originalImage = nil;
CIImage *ci_transformedImage = nil;
CIImage *ci_userTempImage = nil;
static inline void RotatePixelBufferToAngle(CVPixelBufferRef thePixelBuffer, double theAngle) {
@autoreleasepool {
if (context==nil) {
rgbColorSpace = CGColorSpaceCreateDeviceRGB();
context = [CIContext contextWithOptions:@{kCIContextWorkingColorSpace: (__bridge id)rgbColorSpace,
kCIContextOutputColorSpace : (__bridge id)rgbColorSpace}];
}
long int w = CVPixelBufferGetWidth(thePixelBuffer);
long int h = CVPixelBufferGetHeight(thePixelBuffer);
ci_originalImage = [CIImage imageWithCVPixelBuffer:thePixelBuffer];
ci_userTempImage = [ci_originalImage imageByApplyingTransform:CGAffineTransformMakeScale(0.6, 0.6)];
// CGImageRef UICG_image = [context createCGImage:ci_userTempImage fromRect:[ci_userTempImage extent]];
double angle = theAngle;
angle = angle+M_PI;
double scalingFact = ScalingFactorForAngle(angle, CGSizeMake(w, h));
CGAffineTransform transform = CGAffineTransformMakeTranslation(w/2.0, h/2.0);
transform = CGAffineTransformRotate(transform, angle);
transform = CGAffineTransformTranslate(transform, -w/2.0, -h/2.0);
//rotate it by applying a transform
ci_transformedImage = [ci_originalImage imageByApplyingTransform:transform];
CVPixelBufferLockBaseAddress(thePixelBuffer, 0);
CGRect extentR = [ci_transformedImage extent];
CGPoint centerP = CGPointMake(extentR.size.width/2.0+extentR.origin.x,
extentR.size.height/2.0+extentR.origin.y);
CGSize scaledSize = CGSizeMake(w*scalingFact, h*scalingFact);
CGRect cropRect = CGRectMake(centerP.x-scaledSize.width/2.0, centerP.y-scaledSize.height/2.0,
scaledSize.width, scaledSize.height);
CGImageRef cg_img = [context createCGImage:ci_transformedImage fromRect:cropRect];
ci_transformedImage = [CIImage imageWithCGImage:cg_img];
ci_transformedImage = [ci_transformedImage imageByApplyingTransform:CGAffineTransformMakeScale(1.0/scalingFact, 1.0/scalingFact)];
[context render:ci_transformedImage toCVPixelBuffer:thePixelBuffer bounds:CGRectMake(0, 0, w, h) colorSpace:NULL];
CGImageRelease(cg_img);
CVPixelBufferUnlockBaseAddress(thePixelBuffer, 0);
}
}
转到captureOutput:CaptureOutputDidOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection*)连接并应用函数:
CVPixelBufferRef pixBuf = CMSampleBufferGetImageBuffer(sampleBuffer);
RotatePixelBufferToAngle(pixBuf, radians(45.0));
其中45.0-是所需的角度
注意,这不仅是旋转,而且还可以缩放图像,使其填充视频维度(类似于方面填充)。可以通过修改scalingFact变量来关闭缩放。
关于ios - 从CGContext中的Samplebuffer旋转捕获的帧,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/40918526/