• R/O
  • HTTP
  • SSH
  • HTTPS

A01c: 提交

OPC(Olympus Air)用撮影アプリ。


Commit MetaInfo

修订版e37d74205e8f3378fb31fe667a2a2e1b2d8e8f72 (tree)
时间2017-07-20 00:08:52
作者MRSa <mrsa@myad...>
CommiterMRSa

Log Message

インターバル&ブラケッティング撮影のエンジンを組み込む。

更改概述

差异

--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -37,7 +37,7 @@
3737 <ConfirmationsSetting value="0" id="Add" />
3838 <ConfirmationsSetting value="0" id="Remove" />
3939 </component>
40- <component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" default="true" assert-keyword="true" jdk-15="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
40+ <component name="ProjectRootManager" version="2" languageLevel="JDK_1_7" default="true" assert-keyword="true" jdk-15="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
4141 <output url="file://$PROJECT_DIR$/build/classes" />
4242 </component>
4343 <component name="ProjectType">
--- a/wear/src/main/java/jp/sfjp/gokigen/a01c/olycamerawrapper/IOlyCameraCoordinator.java
+++ b/wear/src/main/java/jp/sfjp/gokigen/a01c/olycamerawrapper/IOlyCameraCoordinator.java
@@ -32,6 +32,9 @@ public interface IOlyCameraCoordinator
3232 /** ムービー撮影機能の実行(開始・終了) **/
3333 void movieControl();
3434
35+ /** インターバル&ブラケッティング撮影の実行 **/
36+ void bracketingShot(int bracketingStyle, int bracketingCount, int durationSeconds);
37+
3538 /** 撮影確認画像の設定 **/
3639 void setRecViewMode(boolean isRecViewMode);
3740
--- a/wear/src/main/java/jp/sfjp/gokigen/a01c/olycamerawrapper/OlyCameraCoordinator.java
+++ b/wear/src/main/java/jp/sfjp/gokigen/a01c/olycamerawrapper/OlyCameraCoordinator.java
@@ -25,6 +25,7 @@ import jp.sfjp.gokigen.a01c.olycamerawrapper.property.IOlyCameraPropertyProvider
2525 import jp.sfjp.gokigen.a01c.olycamerawrapper.property.LoadSaveCameraProperties;
2626 import jp.sfjp.gokigen.a01c.olycamerawrapper.property.OlyCameraPropertyProxy;
2727 import jp.sfjp.gokigen.a01c.olycamerawrapper.takepicture.AutoFocusControl;
28+import jp.sfjp.gokigen.a01c.olycamerawrapper.takepicture.BracketingShotControl;
2829 import jp.sfjp.gokigen.a01c.olycamerawrapper.takepicture.MovieRecordingControl;
2930 import jp.sfjp.gokigen.a01c.olycamerawrapper.takepicture.SingleShotControl;
3031 import jp.sfjp.gokigen.a01c.preference.ICameraPropertyAccessor;
@@ -52,6 +53,7 @@ public class OlyCameraCoordinator implements IOlyCameraCoordinator, IIndicatorCo
5253 private final AutoFocusControl autoFocus;
5354 private final SingleShotControl singleShot;
5455 private final MovieRecordingControl movieControl;
56+ private final BracketingShotControl bracketingShot;
5557 private final OlyCameraPropertyProxy propertyProxy;
5658 private final LoadSaveCameraProperties loadSaveCameraProperties;
5759 private final OlyCameraConnection cameraConnection;
@@ -60,7 +62,7 @@ public class OlyCameraCoordinator implements IOlyCameraCoordinator, IIndicatorCo
6062
6163 private boolean isManualFocus = false;
6264 private boolean isAutoFocusLocked = false;
63- private boolean isExposureLocked = false;
65+ //private boolean isExposureLocked = false;
6466
6567 /**
6668 * コンストラクタ
@@ -81,6 +83,7 @@ public class OlyCameraCoordinator implements IOlyCameraCoordinator, IIndicatorCo
8183 autoFocus = new AutoFocusControl(camera, focusFrameDisplay, this); // AF制御
8284 singleShot = new SingleShotControl(camera, focusFrameDisplay, this, showInformation); // 1枚撮影
8385 movieControl = new MovieRecordingControl(context, camera, showInformation); // ムービー撮影
86+ bracketingShot = new BracketingShotControl(camera, focusFrameDisplay, this, showInformation); // ブラケッティング&インターバル撮影
8487 propertyProxy = new OlyCameraPropertyProxy(camera); // カメラプロパティ
8588 cameraStatusDisplay = new CameraStatusDisplay(propertyProxy, showInformation); // 画面表示
8689 this.levelMeter = new LevelMeterHolder(showInformation, android.support.v7.preference.PreferenceManager.getDefaultSharedPreferences(context).getBoolean(ICameraPropertyAccessor.SHOW_LEVEL_GAUGE_STATUS, false)); // デジタル水準器
@@ -216,6 +219,20 @@ public class OlyCameraCoordinator implements IOlyCameraCoordinator, IIndicatorCo
216219 }
217220
218221 /**
222+ * インターバル&ブラケッティング撮影の実行
223+ *
224+ * @param bracketingStyle : ブラケッティングスタイル
225+ * @param bracketingCount : 撮影枚数
226+ * @param durationSeconds : 撮影間隔(単位:秒)
227+ *
228+ */
229+ @Override
230+ public void bracketingShot(int bracketingStyle, int bracketingCount, int durationSeconds)
231+ {
232+ bracketingShot.startShootBracketing(bracketingStyle, bracketingCount, durationSeconds);
233+ }
234+
235+ /**
219236 * 撮影確認画像を生成するか設定する
220237 *
221238 */
@@ -331,8 +348,7 @@ public class OlyCameraCoordinator implements IOlyCameraCoordinator, IIndicatorCo
331348 @Override
332349 public boolean isAELock()
333350 {
334- isExposureLocked = propertyProxy.isExposureLocked();
335- return (isExposureLocked);
351+ return (propertyProxy.isExposureLocked());
336352 }
337353
338354 @Override
--- /dev/null
+++ b/wear/src/main/java/jp/sfjp/gokigen/a01c/olycamerawrapper/takepicture/BracketingShotControl.java
@@ -0,0 +1,434 @@
1+package jp.sfjp.gokigen.a01c.olycamerawrapper.takepicture;
2+
3+import android.graphics.Color;
4+import android.graphics.PointF;
5+import android.util.Log;
6+
7+import java.util.HashMap;
8+import java.util.List;
9+import java.util.concurrent.ExecutorService;
10+import java.util.concurrent.Executors;
11+
12+import jp.co.olympus.camerakit.OLYCamera;
13+import jp.co.olympus.camerakit.OLYCameraAutoFocusResult;
14+import jp.sfjp.gokigen.a01c.IShowInformation;
15+import jp.sfjp.gokigen.a01c.liveview.IAutoFocusFrameDisplay;
16+import jp.sfjp.gokigen.a01c.olycamerawrapper.IIndicatorControl;
17+import jp.sfjp.gokigen.a01c.olycamerawrapper.property.IOlyCameraProperty;
18+
19+/**
20+ * インターバル撮影&ブラケッティング撮影 実行クラス
21+ *
22+ *
23+ * Created by MRSa on 2017/07/19.
24+ */
25+public class BracketingShotControl implements OLYCamera.TakePictureCallback
26+{
27+ private final String TAG = toString();
28+
29+ private static final int BRACKETING_INTERVAL_MILLISECOND = 300; // 撮影待ち時間(ms)
30+ private static final int BRACKETING_PROPERTY_VALUE_SET_RETRY = 10;
31+
32+ private static final int BRACKET_NONE = 0; // 通常のショット
33+ private static final int BRACKET_EXPREV = 1; // 露出補正
34+ private static final int BRACKET_APERTURE = 2; // 絞り
35+ private static final int BRACKET_ISO = 3; // ISO
36+ private static final int BRACKET_SHUTTER = 4; // シャッター
37+ private static final int BRACKET_WB = 5; // ホワイトバランス
38+ private static final int BRACKET_COLOR_TONE = 6; // カラートーン
39+
40+ private final OLYCamera camera;
41+ private final IAutoFocusFrameDisplay autoFocusFrame;
42+ private final IShowInformation statusDrawer;
43+ private final IIndicatorControl indicator;
44+ private boolean isShootingWait = false;
45+ private boolean isBracketingAction = false;
46+ private int retryUpdateBracketingStatus = 0;
47+ private int waitSeconds = 0; // 撮影待ち時間
48+
49+ private int bracketCount = 0;
50+ private String targetPropertyName = null;
51+ private String originalProperty = null;
52+ private int originalPropertyIndex = -1;
53+ private List<String> propertyValueList = null;
54+
55+ /**
56+ *  コンストラクタ
57+ *
58+ */
59+ public BracketingShotControl(OLYCamera camera, IAutoFocusFrameDisplay focusFrameDrawer, IIndicatorControl indicator, IShowInformation statusDrawer)
60+ {
61+ this.camera = camera;
62+ this.autoFocusFrame = focusFrameDrawer;
63+ this.indicator = indicator;
64+ this.statusDrawer = statusDrawer;
65+ }
66+
67+ /**
68+ *  ブラケッティング対象のプロパティの現在設定値と、その選択肢を記憶する
69+ *
70+ * @param name ブラケッティング対象の名前
71+ * @return ブラケッティングの現在設定値
72+ */
73+ private int prepareBracketProperty(String name)
74+ {
75+ try
76+ {
77+ targetPropertyName = name;
78+ if (name.length() > 0)
79+ {
80+ originalProperty = camera.getCameraPropertyValue(name);
81+ propertyValueList = camera.getCameraPropertyValueList(name);
82+ if (bracketCount < 0)
83+ {
84+ bracketCount = propertyValueList.size();
85+ }
86+ return (propertyValueList.indexOf(originalProperty));
87+ }
88+ else
89+ {
90+ originalProperty = null;
91+ propertyValueList = null;
92+ }
93+ }
94+ catch (Exception e)
95+ {
96+ originalProperty = null;
97+ propertyValueList = null;
98+ e.printStackTrace();
99+ System.gc();
100+ }
101+ return (-1);
102+ }
103+
104+
105+ /**
106+ * ブラケッティング対象のプロパティを特定する
107+ *
108+ * @param isBracketing プロパティ
109+ * @return true : 対象の特定完了 / false : 対象の特定失敗
110+ */
111+ private boolean decideBracketProperty(int isBracketing)
112+ {
113+ switch (isBracketing)
114+ {
115+ case BRACKET_EXPREV:
116+ // 露出ブラケット
117+ targetPropertyName = IOlyCameraProperty.EXPOSURE_COMPENSATION;
118+ break;
119+
120+ case BRACKET_APERTURE:
121+ // 絞り値設定
122+ targetPropertyName = IOlyCameraProperty.APERTURE;
123+ break;
124+
125+ case BRACKET_ISO:
126+ // ISO
127+ targetPropertyName = IOlyCameraProperty.ISO_SENSITIVITY;
128+ break;
129+
130+ case BRACKET_SHUTTER:
131+ // シャッターブラケット
132+ targetPropertyName = IOlyCameraProperty.SHUTTER_SPEED;
133+ break;
134+
135+ case BRACKET_WB:
136+ // ホワイトバランスブラケット
137+ targetPropertyName = IOlyCameraProperty.WB_MODE;
138+ bracketCount = -1;
139+ break;
140+
141+ case BRACKET_COLOR_TONE:
142+ // ピクチャーモードブラケット
143+ targetPropertyName = IOlyCameraProperty.COLOR_TONE;
144+ bracketCount = -1;
145+ break;
146+
147+ case BRACKET_NONE:
148+ // パラメータは変更しないパターン...
149+ targetPropertyName = "";
150+ break;
151+
152+ default:
153+ // 何もしない
154+ return (false);
155+ }
156+ originalPropertyIndex = prepareBracketProperty(targetPropertyName);
157+ return (true);
158+ }
159+
160+
161+ /**
162+ * 写真撮影(ブラケッティング撮影)を開始する
163+ * bracketingStyle : ブラケッティングスタイル
164+ * bracketingCount : 撮影枚数
165+ * durationSeconds : 撮影間隔(単位:秒)
166+ */
167+ public void startShootBracketing(int bracketingStyle, int bracketingCount, int durationSeconds)
168+ {
169+ if ((camera.isTakingPicture())||(camera.isRecordingVideo())||(isBracketingAction))
170+ {
171+ // スチル or ムービー撮影中、ブラケッティング撮影中なら、何もしない
172+ return;
173+ }
174+
175+ // ブラケッティング撮影の準備
176+ bracketCount = bracketingCount;
177+ if (!decideBracketProperty(bracketingStyle))
178+ {
179+ // ブラケッティング指定ではないので、何もせずに終了する
180+ return;
181+ }
182+
183+ // 撮影間隔 (単位:秒)
184+ waitSeconds = durationSeconds;
185+
186+ // ブラケッティング撮影開始! (別スレッドでブラケッティング撮影を開始する)
187+ ExecutorService executor = Executors.newSingleThreadExecutor();
188+ executor.submit(new Runnable()
189+ {
190+ @Override
191+ public void run()
192+ {
193+ isBracketingAction = true;
194+ updateMessage("INT");
195+ try
196+ {
197+ startBracket();
198+ }
199+ catch (Exception e)
200+ {
201+ e.printStackTrace();
202+ }
203+ isBracketingAction = false;
204+ updateMessage("");
205+ }
206+ });
207+ }
208+
209+ /**
210+ * 画面にメッセージを表示する
211+ *
212+ * @param msg 表示するメッセージ
213+ */
214+ private void updateMessage(String msg)
215+ {
216+ statusDrawer.setMessage(IShowInformation.AREA_C, Color.CYAN, msg);
217+ }
218+
219+ /**
220+ * ブラケッティング撮影を開始する
221+ * (これは別スレッドで処理する)
222+ *
223+ * 一番小さい選択肢(インデックス)から設定された撮影枚数分、
224+ * 徐々に選択肢をずらして撮影する。
225+ *
226+ */
227+ private void startBracket()
228+ {
229+ int startIndex = originalPropertyIndex - (bracketCount / 2);
230+ if (propertyValueList != null)
231+ {
232+ if ((startIndex + bracketCount) > propertyValueList.size())
233+ {
234+ startIndex = propertyValueList.size() - bracketCount;
235+ }
236+ }
237+ if (startIndex < 0)
238+ {
239+ startIndex = 0;
240+ }
241+
242+ PointF afPoint = camera.getActualAutoFocusPoint();
243+ for (int index = 0; index < bracketCount; index++)
244+ {
245+ // 撮影条件を更新する
246+ updateBracketingStatus(index, startIndex);
247+ startIndex++;
248+
249+ try
250+ {
251+ // AFポイントを設定する
252+ if (afPoint != null)
253+ {
254+ camera.setAutoFocusPoint(afPoint);
255+ }
256+ }
257+ catch (Exception e)
258+ {
259+ e.printStackTrace();
260+ }
261+
262+ if (bracketCount == 1)
263+ {
264+ // 1枚しか撮影しない時は、撮影前にウェイトをかける
265+ waitSeconds(waitSeconds);
266+ }
267+
268+ try
269+ {
270+ // 写真を撮影する
271+ camera.takePicture(new HashMap<String, Object>(), this);
272+ isShootingWait = true;
273+ while (isShootingWait)
274+ {
275+ // ここで撮影状態が整うまで少し待つ
276+ Thread.sleep(BRACKETING_INTERVAL_MILLISECOND);
277+ updateShootingWaitStatus();
278+ }
279+ }
280+ catch (Exception e)
281+ {
282+ e.printStackTrace();
283+ }
284+
285+ // 撮影したことをバイブレータで知らせる
286+ statusDrawer.vibrate(IShowInformation.VIBRATE_PATTERN_SIMPLE_SHORT);
287+
288+ // 指定された時間待機、ただし、最後の撮影が終わったあとには待たないようにする。
289+ if ((index + 1) < bracketCount)
290+ {
291+ waitSeconds(waitSeconds);
292+ }
293+ }
294+ try
295+ {
296+ // 変更したプロパティ値を元の値に戻す...ちょっと待ってから
297+ Thread.sleep(BRACKETING_INTERVAL_MILLISECOND);
298+ if (originalProperty != null)
299+ {
300+ camera.setCameraPropertyValue(targetPropertyName, originalProperty);
301+ }
302+
303+ // とにかくAF枠を消す。
304+ camera.clearAutoFocusPoint();
305+ autoFocusFrame.hideFocusFrame();
306+
307+ indicator.onAfLockUpdate(false);
308+
309+ // 撮影終了をバイブレータで知らせる
310+ statusDrawer.vibrate(IShowInformation.VIBRATE_PATTERN_SIMPLE_MIDDLE);
311+ }
312+ catch (Exception e)
313+ {
314+ e.printStackTrace();
315+ }
316+ }
317+
318+ /**
319+ * 指定された時間待機する
320+ *
321+ * @param seconds 待機秒数
322+ */
323+ private void waitSeconds(int seconds)
324+ {
325+ for (int count = seconds; count > 0; count--)
326+ {
327+ // 待ち時間(単位:秒)
328+ try
329+ {
330+ // BKT表示(撮影枚数表示と待ち時間)を変える
331+ updateMessage("WAIT " + count + "s.");
332+ Thread.sleep(1000);
333+ }
334+ catch (Exception e)
335+ {
336+ e.printStackTrace();
337+ }
338+ }
339+ updateMessage("");
340+ }
341+
342+ /**
343+ * ブラケッティング撮影の状態を更新する
344+ *
345+ * @param index 撮影が終了したカウント(0始まり)
346+ */
347+ private void updateBracketingStatus(int index, int currentIndex)
348+ {
349+ Log.v(TAG, "updateBracketingStatus() : " + index + "(" + currentIndex + ")");
350+
351+ // カメラのプロパティ設定を変える
352+ try
353+ {
354+ if (propertyValueList != null)
355+ {
356+ Thread.sleep(BRACKETING_INTERVAL_MILLISECOND);
357+ camera.setCameraPropertyValue(targetPropertyName, propertyValueList.get(currentIndex));
358+ }
359+ }
360+ catch (Exception e)
361+ {
362+ e.printStackTrace();
363+
364+ // 頭に来たので、再度呼ぶ (リトライオーバーするまで)
365+ if (retryUpdateBracketingStatus < BRACKETING_PROPERTY_VALUE_SET_RETRY)
366+ {
367+ retryUpdateBracketingStatus++;
368+ updateBracketingStatus(index, currentIndex);
369+ }
370+ }
371+ retryUpdateBracketingStatus = 0;
372+
373+ // 撮影枚数表示を変える
374+ updateMessage("INT " + (index + 1) + "/" + bracketCount);
375+ }
376+
377+ /**
378+ * カメラの状態を取得し、撮影可能か確認する。
379+ * (trueならまだ撮影処理中、falseなら撮影可能)
380+ */
381+ private void updateShootingWaitStatus()
382+ {
383+ boolean isBusy = false;
384+ try
385+ {
386+ isBusy = ((camera.isTakingPicture())||(camera.isMediaBusy())||(camera.isRecordingVideo()));
387+
388+ // ちょっと待ち時間をとりたい...
389+ String messageToShow = "getShootingBusyStatus() : " + String.valueOf(isBusy);
390+ Log.v(TAG, messageToShow);
391+ }
392+ catch (Exception e)
393+ {
394+ e.printStackTrace();
395+ }
396+ isShootingWait = isBusy;
397+ }
398+
399+ /**
400+ * OLYCamera.TakePictureCallback の実装
401+ *
402+ *
403+ */
404+ @Override
405+ public void onProgress(OLYCamera olyCamera, OLYCamera.TakingProgress takingProgress, OLYCameraAutoFocusResult olyCameraAutoFocusResult)
406+ {
407+ // 特に何もしないでおこう
408+ }
409+
410+ /**
411+ * OLYCamera.TakePictureCallback の実装
412+ *
413+ */
414+ @Override
415+ public void onCompleted()
416+ {
417+ // 撮影待ち状態の更新
418+ updateShootingWaitStatus();
419+ }
420+
421+ /**
422+ * OLYCamera.TakePictureCallback の実装
423+ *
424+ * @param e 例外情報
425+ */
426+ @Override
427+ public void onErrorOccurred(Exception e)
428+ {
429+ e.printStackTrace();
430+
431+ // 撮影待ち状態の更新
432+ updateShootingWaitStatus();
433+ }
434+}
Show on old repository browser