├── Stacker.app.zip
├── Stacker
├── Assets.xcassets
│ ├── Contents.json
│ └── AppIcon.appiconset
│ │ └── Contents.json
├── main.m
├── Stacker.entitlements
├── Info.plist
├── AppDelegate.h
├── AppDelegate.m
└── Base.lproj
│ └── MainMenu.xib
├── Stacker.xcodeproj
├── project.xcworkspace
│ ├── contents.xcworkspacedata
│ └── xcshareddata
│ │ └── IDEWorkspaceChecks.plist
├── xcuserdata
│ └── pbarnard.xcuserdatad
│ │ └── xcschemes
│ │ └── xcschememanagement.plist
└── project.pbxproj
├── README.md
└── LICENSE
/Stacker.app.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paulrbarnard/stacker/HEAD/Stacker.app.zip
--------------------------------------------------------------------------------
/Stacker/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/Stacker.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Stacker/main.m:
--------------------------------------------------------------------------------
1 | //
2 | // main.m
3 | // Stacker
4 | //
5 | // Created by pbarnard on 30/08/2018.
6 | // Copyright © 2018 ToxicCelery. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | int main(int argc, const char * argv[]) {
12 | return NSApplicationMain(argc, argv);
13 | }
14 |
--------------------------------------------------------------------------------
/Stacker.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/Stacker/Stacker.entitlements:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | com.apple.security.app-sandbox
6 |
7 | com.apple.security.files.user-selected.read-only
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/Stacker.xcodeproj/xcuserdata/pbarnard.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | Stacker.xcscheme
8 |
9 | orderHint
10 | 0
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # stacker
2 | Simple focus stacking controller for the Sony Remote application.
3 | Based on the PC application B8Stack by binarycamera https://github.com/binarycamera/b8stack
4 | All the credit goes to binarycamera.
5 | # Usage
6 | 1. Connect camera to computer using USB cable
7 | 2. Start Sony Imaging Edge
8 | 3. Start Stacker
9 | 4. Set the Shutter Time (The time between shutter actuations).
10 | Note that this needs to allow sufficient time for the Imaging Edge Software to upload the preview
11 | If you finish up with less images than expected increase this time to give Sony a bit more time...
12 | 5. Set the focus delay. This is to give the lens time to move to the new position.
13 | 6. Select the granularity of th emovement.
14 | With a Batis 25 on an A7Riii Fine shas about 300 steps end to,
15 | Medium about 80 and Course about 20. Experiment...
16 | Press Go
17 | # Download
18 | https://www.dropbox.com/s/gt9e0l25t2mg3mu/Stacker.app.zip?dl=1
19 | # Support
20 | Feel free to use the code in any way you like
21 | Send feedback paulrbarnard -at- hotmail -dot- com or throuhg dpreview forum (user:paulrbarnard)
22 |
--------------------------------------------------------------------------------
/Stacker/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "mac",
5 | "size" : "16x16",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "mac",
10 | "size" : "16x16",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "mac",
15 | "size" : "32x32",
16 | "scale" : "1x"
17 | },
18 | {
19 | "idiom" : "mac",
20 | "size" : "32x32",
21 | "scale" : "2x"
22 | },
23 | {
24 | "idiom" : "mac",
25 | "size" : "128x128",
26 | "scale" : "1x"
27 | },
28 | {
29 | "idiom" : "mac",
30 | "size" : "128x128",
31 | "scale" : "2x"
32 | },
33 | {
34 | "idiom" : "mac",
35 | "size" : "256x256",
36 | "scale" : "1x"
37 | },
38 | {
39 | "idiom" : "mac",
40 | "size" : "256x256",
41 | "scale" : "2x"
42 | },
43 | {
44 | "idiom" : "mac",
45 | "size" : "512x512",
46 | "scale" : "1x"
47 | },
48 | {
49 | "idiom" : "mac",
50 | "size" : "512x512",
51 | "scale" : "2x"
52 | }
53 | ],
54 | "info" : {
55 | "version" : 1,
56 | "author" : "xcode"
57 | }
58 | }
--------------------------------------------------------------------------------
/Stacker/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIconFile
10 |
11 | CFBundleIdentifier
12 | $(PRODUCT_BUNDLE_IDENTIFIER)
13 | CFBundleInfoDictionaryVersion
14 | 6.0
15 | CFBundleName
16 | $(PRODUCT_NAME)
17 | CFBundlePackageType
18 | APPL
19 | CFBundleShortVersionString
20 | 1.0
21 | CFBundleVersion
22 | 1
23 | LSApplicationCategoryType
24 | public.app-category.photography
25 | LSMinimumSystemVersion
26 | $(MACOSX_DEPLOYMENT_TARGET)
27 | NSHumanReadableCopyright
28 | Copyright © 2018 ToxicCelery. All rights reserved.
29 | NSMainNibFile
30 | MainMenu
31 | NSPrincipalClass
32 | NSApplication
33 |
34 |
35 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | BSD 2-Clause License
2 |
3 | Copyright (c) 2018, Paul Barnard
4 | All rights reserved.
5 |
6 | Redistribution and use in source and binary forms, with or without
7 | modification, are permitted provided that the following conditions are met:
8 |
9 | * Redistributions of source code must retain the above copyright notice, this
10 | list of conditions and the following disclaimer.
11 |
12 | * Redistributions in binary form must reproduce the above copyright notice,
13 | this list of conditions and the following disclaimer in the documentation
14 | and/or other materials provided with the distribution.
15 |
16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
20 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
23 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 |
--------------------------------------------------------------------------------
/Stacker/AppDelegate.h:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.h
3 | // Stacker
4 | //
5 | // Created by pbarnard on 30/08/2018.
6 | // Copyright © 2018 ToxicCelery.
7 | //
8 |
9 | #import
10 |
11 | @interface AppDelegate : NSObject {
12 | NSAppleScript *key;
13 | int steps;
14 | int stepSize;
15 | int thisStep;
16 | float period;
17 | float focus;
18 | NSTimer *periodTimer;
19 | NSTimer *focusTimer;
20 | NSUserDefaults * prefs;
21 | NSDictionary *defaultPrefs;
22 |
23 |
24 | __weak IBOutlet NSTextField *stepsText;
25 | __weak IBOutlet NSTextField *periodText;
26 | __weak IBOutlet NSTextField *focusText;
27 | __weak IBOutlet NSButton *goButton;
28 | __weak IBOutlet NSTextField *StatusText;
29 | __weak IBOutlet NSButton *stopButton;
30 | __weak IBOutlet NSButton *fineRadio;
31 | __weak IBOutlet NSButton *coarseRadio;
32 | __weak IBOutlet NSButton *xCoarseRadio;
33 | __weak IBOutlet NSButton *homeCheck;
34 | __weak IBOutlet NSSlider *stepSizeSlider;
35 | __weak IBOutlet NSTextField *stepSizeText;
36 | }
37 |
38 |
39 | - (IBAction)stopStack:(id)sender;
40 | - (IBAction)ActionStack:(id)sender;
41 | - (IBAction)stepsChanged:(id)sender;
42 | - (IBAction)periodChanged:(id)sender;
43 | - (IBAction)focusChanged:(id)sender;
44 | - (IBAction)fineChanged:(id)sender;
45 | - (IBAction)coarseChanged:(id)sender;
46 | - (IBAction)xCoarseChanged:(id)sender;
47 | - (IBAction)stepSizeChaged:(id)sender;
48 |
49 |
50 | @end
51 |
52 |
--------------------------------------------------------------------------------
/Stacker/AppDelegate.m:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.m
3 | // Stacker
4 | //
5 | // Created by pbarnard on 30/08/2018.
6 | // Copyright © 2018 ToxicCelery.
7 | //
8 |
9 | #import "AppDelegate.h"
10 |
11 | @interface AppDelegate ()
12 |
13 | @property (weak) IBOutlet NSWindow *window;
14 | @end
15 |
16 | @implementation AppDelegate
17 |
18 | - (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
19 | // Insert code here to initialize your application
20 | NSArray *userDefaults = [NSArray arrayWithObjects:@"10",@"2",@"1",@"0",@"1",@"0",@"1",@"1",nil];
21 | NSArray *keys = [NSArray arrayWithObjects:@"steps",@"period",@"focus",@"fine",@"medium",@"coarse",@"home",@"stepSize",nil];
22 | defaultPrefs = [NSDictionary dictionaryWithObjects:userDefaults forKeys:keys];
23 | prefs = [NSUserDefaults standardUserDefaults];
24 | [prefs registerDefaults:defaultPrefs];
25 |
26 | steps = [[prefs valueForKey:@"steps"] intValue];
27 | stepSize = [[prefs valueForKey:@"stepSize"] intValue];
28 | period = [[prefs valueForKey:@"period"] floatValue];
29 | focus = [[prefs valueForKey:@"focus"] floatValue];
30 | stepsText.intValue = steps;
31 | stepSizeText.intValue = stepSize;
32 | stepSizeSlider.intValue = stepSize;
33 | periodText.floatValue = period;
34 | focusText.floatValue = focus;
35 | StatusText.stringValue = @"";
36 | stopButton.enabled = FALSE;
37 | fineRadio.state = [[prefs valueForKey:@"fine"] boolValue];
38 | coarseRadio.state = [[prefs valueForKey:@"medium"] boolValue];
39 | xCoarseRadio.state = [[prefs valueForKey:@"coarse"] boolValue];
40 | homeCheck.state = [[prefs valueForKey:@"home"] boolValue];
41 | }
42 |
43 | -(BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)sender {
44 | return YES;
45 | }
46 |
47 | - (void)applicationWillTerminate:(NSNotification *)aNotification {
48 | // Insert code here to tear down your application
49 | [prefs setObject:[NSString stringWithFormat:@"%d",steps] forKey:@"steps"];
50 | [prefs setObject:[NSString stringWithFormat:@"%d",stepSize] forKey:@"stepSize"];
51 | [prefs setObject:[NSString stringWithFormat:@"%f",period] forKey:@"period"];
52 | [prefs setObject:[NSString stringWithFormat:@"%f",focus] forKey:@"focus"];
53 | [prefs setObject:[NSString stringWithFormat:@"%ld",(long)fineRadio.state] forKey:@"fine"];
54 | [prefs setObject:[NSString stringWithFormat:@"%ld",(long)coarseRadio.state] forKey:@"medium"];
55 | [prefs setObject:[NSString stringWithFormat:@"%ld",(long)xCoarseRadio.state] forKey:@"coarse"];
56 | [prefs setObject:[NSString stringWithFormat:@"%ld",(long)homeCheck.state] forKey:@"home"];
57 | }
58 |
59 |
60 | - (IBAction)stopStack:(id)sender {
61 | [self stopFocusTimer];
62 | [self stopPeriodTimer];
63 | stopButton.enabled = FALSE;
64 | goButton.enabled = TRUE;
65 | }
66 |
67 | - (IBAction)ActionStack:(id)sender {
68 | dispatch_async(dispatch_get_main_queue(), ^{
69 | [self nearFocus];
70 | self->thisStep = 0;
71 | [self startFocusTimer:2]; // make initial start 2 seconds
72 | });
73 | goButton.enabled = FALSE;
74 | stopButton.enabled = TRUE;
75 | }
76 |
77 | -(void)activateRemote{
78 | NSAppleScript *command = [[NSAppleScript alloc] initWithSource:@"activate application \"Remote\""];
79 | [command executeAndReturnError:nil];
80 | }
81 |
82 | -(void)nearFocus{
83 | if(homeCheck.state == TRUE){
84 | [self activateRemote];
85 | NSAppleScript *command = [[NSAppleScript alloc] initWithSource:@"tell application \"System Events\" to keystroke \"qqqq\""];
86 | [command executeAndReturnError:nil];
87 | [self startFocusTimer:2]; // wait 2 seconds before first frame
88 | }
89 | }
90 |
91 | -(void)stepFocus{
92 | [self activateRemote];
93 | for (int i=0; i
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
695 |
696 |
697 |
698 |
699 |
700 |
701 |
702 |
703 |
704 |
714 |
715 |
716 |
717 |
718 |
719 |
720 |
721 |
722 |
723 |
724 |
725 |
726 |
727 |
728 |
729 |
730 |
731 |
732 |
733 |
734 |
735 |
736 |
737 |
738 |
739 |
740 |
741 |
742 |
743 |
744 |
745 |
746 |
747 |
748 |
749 |
750 |
751 |
752 |
753 |
754 |
755 |
756 |
757 |
758 |
759 |
760 |
761 |
762 |
763 |
764 |
765 |
766 |
767 |
768 |
769 |
770 |
771 |
781 |
782 |
783 |
784 |
785 |
786 |
787 |
788 |
789 |
799 |
809 |
819 |
820 |
821 |
822 |
823 |
824 |
825 |
826 |
827 |
828 |
829 |
830 |
831 |
832 |
833 |
834 |
835 |
836 |
837 |
838 |
839 |
840 |
841 |
842 |
849 |
850 |
851 |
852 |
853 |
854 |
855 |
856 |
857 |
858 |
859 |
860 |
861 |
862 |
863 |
864 |
865 |
866 |
867 |
868 |
869 |
870 |
871 |
872 |
873 |
874 |
875 |
876 |
877 |
878 |
879 |
880 |
881 |
882 |
883 |
884 |
885 |
886 |
887 |
888 |
889 |
890 |
891 |
892 |
893 |
894 |
895 |
896 |
--------------------------------------------------------------------------------