Skip to content

Commit

Permalink
New: Save image to photos; Scan QRCode from image;
Browse files Browse the repository at this point in the history
  • Loading branch information
CareVPN committed Feb 12, 2016
1 parent 02360ad commit a758982
Show file tree
Hide file tree
Showing 4 changed files with 148 additions and 12 deletions.
2 changes: 1 addition & 1 deletion ShadowVPN/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
}

func application(app: UIApplication, openURL url: NSURL, options: [String : AnyObject]) -> Bool {
if url.scheme == "shadowVPN" {
if url.scheme == "shadowvpn" {
NSNotificationCenter.defaultCenter().postNotificationName(enableCurrentVPNManagerVPNStateFromWidget,
object: nil, userInfo: ["command": url.host!])
}
Expand Down
4 changes: 3 additions & 1 deletion ShadowVPN/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,13 @@
<dict>
<key>CFBundleTypeRole</key>
<string>Editor</string>
<key>CFBundleURLIconFile</key>
<string></string>
<key>CFBundleURLName</key>
<string>shadowVPN.iOS</string>
<key>CFBundleURLSchemes</key>
<array>
<string>shadowVPN</string>
<string>shadowvpn</string>
</array>
</dict>
</array>
Expand Down
97 changes: 90 additions & 7 deletions ShadowVPN/QRCodeReaderVC.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,24 @@

import UIKit
import AVFoundation
import Photos


let SCREEN_HEIGHT = UIScreen.mainScreen().bounds.height
let SCREEN_WIDTH = UIScreen.mainScreen().bounds.width


class QRCodeReaderVC: UIViewController, AVCaptureMetadataOutputObjectsDelegate {
class QRCodeReaderVC: UIViewController, AVCaptureMetadataOutputObjectsDelegate, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
var captureSession: AVCaptureSession?
var captureVideoPreviewLayer: AVCaptureVideoPreviewLayer?
var focusFrame: UIView?
var delegate: QRCodeWriteBackDelegate?

override func viewDidLoad() {
super.viewDidLoad()
self.navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Albums", style: UIBarButtonItemStyle.Plain, target: self, action: "selectFromAlbum:")

self.configureInputDevice()
self.setupCapture()
self.configureVideoPreviewLayer()
self.initializeFocusFrame()
}
Expand All @@ -44,6 +46,82 @@ class QRCodeReaderVC: UIViewController, AVCaptureMetadataOutputObjectsDelegate {
}
*/

func selectFromAlbum(sender: UIBarButtonItem) {
if captureSession != nil {
captureSession?.stopRunning()
}

let status = PHPhotoLibrary.authorizationStatus()

switch status {
case .Denied, .Restricted:
let alert = UIAlertController(title: "No Permission", message: "You should approve ShadowVPN to access your photos", preferredStyle: UIAlertControllerStyle.Alert)

let settingAction = UIAlertAction(title: "Setup", style: UIAlertActionStyle.Default, handler: { (action: UIAlertAction) -> Void in
dispatch_async(dispatch_get_main_queue(), { () -> Void in
let settingURL = NSURL(string: UIApplicationOpenSettingsURLString)
UIApplication.sharedApplication().openURL(settingURL!)
})
})
alert.addAction(settingAction)

let cancelAction = UIAlertAction(title: "Cancel", style: UIAlertActionStyle.Cancel, handler: nil)
alert.addAction(cancelAction)
self.presentViewController(alert, animated: true, completion: nil)
default:
let imagePicker = UIImagePickerController()
imagePicker.delegate = self
self.presentViewController(imagePicker, animated: true, completion: nil)
}
}

func imagePickerControllerDidCancel(picker: UIImagePickerController) {
picker.dismissViewControllerAnimated(true) { () -> Void in
if self.captureSession != nil {
self.captureSession?.startRunning()
}
}
}

func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) {
picker.dismissViewControllerAnimated(true, completion: nil)
let image = CIImage(image: info[UIImagePickerControllerOriginalImage] as! UIImage)

let detector = CIDetector(ofType: CIDetectorTypeQRCode, context: nil, options: nil)
let features = detector.featuresInImage(image!)
if features.count > 0 {
let feature = features[0] as! CIQRCodeFeature
self.parseQRCodeContext(context: feature.messageString)
} else {
if captureSession != nil {
captureSession?.startRunning()
}
}
}

func setupCapture() {
self.view.backgroundColor = UIColor.blackColor()
let status = AVCaptureDevice.authorizationStatusForMediaType(AVMediaTypeVideo)
switch status {
case .Denied, .Restricted:
let alert = UIAlertController(title: "No Permission", message: "You should approve ShadowVPN to access your video capture", preferredStyle: UIAlertControllerStyle.Alert)

let settingAction = UIAlertAction(title: "Setup", style: UIAlertActionStyle.Default, handler: { (action: UIAlertAction) -> Void in
let settingURL = NSURL(string: UIApplicationOpenSettingsURLString)
dispatch_async(dispatch_get_main_queue(), { () -> Void in
UIApplication.sharedApplication().openURL(settingURL!)
})
})
alert.addAction(settingAction)

let cancelAction = UIAlertAction(title: "Cancel", style: UIAlertActionStyle.Cancel, handler: nil)
alert.addAction(cancelAction)
self.presentViewController(alert, animated: true, completion: nil)
default:
self.configureInputDevice()
}
}

func configureInputDevice() {
let captureInput: AnyObject!
let captureDevice = AVCaptureDevice.defaultDeviceWithMediaType(AVMediaTypeVideo)
Expand All @@ -61,15 +139,18 @@ class QRCodeReaderVC: UIViewController, AVCaptureMetadataOutputObjectsDelegate {
let captureMetadataOutput = AVCaptureMetadataOutput()
captureSession?.addOutput(captureMetadataOutput)

self.setupScanRect(captureMetaDataOutput: captureMetadataOutput)
captureMetadataOutput.metadataObjectTypes = [AVMetadataObjectTypeQRCode]
captureMetadataOutput.setMetadataObjectsDelegate(self, queue: dispatch_get_main_queue())
}

func setupScanRect(captureMetaDataOutput output: AVCaptureMetadataOutput) {
let scanRect = CGRectMake((SCREEN_WIDTH - 300) / 2, (SCREEN_HEIGHT - 300) / 2, 300, 300)
let y = scanRect.origin.x / SCREEN_WIDTH
let x = scanRect.origin.y / SCREEN_HEIGHT
let height = scanRect.width / SCREEN_WIDTH
let width = scanRect.height / SCREEN_HEIGHT

captureMetadataOutput.rectOfInterest = CGRectMake(x, y, width, height)
captureMetadataOutput.setMetadataObjectsDelegate(self, queue: dispatch_get_main_queue())
captureMetadataOutput.metadataObjectTypes = [AVMetadataObjectTypeQRCode]
output.rectOfInterest = CGRectMake(x, y, width, height)
}

func configureVideoPreviewLayer() {
Expand Down Expand Up @@ -115,7 +196,9 @@ class QRCodeReaderVC: UIViewController, AVCaptureMetadataOutputObjectsDelegate {
var config: Dictionary = [String: String]()

if url.scheme == "shadowvpn" && url.host == "QRCode" {
captureSession?.stopRunning()
if captureSession != nil {
captureSession?.stopRunning()
}
for item in url.queryItems! {
config[item.name] = item.value
}
Expand Down
57 changes: 54 additions & 3 deletions ShadowVPN/QRCodeShareVC.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,11 @@
//

import UIKit
import Photos

class QRCodeShareVC: UIViewController {
var configQuery: String?
var imageView: UIImageView!

override func viewDidLoad() {
super.viewDidLoad()
Expand Down Expand Up @@ -38,6 +40,7 @@ class QRCodeShareVC: UIViewController {
*/

func displayQRCodeImage() {
// show Image
let query: String = self.configQuery!

let filter = CIFilter(name: "CIQRCodeGenerator")
Expand All @@ -48,7 +51,7 @@ class QRCodeShareVC: UIViewController {
let x = (self.view.bounds.width - width) / 2
let y = (self.view.bounds.height - heigth) / 2

let imgView: UIImageView = UIImageView(frame: CGRectMake(x, y, width, heigth))
self.imageView = UIImageView(frame: CGRectMake(x, y, width, heigth))
let codeImage = UIImage(CIImage: (filter?.outputImage)!.imageByApplyingTransform(CGAffineTransformMakeScale(10, 10)))

let iconImage = UIImage(named: "qrcode_avatar")
Expand All @@ -65,8 +68,56 @@ class QRCodeShareVC: UIViewController {

UIGraphicsEndImageContext()

imgView.image = resultImage
self.view.addSubview(imgView)
let tapGR = UITapGestureRecognizer(target: self, action: "tapImage:")
imageView.userInteractionEnabled = true
imageView.addGestureRecognizer(tapGR)

self.imageView.image = resultImage
self.view.addSubview(self.imageView)
}

// func tapImage(sender: UITapGestureRecognizer) {
// print("image view tapped")
// }

func save() {
// save code image to album

let status = PHPhotoLibrary.authorizationStatus()

switch status {
case .Denied, .Restricted:
let alert = UIAlertController(title: "No Permission", message: "You should approve ShadowVPN to access your photos", preferredStyle: UIAlertControllerStyle.Alert)

let settingAction = UIAlertAction(title: "Setup", style: UIAlertActionStyle.Default, handler: { (action: UIAlertAction) -> Void in
dispatch_async(dispatch_get_main_queue(), { () -> Void in
let settingURL = NSURL(string: UIApplicationOpenSettingsURLString)
UIApplication.sharedApplication().openURL(settingURL!)
})
})
alert.addAction(settingAction)

let cancelAction = UIAlertAction(title: "Cancel", style: UIAlertActionStyle.Cancel, handler: nil)
alert.addAction(cancelAction)
self.presentViewController(alert, animated: true, completion: nil)
default:
UIImageWriteToSavedPhotosAlbum(self.imageView.image!, self, "image:didFinishSavingWithError:contextInfo:", nil)
}

}

func image(image: UIImage, didFinishSavingWithError error: NSError?, contextInfo: AnyObject) {
if (error != nil) {
NSLog("%@", error!)
} else {
let alert = UIAlertController(title: "Saved", message: "Image save to Photos", preferredStyle: UIAlertControllerStyle.Alert)
let done = UIAlertAction(title: "OK", style: .Default, handler: { (action: UIAlertAction) -> Void in
self.navigationController?.popToRootViewControllerAnimated(true)
})
alert.addAction(done)
self.presentViewController(alert, animated: true, completion: nil)
NSLog("saved image to album")
}
}

}

0 comments on commit a758982

Please sign in to comment.