私はUIImagePickerControllerを使ってiPhoneで写真を撮っています。その場で写真を調整したいのですが、UIImagePickerControllerを使ってその場で写真の形を調整することができますが、その場で色を変更する方法は見つけられません。たとえば、すべての色を白黒に変更します。iPhoneカメラのプレビューウィンドウでピクセルの色を変更する方法は?
ありがとうございました。
私はUIImagePickerControllerを使ってiPhoneで写真を撮っています。その場で写真を調整したいのですが、UIImagePickerControllerを使ってその場で写真の形を調整することができますが、その場で色を変更する方法は見つけられません。たとえば、すべての色を白黒に変更します。iPhoneカメラのプレビューウィンドウでピクセルの色を変更する方法は?
ありがとうございました。
これを行う最もよい方法は、AVCaptureSessionオブジェクトを使用することです。私はフリーアプリ "Live Effects Cam"であなたが話していることをまさにやっています
これを実装するのに役立ついくつかのコード例があります。
- (void) activateCameraFeed
{
videoSettings = nil;
#if USE_32BGRA
pixelFormatCode = [[NSNumber alloc] initWithUnsignedInt:(unsigned int)kCVPixelFormatType_32BGRA];
pixelFormatKey = [[NSString alloc] initWithString:(NSString *)kCVPixelBufferPixelFormatTypeKey];
videoSettings = [[NSDictionary alloc] initWithObjectsAndKeys:pixelFormatCode, pixelFormatKey, nil];
#endif
videoDataOutputQueue = dispatch_queue_create("com.jellyfilledstudios.ImageCaptureQueue", NULL);
captureVideoOutput = [[AVCaptureVideoDataOutput alloc] init];
[captureVideoOutput setAlwaysDiscardsLateVideoFrames:YES];
[captureVideoOutput setSampleBufferDelegate:self queue:videoDataOutputQueue];
[captureVideoOutput setVideoSettings:videoSettings];
[captureVideoOutput setMinFrameDuration:kCMTimeZero];
dispatch_release(videoDataOutputQueue); // AVCaptureVideoDataOutput uses dispatch_retain() & dispatch_release() so we can dispatch_release() our reference now
if (useFrontCamera)
{
currentCameraDeviceIndex = frontCameraDeviceIndex;
cameraImageOrientation = UIImageOrientationLeftMirrored;
}
else
{
currentCameraDeviceIndex = backCameraDeviceIndex;
cameraImageOrientation = UIImageOrientationRight;
}
selectedCamera = [[AVCaptureDevice devices] objectAtIndex:(NSUInteger)currentCameraDeviceIndex];
captureVideoInput = [AVCaptureDeviceInput deviceInputWithDevice:selectedCamera error:nil];
captureSession = [[AVCaptureSession alloc] init];
[captureSession beginConfiguration];
[self setCaptureConfiguration];
[captureSession addInput:captureVideoInput];
[captureSession addOutput:captureVideoOutput];
[captureSession commitConfiguration];
[captureSession startRunning];
}
// AVCaptureVideoDataOutputSampleBufferDelegate
// AVCaptureAudioDataOutputSampleBufferDelegate
//
- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
if (captureOutput==captureVideoOutput)
{
[self performImageCaptureFrom:sampleBuffer fromConnection:connection];
}
[pool drain];
}
- (void) performImageCaptureFrom:(CMSampleBufferRef)sampleBuffer
{
CVImageBufferRef imageBuffer;
if (CMSampleBufferGetNumSamples(sampleBuffer) != 1)
return;
if (!CMSampleBufferIsValid(sampleBuffer))
return;
if (!CMSampleBufferDataIsReady(sampleBuffer))
return;
imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer);
if (CVPixelBufferGetPixelFormatType(imageBuffer) != kCVPixelFormatType_32BGRA)
return;
CVPixelBufferLockBaseAddress(imageBuffer,0);
uint8_t *baseAddress = (uint8_t *)CVPixelBufferGetBaseAddress(imageBuffer);
size_t bytesPerRow = CVPixelBufferGetBytesPerRow(imageBuffer);
size_t width = CVPixelBufferGetWidth(imageBuffer);
size_t height = CVPixelBufferGetHeight(imageBuffer);
int bufferSize = bytesPerRow * height;
uint8_t *tempAddress = malloc(bufferSize);
memcpy(tempAddress, baseAddress, bytesPerRow * height);
baseAddress = tempAddress;
//
// Apply affects to the pixels stored in (uint32_t *)baseAddress
//
//
// example: grayScale((uint32_t *)baseAddress, width, height);
// example: sepia((uint32_t *)baseAddress, width, height);
//
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef newContext = nil;
if (cameraDeviceSetting != CameraDeviceSetting640x480) // not an iPhone4 or iTouch 5th gen
newContext = CGBitmapContextCreate(baseAddress, width, height, 8, bytesPerRow, colorSpace, kCGBitmapByteOrder32Little | kCGImageAlphaNoneSkipFirst);
else
newContext = CGBitmapContextCreate(baseAddress, width, height, 8, bytesPerRow, colorSpace, kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedFirst);
CGImageRef newImage = CGBitmapContextCreateImage(newContext);
CGColorSpaceRelease(colorSpace);
CGContextRelease(newContext);
free(tempAddress);
CVPixelBufferUnlockBaseAddress(imageBuffer,0);
if (newImage == nil)
{
return;
}
// To be able to display the CGImageRef newImage in your UI you will need to do it like this
// because you are running on a different thread here…
//
[self performSelectorOnMainThread:@selector(newCameraImageNotification:) withObject:(id)newImage waitUntilDone:YES];
}
イメージにビューをオーバーレイし、ブレンディングモードを黒/白の効果に合わせて変更できます。
はこれを行うには
もう一つの方法は、AVFoundation
を使用して各フレームに変換することです、特にそのデモでは、アップルからBlending Modes
例をQuartzDemoをチェックしてください。私はこれに多大な経験はありませんが、WWDC2010のビデオ "セッション409 - AVFoundationでカメラを使用する"とそのサンプルプロジェクトは、あなたの問題を解決するのに役立つはずです。
もちろん、iOS4クラスを使用しても問題ありません。
あなたのライブエフェクトカムを試してみましたが、それは素晴らしいと私は実装しようとしていたより多くの機能があります。よくやった!ただそれが無料であることにちょうど驚いた。 – BlueDolphin
ありがとうございます。私は99セントで、1日に平均1500ダウンロードを超えると、1日に50ダウンロードを下回ります。私は、新機能について最も求められているアプリの購入を含むアップデートをリリースしています。私は今日、新しいアプリを開発している人に、アプリ内購入の方法で無料アプリをおすすめします。 –