2014年10月20日 星期一

解析 iOS 照相和錄影如何達成

請參考 AVCam SampleAV Foundation Programming Guide

iOS 拍照和錄影是透過 AV Foundation framework 來完成的。首先先介紹幾個類別:
1. AVCaptureDevice - 用來描述輸入硬體元件,例如:攝影機或麥克風。
2. AVCautureInput - 用來設定輸入硬體元件輸出埠。
3. AVCaptureOutput - 用來描述要輸出的結果,例出要輸出成照片檔 (AVCaptureStillImageOutput) 或 影片檔 (AVCaptureMovieFileOutput)等。
4. AVCaptureConnection - 用來描述和串聯輸入物件和輸出物件的類別,被使用於 AVCaptureSession 內部,通常會使用 AVCatureSession 物件,而不會直接使用 AVCaptureConnection。
5. AVCaptureSession - 所有輸入硬體物件(AVCaputureInput objects)和輸入物件(AVCaptureOutput objects,可能是照片檔或影片檔)都會被加入 AVCaptureSession 物件,最後透過 -(void)startRunning; 和 -(void)stopRunning; 來啟動和停止工作。
6. AVCaptureVideoPreviewLayer - 這是一個滿重要的類別,如其名,就是用於在螢幕上產生預覽畫面用。在此預覽的畫面是指輸入影像串流直接即時顯示在View上,而不是指拍照後的預覽。

接著,就來分解 AVCam source code 吧~
先來看看初始化要作些什麼吧!

1. 產生 AVCaptureSession 物件,先把 AVCaptureVideoPreviewLayer 指定給 session.

 AVCaptureSession *session = [[AVCaptureSession alloc] init];
[[self previewView] setSession:session];

2. 找到適當的 AVCaptureDevice ,產生適當的 AVCaptureInput
AVCaptureDevice *videoDevice = [AVCamViewController deviceWithMediaType:AVMediaTypeVideo preferringPosition:AVCaptureDevicePositionBack];
AVCaptureDeviceInput *videoDeviceInput = [AVCaptureDeviceInput deviceInputWithDevice:videoDevice error:&error];
AVCaptureDevice *audioDevice = [[AVCaptureDevice devicesWithMediaType:AVMediaTypeAudio] firstObject]; AVCaptureDeviceInput *audioDeviceInput = [AVCaptureDeviceInput deviceInputWithDevice:audioDevice error:&error];

3. 把 AVCaptureInput 加入 session。
if ([session canAddInput:videoDeviceInput])
{
    [session addInput:videoDeviceInput];
    ...
}
if ([session canAddInput:audioDeviceInput])
{
    [session addInput:audioDeviceInput];
    ...
}

4. 初始要輸出的影片檔和圖片檔加到 session。
AVCaptureMovieFileOutput *movieFileOutput = [[AVCaptureMovieFileOutput alloc] init];
if ([session canAddOutput:movieFileOutput])
{
    [session addOutput:movieFileOutput];
    ...
}
    
AVCaptureStillImageOutput *stillImageOutput = [[AVCaptureStillImageOutput alloc] init];
if ([session canAddOutput:stillImageOutput])
{
    [session addOutput:stillImageOutput];
    ...
}

接著,來拍照吧!拍照的指令就是
[AVCaptureStillImageOutput captureStillImageAsynchronouslyFromConnection:completionHandler:];
來看看 Sample source code 怎麼寫的。
- (IBAction)snapStillImage:(id)sender
{
    dispatch_async([self sessionQueue], ^{
        ...
        [[self stillImageOutput] captureStillImageAsynchronouslyFromConnection:[[self stillImageOutput] connectionWithMediaType:AVMediaTypeVideo] completionHandler:^(CMSampleBufferRef imageDataSampleBuffer, NSError *error) {
            if (imageDataSampleBuffer)  // imageDataSampleBuffer 指向儲存照片內容的地方
            {
                // 將數據用 NSData 物件化
                NSData *imageData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageDataSampleBuffer];
                // 再轉成 UIImage 物件
                UIImage *image = [[UIImage alloc] initWithData:imageData];
                // 最後,儲存到系統相簿
                [[[ALAssetsLibrary alloc] init] writeImageToSavedPhotosAlbum:[image CGImage] orientation:(ALAssetOrientation)[image imageOrientation] completionBlock:nil];
            }
        }];
    });
}

