Skip to content

Commit 782f4c2

Browse files
committed
V0.1.0
1 parent 6d3608d commit 782f4c2

33 files changed

+388
-211
lines changed

.idea/caches/deviceStreaming.xml

Lines changed: 12 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/copilot.data.migration.agent.xml

Lines changed: 6 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/copilot.data.migration.ask.xml

Lines changed: 6 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/copilot.data.migration.ask2agent.xml

Lines changed: 6 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/copilot.data.migration.edit.xml

Lines changed: 6 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/deviceManager.xml

Lines changed: 13 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

app/build.gradle

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ android {
88
namespace = "tech.treeentertainment.camera"
99
minSdk 21
1010
targetSdk 36
11-
versionCode 1
12-
versionName "0.0.1"
11+
versionCode 2
12+
versionName "0.1.0"
1313
compileSdkVersion 35
1414
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
1515
}

app/src/main/assets/changelog/changelog.html

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,27 @@ <h3>Bugfixes</h3>
2222
</ul>
2323
-->
2424
<hr>
25+
<h2>Version 0.1.0 BETA (2025-10-02)</h2>
26+
<!-- <h3>New Features</h3>-->
27+
<!-- <ul>-->
28+
<!-- <li></li>-->
29+
<!-- </ul>-->
30+
<hr>
31+
<h3>Improvements</h3>
32+
<ul>
33+
<li>Add liveview capture settings & enabler</li>
34+
<li>Update minor files</li>
35+
</ul>
36+
<h3>Bugfixes</h3>
37+
<ul>
38+
<li>Fix capture error</li>
39+
</ul>
40+
<hr>
41+
<h3>Contributor</h3>
42+
<ul>
43+
<li><a href="https://github.com/channel101">@channel101</a></li>
44+
</ul>
45+
<hr>
2546
<h2>Version 0.0.1 BETA (2025-09-26)</h2>
2647
<!-- <h3>New Features</h3>-->
2748
<!-- <ul>-->

app/src/main/java/tech/treeentertainment/camera/ptp/EosCamera.java

Lines changed: 65 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
11

22
package tech.treeentertainment.camera.ptp;
33

4+
import java.io.File;
5+
import java.io.FileOutputStream;
46
import java.util.ArrayList;
57
import java.util.List;
68
import java.util.Set;
79

10+
import android.graphics.Bitmap;
11+
import android.os.Environment;
812
import android.util.Log;
913

1014
import tech.treeentertainment.camera.ptp.PtpConstants.Operation;
@@ -15,6 +19,9 @@
1519
import tech.treeentertainment.camera.ptp.commands.eos.EosSetLiveViewAction;
1620
import tech.treeentertainment.camera.ptp.commands.eos.EosSetPropertyCommand;
1721
import tech.treeentertainment.camera.ptp.commands.eos.EosTakePictureCommand;
22+
import tech.treeentertainment.camera.ptp.commands.nikon.NikonCaptureDuringLvCommand;
23+
import tech.treeentertainment.camera.ptp.commands.nikon.NikonStopLiveViewAction;
24+
import tech.treeentertainment.camera.ptp.commands.nikon.NikonTakePictureCommand;
1825
import tech.treeentertainment.camera.ptp.model.LiveViewData;
1926

