J'ai besoin d'get le UIImage
partir de données d'image non compressées de CMSampleBufferRef. J'utilise le code:
captureStillImageOutput captureStillImageAsynchronouslyFromConnection:connection completionHandler:^(CMSampleBufferRef imageSampleBuffer, NSError *error) { // that famous function from Apple docs found on a lot of websites // does NOT work for still images UIImage *capturedImage = [self imageFromSampleBuffer:imageSampleBuffer]; }
http://developer.apple.com/library/ios/#qa/qa1702/_index.html est un lien vers la fonction imageFromSampleBuffer
.
Mais cela ne fonctionne pas correctement. 🙁
Il existe une méthode jpegStillImageNSDataRepresentation:imageSampleBuffer
, mais elle donne datatables compressées (enfin, parce que JPEG).
Comment puis-je créer UIImage
avec datatables non compressées les plus brutes après la capture de Still Image?
Peut-être, je devrais spécifier quelques parameters à la sortie video? J'utilise actuellement ceux:
captureStillImageOutput = [[AVCaptureStillImageOutput alloc] init]; captureStillImageOutput.outputSettings = @{ (id)kCVPixelBufferPixelFormatTypeKey : @(kCVPixelFormatType_32BGRA) };
J'ai remarqué, cette sortie a une valeur par défaut pour AVVideoCodecKey
, qui est AVVideoCodecJPEG
. Peut-il être évité de quelque façon que ce soit, ou est-ce important quand on capture une image fixe?
J'ai trouvé quelque chose là: Les données d'image brutes de la camera comme "645 PRO" , mais j'ai juste besoin d'un UIImage, sans utiliser OpenCV ou OGLES ou autre tiers.
La méthode imageFromSampleBuffer
fonctionne en fait J'utilise une version modifiée de celle-ci, mais si je me souviens bien, vous devez régler correctement les parameters de sortie. Je pense que vous devez définir la key comme kCVPixelBufferPixelFormatTypeKey
et la valeur comme kCVPixelFormatType_32BGRA
.
Donc par exemple:
NSSsortingng* key = (NSSsortingng*)kCVPixelBufferPixelFormatTypeKey; NSNumber* value = [NSNumber numberWithUnsignedInt:kCVPixelFormatType_32BGRA]; NSDictionary* outputSettings = [NSDictionary dictionaryWithObject:value forKey:key]; [newStillImageOutput setOutputSettings:outputSettings];
MODIFIER
J'utilise ces parameters pour prendre stillImages pas video. Est-ce que votre sessionPreset AVCaptureSessionPresetPhoto? Il peut y avoir des problèmes avec ça
AVCaptureSession *newCaptureSession = [[AVCaptureSession alloc] init]; [newCaptureSession setSessionPreset:AVCaptureSessionPresetPhoto];
EDIT 2
La partie sur l'logging de UIImage est identique à celle de la documentation. C'est la raison pour laquelle je demandais d'autres origines du problème, mais je suppose que c'était juste pour les pailles. Il y a un autre moyen que je connais, mais cela nécessite OpenCV.
- (UIImage *) imageFromSampleBuffer:(CMSampleBufferRef) sampleBuffer{ CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer); CVPixelBufferLockBaseAddress(imageBuffer, 0); void *baseAddress = CVPixelBufferGetBaseAddress(imageBuffer); // Get the number of bytes per row for the pixel buffer size_t bytesPerRow = CVPixelBufferGetBytesPerRow(imageBuffer); // Get the pixel buffer width and height size_t width = CVPixelBufferGetWidth(imageBuffer); size_t height = CVPixelBufferGetHeight(imageBuffer); // Create a device-dependent RGB color space CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); // Create a bitmap graphics context with the sample buffer data CGContextRef context = CGBitmapContextCreate(baseAddress, width, height, 8, bytesPerRow, colorSpace, kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedFirst); // Create a Quartz image from the pixel data in the bitmap graphics context CGImageRef quartzImage = CGBitmapContextCreateImage(context); // Unlock the pixel buffer CVPixelBufferUnlockBaseAddress(imageBuffer,0); // Free up the context and color space CGContextRelease(context); CGColorSpaceRelease(colorSpace); // Create an image object from the Quartz image UIImage *image = [UIImage imageWithCGImage:quartzImage]; // Release the Quartz image CGImageRelease(quartzImage); return (image); }
Je suppose que cela ne vous aide pas, désolé. Je ne sais pas assez pour penser à d'autres origines pour votre problème.
Voici un moyen plus efficace:
UIImage *image = [UIImage imageWithData:[self imageToBuffer:sampleBuffer]]; - (NSData *) imageToBuffer:(CMSampleBufferRef)source { CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(source); CVPixelBufferLockBaseAddress(imageBuffer,0); size_t bytesPerRow = CVPixelBufferGetBytesPerRow(imageBuffer); size_t width = CVPixelBufferGetWidth(imageBuffer); size_t height = CVPixelBufferGetHeight(imageBuffer); void *src_buff = CVPixelBufferGetBaseAddress(imageBuffer); NSData *data = [NSData dataWithBytes:src_buff length:bytesPerRow * height]; CVPixelBufferUnlockBaseAddress(imageBuffer, 0); return data; }