1

私はインターネットを精査しており、ZXing を使用してバーコードを拡大するのに役立つあらゆる種類のコードを探していました。

ここのgitサイトのコードから始めました

https://github.com/zxing/zxing

それ以来、デフォルトの解像度を 1920x1080 に上げることができました。

self.captureSession.sessionPreset = AVCaptureSessionPreset1920x1080;

これは問題ありませんが、問題は、非常に小さなバーコードをスキャンしていて、1920x1080 が機能しても、焦点を失うことなく小さなバーコードに近づいてキャプチャするためのズームが得られないことです。解決策はかなり役に立ちましたが、それだけでは十分ではありません。

私がする必要があるのは、キャプチャ セッションを 1920x1080 のスクロール ビューに設定し、実際の画像キャプチャを画面の境界から取得するように設定して、スクロール ビュー自体をズームインおよびズームアウトして、 「ズーム」のような影響。

それに関する問題は、どこから始めればよいかわからないということです...何かアイデアはありますか?

4

1 に答える 1

3

ここでこれを何度も見たので、誰も答えを持っていないようです。私は私自身の答えを共有すると思いました。

誰も知らないと思われる 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];

}

これが誰かを助けることを願っています! 私は先に進み、これに関するビデオチュートリアルに進むかもしれません. どのような需要があるかにもよると思います。

于 2013-06-27T07:46:39.313 に答える