2012-01-26 41 views
18

Điều này có vẻ như là một nhiệm vụ đơn giản, nhưng nó là lái xe cho tôi hạt. Có thể chuyển đổi UIView chứa AVCaptureVideoPreviewLayer thành một lớp con thành hình ảnh được lưu không? Tôi muốn tạo lớp phủ thực tế gia tăng và có nút lưu ảnh vào thư viện ảnh. Giữ nút nguồn + phím chủ ghi lại ảnh chụp màn hình vào cuộn camera, nghĩa là tất cả logic chụp của tôi đang hoạt động và tác vụ có thể thực hiện được. Nhưng tôi dường như không thể làm cho nó hoạt động theo chương trình.Có thể hiển thị AVCaptureVideoPreviewLayer trong ngữ cảnh đồ họa không?

Tôi đang chụp bản xem trước trực tiếp hình ảnh của máy ảnh bằng AVCaptureVideoPreviewLayer. Tất cả các nỗ lực của tôi để hiển thị hình ảnh không thành công:

previewLayer = [AVCaptureVideoPreviewLayer layerWithSession:captureSession]; 
//start the session, etc... 


//this saves a white screen 
- (IBAction)saveOverlay:(id)sender { 
    NSLog(@"saveOverlay"); 

    UIGraphicsBeginImageContext(appDelegate.window.bounds.size); 
     UIGraphicsBeginImageContext(scrollView.frame.size); 

    [previewLayer.presentationLayer renderInContext:UIGraphicsGetCurrentContext()]; 


// [appDelegate.window.layer renderInContext:UIGraphicsGetCurrentContext()]; 

    UIImage *screenshot = UIGraphicsGetImageFromCurrentImageContext(); 
    UIGraphicsEndImageContext(); 

    UIImageWriteToSavedPhotosAlbum(screenshot, self, 
            @selector(image:didFinishSavingWithError:contextInfo:), nil); 
} 

// điều này hiển thị mọi thứ, XÁC NHẬN cho lớp xem trước trống.

[appDelegate.window.layer renderInContext:UIGraphicsGetCurrentContext()]; 

Tôi đã đọc ở đâu đó rằng điều này có thể do sự cố bảo mật của iPhone. Điều này có đúng không?

Chỉ cần rõ ràng: Tôi không muốn lưu hình ảnh cho máy ảnh. Tôi muốn lưu lớp xem trước trong suốt chồng lên trên một hình ảnh khác, do đó tạo ra độ trong suốt. Tuy nhiên, vì một lý do nào đó tôi không thể làm cho nó hoạt động.

Trả lời

4

Tôi có thể khuyên bạn dùng thử Hình ảnh GPU.

https://github.com/BradLarson/GPUImage

Nó sử dụng OpenGL, vì vậy nó khá nhanh. Nó có thể xử lý hình ảnh từ máy ảnh và thêm bộ lọc cho chúng (có rất nhiều ảnh), bao gồm phát hiện cạnh, phát hiện chuyển động và nhiều hơn nữa

Giống như OpenCV nhưng dựa trên hình ảnh GPU của tôi dễ dàng kết nối với dự án của bạn và ngôn ngữ là mục tiêu-c.

Vấn đề có thể xuất hiện nếu bạn quyết định sử dụng Box2D cho vật lý - là sử dụng OpenGL quá và bạn sẽ cần phải dành thời gian cho đến khi 2 khung này sẽ ngừng chiến đấu))

+0

Tôi đoán những gì OP và tôi đang cố gắng, là để có được một nguồn cấp video trực tiếp sử dụng avcapturevideopreviewlayer và đang cố gắng để thêm một hình ảnh thu nhỏ lại. Tôi đang cố gắng thêm hình ảnh được chia tỷ lệ lên trên nguồn cấp dữ liệu video trực tiếp dựa trên phát hiện khuôn mặt và ảnh chụp màn hình được lưu chỉ là hình ảnh của lớp phủ chứ không phải là avcapturevideopreviewlayer. –

+0

Trong hình ảnh GPU có thêm bộ lọc trên các lớp vì vậy tôi khá chắc chắn có cách để lưu chỉ lớp hiện tại (có phương pháp trong GPU Hình ảnh để làm cho UIImage từ khung) Nếu bạn muốn nhận được chỉ là những gì trên màn hình - đó là cách để làm cho ảnh chụp màn hình programmatically.I không thể nhớ nó bây giờ nhưng tôi đã nhìn thấy nó trên stackoverflow) – Roma

+0

Roma, cảm ơn bạn rất nhiều vì câu trả lời của bạn. Mặc dù tôi không sử dụng GPUImage, tôi chắc chắn sẽ sớm sử dụng nó. Cảm ơn bạn đã đăng bài dưới dạng tùy chọn thay thế. –

15

Tôi thích @ đề nghị sử dụng GPU ảnh Roma - ý tưởng tuyệt vời. . . . tuy nhiên nếu bạn muốn có một cách tiếp cận CocoaTouch tinh khiết, đây là những điều cần làm:

Thực hiện AVCaptureVideoDataOutputSampleBufferDelegate

- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer 
fromConnection:(AVCaptureConnection *)connection 
{ 
    // Create a UIImage+Orientation from the sample buffer data 
    if (_captureFrame) 
    { 
     [captureSession stopRunning]; 

     _captureFrame = NO; 
     UIImage *image = [ImageTools imageFromSampleBuffer:sampleBuffer]; 
     image = [image rotate:UIImageOrientationRight]; 

     _frameCaptured = YES; 

     if (delegate != nil) 
     { 
      [delegate cameraPictureTaken:image]; 
     } 
    } 
} 

Capture như sau:

+ (UIImage *) imageFromSampleBuffer:(CMSampleBufferRef) sampleBuffer 
{ 
    // Get a CMSampleBuffer's Core Video image buffer for the media data 
    CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer); 
    // Lock the base address of the pixel buffer 
    CVPixelBufferLockBaseAddress(imageBuffer, 0); 

    // Get the number of bytes per row for the pixel buffer 
    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); 
} 

Blend UIImage với lớp phủ

  • Bây giờ bạn có UIImage, hãy thêm nó vào UIView mới.
  • Thêm lớp phủ ở trên cùng dưới dạng chế độ xem phụ.

Capture các UIView mới

+ (UIImage*)imageWithView:(UIView*)view 
{ 
    UIGraphicsBeginImageContextWithOptions(view.bounds.size, view.opaque, [UIScreen mainScreen].scale); 
    [view.layer renderInContext:UIGraphicsGetCurrentContext()]; 
    UIImage* img = UIGraphicsGetImageFromCurrentImageContext(); 
    UIGraphicsEndImageContext(); 
    return img; 
} 
+0

Tôi nghĩ rằng đây là những gì tôi đang tìm kiếm. Sẽ cố gắng để có được điều này chạy và cho bạn biết làm thế nào nó đi. Cảm ơn vì sớm phản hồi! –

+0

bạn đang sử dụng phần mở rộng uiimage cho image = [image rotate: UIImageOrientationRight]; ? –

+0

Có, bước đó là tùy chọn. Tuy nhiên, hãy để tôi cung cấp cho bạn mã. –

Các vấn đề liên quan