ここでこれを何度も見たので、誰も答えを持っていないようです。私は私自身の答えを共有すると思いました。
誰も知らないと思われる 2 つのプロパティがあります。両方をカバーします。
現在、最初のものは iOS 6+ に適しています。Apple は setVideoScaleAndCropfactor というプロパティを追加しました。
この設定はこれを返します。これは CGFloat タイプです。これの唯一の欠点は、値を AVConnection に設定してから、接続を stillImageCapture に設定する必要があることです。iOS 6 の他のものでは動作しません。これを行うには、非同期で動作するように設定する必要があり、デコーダーが動作するようにコードをループして、そのスケールで写真を撮る必要があります。
最後に、プレビュー レイヤーを自分でスケーリングする必要があります。
これはすべて大変な作業のように聞こえます。そして、それは本当にそうです。ただし、これにより、元のスキャン画像が 1920x1080 または設定したもので撮影されるように設定されます。ピクセルを引き伸ばす現在の画像をスケーリングするのではなく、デコーダーがバーコードを見逃す原因となります。
SPこれは次のようになります
stillImageConnection = [stillImageOutput connectionWithMediaType:AVMediaTypeVideo];
[stillImageConnection setVideoOrientation:AVCaptureVideoOrientationPortrait];
[stillImageConnection setVideoScaleAndCropFactor:effectiveScale];
[stillImageOutput setOutputSettings:[NSDictionary dictionaryWithObject:[NSNumber numberWithInt:kCMPixelFormat_32BGRA]
forKey:(id)kCVPixelBufferPixelFormatTypeKey]];
[stillImageOutput captureStillImageAsynchronouslyFromConnection:stillImageConnection
completionHandler:^(CMSampleBufferRef imageDataSampleBuffer, NSError *error)
{
if(error)
return;
NSString *path = [NSString stringWithFormat:@"%@%@",
[[NSBundle mainBundle] resourcePath],
@"/blank.wav"];
SystemSoundID soundID;
NSURL *filePath = [NSURL fileURLWithPath:path isDirectory:NO];
AudioServicesCreateSystemSoundID(( CFURLRef)filePath, &soundID);
AudioServicesPlaySystemSound(soundID);
CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(imageDataSampleBuffer);
/*Lock the image buffer*/
CVPixelBufferLockBaseAddress(imageBuffer,0);
/*Get information about the image*/
size_t bytesPerRow = CVPixelBufferGetBytesPerRow(imageBuffer);
size_t width = CVPixelBufferGetWidth(imageBuffer);
size_t height = CVPixelBufferGetHeight(imageBuffer);
uint8_t* baseAddress = CVPixelBufferGetBaseAddress(imageBuffer);
void* free_me = 0;
if (true) { // iOS bug?
uint8_t* tmp = baseAddress;
int bytes = bytesPerRow*height;
free_me = baseAddress = (uint8_t*)malloc(bytes);
baseAddress[0] = 0xdb;
memcpy(baseAddress,tmp,bytes);
}
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef newContext =
CGBitmapContextCreate(baseAddress, width, height, 8, bytesPerRow, colorSpace,
kCGBitmapByteOrder32Little | kCGImageAlphaNoneSkipFirst);
CGImageRef capture = CGBitmapContextCreateImage(newContext);
CVPixelBufferUnlockBaseAddress(imageBuffer,0);
free(free_me);
CGContextRelease(newContext);
CGColorSpaceRelease(colorSpace);
Decoder* d = [[Decoder alloc] init];
[self decoding:d withimage:&capture];
}];
}
iOS 7 で登場する 2 番目の機能は、これまで述べてきたことすべてを変更します。videoZoomFactor という新しいプロパティがあります。これは CGFloat です。ただし、静止画キャプチャのように影響を与えるだけでなく、スタックの上部にあるすべてを変更します。
つまり、プレビュー レイヤーを手動でズームする必要はありません。stillimagecaptureloop を通過する必要はなく、AVConnection に設定する必要もありません。CGFloat を設定するだけで、すべてがスケーリングされます。
iOS 7 アプリケーションを公開できるようになるまでには、しばらく時間がかかることがわかりました。ですから、これを難しい方法で行う方法を真剣に検討します。簡単なヒント。ピンチとズームのジェスチャを使用して、setvideoscaleandcropfactor の CGFloat を設定します。didload で値を 1 に設定することを忘れないでください。そこからスケーリングできます。ジェスチャで同時に、それを使用して CATransaction を実行し、プレビュー レイヤーをスケーリングできます。
ジェスチャ キャプチャとプレビュー レイヤーの実行方法のサンプルを次に示します。
- (IBAction)handlePinchGesture:(UIPinchGestureRecognizer *)recognizer
{
effectiveScale = recognizer.scale;
if (effectiveScale < 1.0)
effectiveScale = 1.0;
if (effectiveScale > 25)
effectiveScale = 25;
stillImageConnection = [stillImageOutput connectionWithMediaType:AVMediaTypeVideo];
[stillImageConnection setVideoScaleAndCropFactor:effectiveScale];
[CATransaction begin];
[CATransaction setAnimationDuration:0];
[prevLayer setAffineTransform:CGAffineTransformMakeScale(effectiveScale, effectiveScale)];
[CATransaction commit];
}
これが誰かを助けることを願っています! 私は先に進み、これに関するビデオチュートリアルに進むかもしれません. どのような需要があるかにもよると思います。