ios - ios AVFoundation 中的 Zxing 缩放功能

标签 ios avfoundation barcode zxing barcode-scanner

我一直在网上搜索,并一直在寻找任何类型的代码来帮助我使用 ZXing 放大条形码。

我从他们的 git 站点的代码开始

https://github.com/zxing/zxing

从那时起,我已经能够将默认分辨率提高到 1920x1080。

self.captureSession.sessionPreset = AVCaptureSessionPreset1920x1080;

这很好,但问题是我正在扫描非常小的条形码,即使 1920x1080 可以工作,它也没有给我任何缩放来捕捉更接近更小的条形码而不会失去焦点。现在该决议确实帮助了我很多,但它根本不够接近。

我在想我需要做的是将捕获 session 设置为 1920x1080 的 ScrollView ,然后将实际的图像捕获设置为从我的屏幕边界获取,这样我就可以放大和缩小 ScrollView 本身以实现“缩放”的影响。

问题在于我真的不知道从哪里开始......有什么想法吗?

最佳答案

好的,因为我在这里多次看到这个,似乎没有人有答案。我想我会分享我自己的答案。

似乎没有人知道 2 个属性。两者都覆盖。

现在第一个适用于 iOS 6+。 Apple 添加了一个名为 setVideoScaleAndCropfactor 的属性。

此设置返回一个 this 是 CGFloat 类型。唯一的缺点是您必须将值设置为 AVConnection,然后将连接设置为 StillImageCapture。它不适用于 iOS 6 中的任何其他内容。现在,为了做到这一点,您必须将其设置为异步工作,并且您必须循环代码以使解码器工作并以该比例拍摄照片。

最后一件事是您必须自己缩放预览图层。

这一切听起来像很多工作。它真的是。但是,这会将您的原始扫描图片设置为 1920x1080 或您设置的任何值。而不是缩放将拉伸(stretch)像素导致解码器错过条形码的当前图像。

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 中的第二个将改变我刚才所说的一切。您有一个名为 videoZoomFactor 的新属性。这是一个 CGFloat。然而,它改变了堆栈顶部的所有内容,而不仅仅是像静止图像捕获那样影响。

换句话说,您不必手动缩放预览层。您不必经过一些静止图像捕获循环,也不必将其设置为 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];

}

希望这可以帮助某人!我可能会继续观看有关此的视频教程。我猜这取决于对它有什么样的需求。

关于ios - ios AVFoundation 中的 Zxing 缩放功能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16681952/

相关文章:

ios - 如何使用 [String : Any] parameters 构造多部分表单数据请求

ios - Swift 对象数组过滤

ios - 使用长按手势与 AVFoundation 开始停止录制

iphone - 使用不四舍五入的 CMTime?

php - 如何使用 PHP 生成条形码并将其显示为同一页面上的图像

java - 生成并使用 PDF 底部的条形码

ios - 特定日期格式的日期格式化程序

ios - CollectionView 的单元格不适合屏幕

ios - 检测带有圆角的卡片边缘

java - java swing 应用程序中的条形码扫描在嵌入式选项卡控制字符上间歇性失败