2018-04-22[n年前へ]
■Python(Pythonista)でiOSカメラを自由自在に使ってみる 
iPhone/iPadなどの機器のカメラは、焦点位置や露光時間や感度など、わりと細かく制御することができます。そうした撮影処理を使って、露光時間を変えた撮影を何枚もして画像(ハイダイナミックレンジ:HDR)合成をしたり、焦点位置を変えた撮影から焦点合成(フォーカススタッキング)を行ったりすると、意外に楽しいものです。とはいえ、そんなコード遊びをするのに、毎回Objective-C(やC++)でコーディングするのは少し面倒です。
というわけで、今日はiOSで動くPython ( Pythonista ) で、iOSのカメラをマニュアル撮影的に使うコードを書いてみました。それが下に貼り付けたPythonコード例です。この例では、焦点制御を無効化した上で、最近接位置から無限遠までのレンズ位置を0.0〜1.0の任意位置に制御しつ、撮影を行うことができます。
「開発用マシンでコードを書いてビルドした上で、スマホに転送して動かす」というような手間を掛けずとも、スマホ上で比較的短いコードを書いて、それをスマホ上で瞬時に動かして「自分だけの特殊撮影マシン」を仕立てて遊ぶことができるのは面白いものです。…今回貼り付けた撮影処理部分は全くPythonっぽくないコードですが、ひとたび「ライブラリ化」してしまえば、こんなコードを見る必要もなく、やりたいことだけをPythonから気楽に実行することができるようになります。…となれば、色々遊んでみたくなる人も多いのではないでしょうか。
# coding: utf-8
from objc_util import *
import time
AVCaptureSession = ObjCClass('AVCaptureSession')
AVCaptureDevice = ObjCClass('AVCaptureDevice')
AVCaptureDeviceInput = ObjCClass('AVCaptureDeviceInput')
AVCapturePhotoOutput = ObjCClass('AVCapturePhotoOutput')
def manualCapture(device, output, focusDistance, fileName):
def captureOutput_didFinishProcessingPhotoSampleBuffer_
previewPhotoSampleBuffer_resolvedSettings_bracketSettings_error_(
_self, _cmd, _output, _photoBuffer, _previewBuffer,
_resolveSettings, bracketSettings, _error ):
photoBuffer = ObjCInstance(_photoBuffer)
jpegPhotoData = ObjCClass('AVCapturePhotoOutput'
).JPEGPhotoDataRepresentationForJPEGSampleBuffer_
previewPhotoSampleBuffer_(
photoBuffer, _previewBuffer)
jpegPhotoData.writeToFile_atomically_(fileName, True )
# delegate
CameraManualPhotoCaptureDelegate = create_objc_class(
'CameraManualPhotoCaptureDelegate',
methods=[
captureOutput_didFinishProcessingPhotoSampleBuffer_
previewPhotoSampleBuffer_resolvedSettings_bracketSettings_error_ ],
protocols=[ 'AVCapturePhotoCaptureDelegate' ])
device.lockForConfiguration_(None)
device.setFocusModeLockedWithLensPosition_completionHandler_(
focusDistance, None)
device.unlockForConfiguration()
time.sleep(1)
delegate = CameraManualPhotoCaptureDelegate.new()
settings = ObjCClass('AVCapturePhotoSettings'
).photoSettings()
settings.AVCaptureFocusMode = 0
output.capturePhotoWithSettings_delegate_(
settings, delegate )
time.sleep(1)
delegate.release()
@on_main_thread
def main():
session = AVCaptureSession.alloc().init()
device =
AVCaptureDevice.defaultDeviceWithMediaType_('vide')
_input =
AVCaptureDeviceInput.deviceInputWithDevice_error_(
device, None)
if _input:
session.addInput_(_input)
else:
return
session.startRunning()
output = AVCapturePhotoOutput.alloc().init()
session.addOutput_(output)
time.sleep(1)
manualCapture(device, output, 0.0, 'sample.jpg')
time.sleep(1)
session.stopRunning()
session.release()
output.release()
if __name__ == '__main__':
main()
■Powered
by yagm.net