2027
public class EosCamera extends PtpCamera {
@@ -72,11 +79,65 @@ public void focus() {
7279
//queue.add(new SimpleCommand(this, Operation.EosRemoteReleaseOn, 1, 0));
7380
}
7481

75-
public void capture() {
76-
if (isBulbCurrentShutterSpeed()) {
77-
queue.add(new SimpleCommand(this, cameraIsCapturing ? Operation.EosBulbEnd : Operation.EosBulbStart));
82+
@Override
83+
public void capture(int mode) {
84+
if (mode == CAPTURE_HIGH_QUALITY) {
85+
if (isBulbCurrentShutterSpeed()) {
86+
queue.add(new SimpleCommand(this, cameraIsCapturing ? Operation.EosBulbEnd : Operation.EosBulbStart));
87+
} else {
88+
queue.add(new EosTakePictureCommand(this));
89+
}
7890
} else {
79-
queue.add(new EosTakePictureCommand(this));
91+
// LiveView 프레임 캡쳐
92+
LiveViewData frame = new LiveViewData();
93+
frame.setFrameReadyListener(bmp -> {
94+
95+
if (bmp != null) {
96+
Log.d("CameraCapture", "LiveView frame captured, size="
97+
+ bmp.getWidth() + "x" + bmp.getHeight());
98+
99+
// 1. mutable 복사
100+
bmp = bmp.copy(Bitmap.Config.ARGB_8888, true);
101+
Log.d("CameraCapture", "Bitmap copied as mutable");
102+
103+
saveBitmapToPhone(bmp, "liveview_" + System.currentTimeMillis() + ".jpg");
104+
105+
// 3. Fragment listener 호출
106+
if (listener != null) {
107+
int handle = (int) System.currentTimeMillis();
108+
Log.d("CameraCapture", "Notify listener: handle=" + handle);
109+
listener.onCapturedPictureReceived(
110+
handle,
111+
"liveview_" + handle + ".jpg",
112+
bmp,
113+
bmp
114+
);
115+
} else {
116+
Log.w("CameraCapture", "Listener is null, cannot deliver bitmap");
117+
}
118+
} else {
119+
Log.w("CameraCapture", "LiveView frame capture failed, bmp=null");
120+
}
121+
});
122+
getLiveViewPicture(frame);
123+
}
124+
}
125+
126+
@SuppressWarnings("ResultOfMethodCallIgnored")
127+
private void saveBitmapToPhone(Bitmap bmp, String fileName) {
128+
try {
129+
// 저장 경로: Pictures 디렉토리 사용 (API 29+ 대응)
130+
File dir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), "somecamera");
131+
if (!dir.exists()) dir.mkdirs();
132+
133+
File file = new File(dir, fileName);
134+
FileOutputStream out = new FileOutputStream(file);
135+
bmp.compress(Bitmap.CompressFormat.JPEG, 95, out);
136+
out.flush();
137+
out.close();
138+
Log.d("CameraCapture", "Bitmap saved: " + file.getAbsolutePath());
139+
} catch (Exception e) {
140+
Log.e("CameraCapture", "Bitmap save failed", e);
80141
}
81142
}
82143

app/src/main/java/tech/treeentertainment/camera/ptp/NikonCamera.java

Lines changed: 70 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
11

22
package tech.treeentertainment.camera.ptp;
33

4+
import android.graphics.Bitmap;
5+
import android.os.Environment;
46
import android.util.Log;
57

8+
import java.io.File;
9+
import java.io.FileOutputStream;
610
import java.util.ArrayList;
711
import java.util.HashSet;
812
import java.util.List;
@@ -21,6 +25,7 @@
2125
import tech.treeentertainment.camera.ptp.commands.nikon.NikonOpenSessionAction;
2226
import tech.treeentertainment.camera.ptp.commands.nikon.NikonStartLiveViewAction;
2327
import tech.treeentertainment.camera.ptp.commands.nikon.NikonStopLiveViewAction;
28+
import tech.treeentertainment.camera.ptp.commands.nikon.NikonTakePictureCommand;
2429
import tech.treeentertainment.camera.ptp.model.DevicePropDesc;
2530
import tech.treeentertainment.camera.ptp.model.LiveViewData;
2631
import tech.treeentertainment.camera.ptp.commands.nikon.NikonCaptureDuringLvCommand;
@@ -74,16 +79,6 @@ public void run() {
7479
}
7580
});
7681
}
77-
78-
// ✅ LiveView 종료 후 캡처 실행
79-
if (waitCaptureAfterLvStop
80-
&& (property == PtpConstants.Property.ExposureTime
81-
|| property == PtpConstants.Property.NikonShutterSpeed)) {
82-
83-
Log.i("NikonCamera", "LiveView stopped event received, starting capture.");
84-
waitCaptureAfterLvStop = false;
85-
queue.add(new InitiateCaptureCommand(this));
86-
}
8782
}
8883