驚 ~! 拍照怎麼這麼簡單;那攝影呢?來看看吧~!

    //開始錄影並指定錄影要暫存到那個檔案。
    [AVCaptureMovieFileOutput startRecordingToOutputFileURL:recordingDelegate:] 
    //結束錄影
    [AVCaptureMovieFileOutput stopRecording]  

不難,看原始碼就懂了

2014年7月15日 星期二

MAC OS X: Sweep IP Address: 在 MAC 上,去掃描網路上的 ip address。

想知道,網路上有那些 IP 位址己經被使用了嗎了,在 Windows 上,可以使用Angry IP Scanner。 但,在 MAC 上,並不用這麼麻煩,只要打開終端機(terminal), 在上面鍵入以下指令即可。

xCedar$ for x in {1..254}; do ping -c 1 -W 100 192.168.1.$x | grep 'time='; done

以上,簡單吧~! 指令中,以 for ... done 為主的迥圈,設定 x 的值,從 1 到 254; 並變數 x 的值,
以 $x 代入 ping 的指令中。
-c 1: ping 的次數為一次; -W 100: 等待回應時間為 100ms。
最後以關鍵字 "time=" 來列出有回應的 IP 位址。

Ref:Ping Sweep for MAC OS X

2014年6月26日 星期四

iOS 7 的 MotionEffects

iOS 7 剛出來時,大家第一個會注意到的事在 Lock Screen 有一個會動的背景;那就是 Motion Effects。
其實它很簡單,我試著在一個UIView 加上一個 UIButton,接著讓 Button 是浮動的。看程式碼就懂了。

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.

    aButton.layer.mask.frame = aButton.bounds;
    aButton.layer.masksToBounds = YES;

    UIInterpolatingMotionEffect *xAxis = [[UIInterpolatingMotionEffect alloc]
                                          initWithKeyPath:@"center.x"
                                          type:UIInterpolatingMotionEffectTypeTiltAlongHorizontalAxis];

    xAxis.minimumRelativeValue = [NSNumber numberWithFloat:-90.0];
    xAxis.maximumRelativeValue = [NSNumber numberWithFloat:90.0];

    UIInterpolatingMotionEffect *yAxis = [[UIInterpolatingMotionEffect alloc]
                                          initWithKeyPath:@"center.y"
                                          type:UIInterpolatingMotionEffectTypeTiltAlongVerticalAxis];

    yAxis.minimumRelativeValue = [NSNumber numberWithFloat:-90.0];
    yAxis.maximumRelativeValue = [NSNumber numberWithFloat:90.0];

    UIMotionEffectGroup *group = [[UIMotionEffectGroup alloc]init];
    group.motionEffects = @[xAxis, yAxis];
    [aButton addMotionEffect:group];
}

2014年4月28日 星期一

Mac OS X Mavericks 開啟 關閉 系統內建的 FTP Server

在Mac OS X Mavericks 上,己經將原來放置在 "檔案共享"裡的 "FTP伺服器" 選項己經拿掉了。現在只能透過 command line 中的 launchctl 去啟動和關閉系統內建的"FTP伺服器"。

開啟

sudo -s launchctl load -w /System/Library/LaunchDaemous/ftp.plist

關閉

sudo -s launchctl unload -w /System/Library/LaunchDaemous/ftp.plist

2014年1月4日 星期六

Sublime text 2 setup

最近常使用 Sublime Text 來編輯一些文件,有時候,電腦重灌就忘了一些常用套件是怎麼裝旳,以下列一些常用的套件的URL吧!

Sublime Text 2 http://www.sublimetext.com/2
Package Control https://sublime.wbond.net/installation#st2
Markdown preview https://github.com/revolunet/sublimetext-markdown-preview