8984
@Override
@@ -238,6 +233,7 @@ public boolean isSettingPropertyPossible(int property) {
238233
case Property.FocusPoints:
239234
return true;
240235
case Property.ColorTemperature:
236+
241237
return wb != null && wb == 0x8012;
242238
default:
243239
return true;
@@ -251,29 +247,74 @@ public void focus() {
251247

252248
@Override
253249
public void capture(int mode) {
254-
if (liveViewOpen) {
255-
// ✅ Nikon 전용 CaptureDuringLv 지원 여부 확인
256-
if (hasSupportForOperation(Operation.NikonCaptureDuringLv)) {
257-
Log.d("NikonCamera", "Using NikonCaptureDuringLv (high quality).");
258-
queue.add(new NikonCaptureDuringLvCommand(this));
259-
return;
250+
if (mode == CAPTURE_HIGH_QUALITY) {
251+
if (liveViewOpen) {
252+
if (hasSupportForOperation(Operation.NikonCaptureDuringLv)) {
253+
Log.d("NikonCamera", "Using NikonCaptureDuringLv (high quality).");
254+
queue.add(new NikonCaptureDuringLvCommand(this));
255+
} else {
256+
Log.d("NikonCamera", "No CaptureDuringLv support, stopping LiveView first.");
257+
queue.add(new NikonStopLiveViewAction(this, false, () -> {
258+
android.util.Log.i("NikonCamera", "StopLiveView requested, waiting for event...");
259+
queue.add(new NikonTakePictureCommand(this));
260+
}));
261+
}
262+
260263
} else {
261-
Log.d("NikonCamera", "No CaptureDuringLv support, stopping LiveView first.");
262-
263-
waitCaptureAfterLvStop = true;
264-
// onPropertyChanged 이벤트에서 실행되도록 위임
265-
queue.add(new NikonStopLiveViewAction(this, false, () -> {
266-
android.util.Log.i("NikonCamera", "StopLiveView requested, waiting for event...");
267-
}));
268-
return;
264+
Log.d("NikonCamera", "Normal capture (LiveView not open).");
265+
queue.add(new NikonTakePictureCommand(this));
269266
}
270-
}
267+
} else {
268+
LiveViewData frame = new LiveViewData();
269+
frame.setFrameReadyListener(bmp -> {
271270

272-
// ✅ 기본 캡처
273-
Log.d("NikonCamera", "Normal capture (LiveView not open).");
274-
queue.add(new InitiateCaptureCommand(this));
275-
}
271+
if (bmp != null) {
272+
Log.d("CameraCapture", "LiveView frame captured, size="
273+
+ bmp.getWidth() + "x" + bmp.getHeight());
274+
275+
// 1. mutable 복사
276+
bmp = bmp.copy(Bitmap.Config.ARGB_8888, true);
277+
Log.d("CameraCapture", "Bitmap copied as mutable");
276278

279+
saveBitmapToPhone(bmp, "liveview_" + System.currentTimeMillis() + ".jpg");
280+
281+
// 3. Fragment listener 호출
282+
if (listener != null) {
283+
int handle = (int) System.currentTimeMillis();
284+
Log.d("CameraCapture", "Notify listener: handle=" + handle);
285+
listener.onCapturedPictureReceived(
286+
handle,
287+
"liveview_" + handle + ".jpg",
288+
bmp,
289+
bmp
290+
);
291+
} else {
292+
Log.w("CameraCapture", "Listener is null, cannot deliver bitmap");
293+
}
294+
} else {
295+
Log.w("CameraCapture", "LiveView frame capture failed, bmp=null");
296+
}
297+
});
298+
getLiveViewPicture(frame);
299+
}
300+
}
301+
@SuppressWarnings("ResultOfMethodCallIgnored")
302+
private void saveBitmapToPhone(Bitmap bmp, String fileName) {
303+
try {
304+
// 저장 경로: Pictures 디렉토리 사용 (API 29+ 대응)
305+
File dir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), "somecamera");
306+
if (!dir.exists()) dir.mkdirs();
307+
308+
File file = new File(dir, fileName);
309+
FileOutputStream out = new FileOutputStream(file);
310+
bmp.compress(Bitmap.CompressFormat.JPEG, 95, out);
311+
out.flush();
312+
out.close();
313+
Log.d("CameraCapture", "Bitmap saved: " + file.getAbsolutePath());
314+
} catch (Exception e) {
315+
Log.e("CameraCapture", "Bitmap save failed", e);
316+
}
317+
}
277318

278319
private int wholeWidth;
279320
private int wholeHeight;

0 commit comments

Comments
 (0)