Camera exposure logic is in place. Will take a photo with the device camera and use the exif data to determine the correct exposure for the bolex.
- Determines # of stops between fstop of phone and set fstop of bolex - Determines # of stops between iso of phone and set iso of bolex - Compensates for the 0.8 prism constant
This commit is contained in:
parent
7a392aba0e
commit
4b72c9eeed
|
@ -1,3 +1,7 @@
|
||||||
|
/* jshint esversion:6, strict:true, browser:true*/
|
||||||
|
/* global console, alert */
|
||||||
|
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
var mobile = {};
|
var mobile = {};
|
||||||
|
|
||||||
|
@ -29,7 +33,7 @@ mobile.ble.scan = function () {
|
||||||
alert('No INTVAL devices found.');
|
alert('No INTVAL devices found.');
|
||||||
settingsPage();
|
settingsPage();
|
||||||
}
|
}
|
||||||
}, 5000)
|
}, 5000);
|
||||||
};
|
};
|
||||||
|
|
||||||
mobile.ble.onDiscover = function (device) {
|
mobile.ble.onDiscover = function (device) {
|
||||||
|
@ -43,18 +47,18 @@ mobile.ble.onDiscover = function (device) {
|
||||||
} else {
|
} else {
|
||||||
//console.log(`BLE - Discovered Other ${device.id}`);
|
//console.log(`BLE - Discovered Other ${device.id}`);
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
mobile.ble.connect = function (device) {
|
mobile.ble.connect = function (device) {
|
||||||
console.log(`BLE - Connecting to ${device.id}`)
|
console.log(`BLE - Connecting to ${device.id}`);
|
||||||
ble.connect(device.id, (peripheral) => {
|
ble.connect(device.id, (peripheral) => {
|
||||||
mobile.ble.onConnect(peripheral, device);
|
mobile.ble.onConnect(peripheral, device);
|
||||||
}, mobile.ble.onError);
|
}, mobile.ble.onError);
|
||||||
};
|
};
|
||||||
|
|
||||||
mobile.ble.onConnect = function (peripheral, device) {
|
mobile.ble.onConnect = function (peripheral, device) {
|
||||||
const elem = document.getElementById('bluetooth')
|
const elem = document.getElementById('bluetooth');
|
||||||
const option = document.createElement('option')
|
const option = document.createElement('option');
|
||||||
const disconnect = document.getElementById('disconnect');
|
const disconnect = document.getElementById('disconnect');
|
||||||
const scan = document.getElementById('scan');
|
const scan = document.getElementById('scan');
|
||||||
|
|
||||||
|
@ -85,11 +89,11 @@ mobile.ble.disconnect = function () {
|
||||||
const scan = document.getElementById('scan');
|
const scan = document.getElementById('scan');
|
||||||
let device;
|
let device;
|
||||||
if (!mobile.ble.connected) {
|
if (!mobile.ble.connected) {
|
||||||
console.warn('Not connected to any device')
|
console.warn('Not connected to any device');
|
||||||
return false
|
return false;
|
||||||
}
|
}
|
||||||
device = mobile.ble.device
|
device = mobile.ble.device;
|
||||||
console.log(`BLE - Disconnecting from ${device.id}`)
|
console.log(`BLE - Disconnecting from ${device.id}`);
|
||||||
ble.disconnect(device.id, mobile.ble.onDisconnect, mobile.ble.onDisconnect);
|
ble.disconnect(device.id, mobile.ble.onDisconnect, mobile.ble.onDisconnect);
|
||||||
|
|
||||||
elem.innerHTML = '';
|
elem.innerHTML = '';
|
||||||
|
@ -112,6 +116,9 @@ mobile.ble.onError = function (err) {
|
||||||
|
|
||||||
mobile.init = function () {
|
mobile.init = function () {
|
||||||
const bleInputs = document.querySelectorAll('.ble');
|
const bleInputs = document.querySelectorAll('.ble');
|
||||||
|
const bolIso = document.querySelector('.iso');
|
||||||
|
const bolF = document.querySelector('.fstop');
|
||||||
|
|
||||||
document.querySelector('body').classList.add('mobile');
|
document.querySelector('body').classList.add('mobile');
|
||||||
|
|
||||||
window.frame = mobile.frame;
|
window.frame = mobile.frame;
|
||||||
|
@ -128,13 +135,13 @@ mobile.init = function () {
|
||||||
}
|
}
|
||||||
spinnerInit();
|
spinnerInit();
|
||||||
mobile.ble.scan();
|
mobile.ble.scan();
|
||||||
mobile.cameraValues()
|
mobile.cameraValues();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
mobile.getState = function () {
|
mobile.getState = function () {
|
||||||
if (!mobile.ble.connected) {
|
if (!mobile.ble.connected) {
|
||||||
//
|
//returning here will prevent error alert
|
||||||
}
|
}
|
||||||
ble.read(mobile.ble.device.id,
|
ble.read(mobile.ble.device.id,
|
||||||
mobile.ble.SERVICE_ID,
|
mobile.ble.SERVICE_ID,
|
||||||
|
@ -145,7 +152,7 @@ mobile.getState = function () {
|
||||||
mobile.stateSuccess = function (data) {
|
mobile.stateSuccess = function (data) {
|
||||||
let str = bytesToString(data);
|
let str = bytesToString(data);
|
||||||
let res = JSON.parse(str);
|
let res = JSON.parse(str);
|
||||||
setState(res)
|
setState(res);
|
||||||
};
|
};
|
||||||
|
|
||||||
mobile.frame = function () {
|
mobile.frame = function () {
|
||||||
|
@ -229,7 +236,7 @@ mobile.exposureSuccess = function () {
|
||||||
|
|
||||||
mobile.setDelay = function () {
|
mobile.setDelay = function () {
|
||||||
const delay = document.getElementById('delay').value;
|
const delay = document.getElementById('delay').value;
|
||||||
const scaledDelay = scaleTime(delay, STATE.delayScale)
|
const scaledDelay = scaleTime(delay, STATE.delayScale);
|
||||||
let opts = {
|
let opts = {
|
||||||
type : 'delay',
|
type : 'delay',
|
||||||
delay : scaledDelay
|
delay : scaledDelay
|
||||||
|
@ -243,7 +250,7 @@ mobile.setDelay = function () {
|
||||||
}
|
}
|
||||||
|
|
||||||
mobile.delaySuccess = function () {
|
mobile.delaySuccess = function () {
|
||||||
console.log('Set delay')
|
console.log('Set delay');
|
||||||
mobile.getState();
|
mobile.getState();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -417,6 +424,7 @@ mobile.setWifiSuccess = function () {
|
||||||
console.log('Set new wifi credentials');
|
console.log('Set new wifi credentials');
|
||||||
setTimeout(mobile.getWifi, 100);
|
setTimeout(mobile.getWifi, 100);
|
||||||
};
|
};
|
||||||
|
mobile.exif = {}
|
||||||
|
|
||||||
mobile.getCamera = function () {
|
mobile.getCamera = function () {
|
||||||
const opts = {
|
const opts = {
|
||||||
|
@ -430,62 +438,171 @@ mobile.cameraSuccess = function (result) {
|
||||||
const thisResult = JSON.parse(result);
|
const thisResult = JSON.parse(result);
|
||||||
const metadata = JSON.parse(thisResult.json_metadata);
|
const metadata = JSON.parse(thisResult.json_metadata);
|
||||||
|
|
||||||
mobile.cameraExposure(fstop, metadata);
|
mobile.cameraExposure(metadata.Exif);
|
||||||
}
|
};
|
||||||
mobile.cameraError = function (err) {
|
mobile.cameraError = function (err) {
|
||||||
console.error(err);
|
console.error(err);
|
||||||
alert(err);
|
alert(err);
|
||||||
};
|
};
|
||||||
|
|
||||||
mobile.cameraExposure = function (exif) {
|
mobile.cameraExposure = function (exif) {
|
||||||
const fstop = BOLEX.fstop || 5.6;
|
const cam_exp = document.getElementById('cam_exp');
|
||||||
|
const cam_f = document.getElementById('cam_f');
|
||||||
|
const cam_iso = document.getElementById('cam_iso');
|
||||||
|
const bol_exp = document.getElementById('bol_exp');
|
||||||
|
const bol_f = document.getElementById('bol_f');
|
||||||
|
const bol_iso = document.getElementById('bol_iso');
|
||||||
|
const bol_f_diff = document.getElementById('bol_f_diff');
|
||||||
|
const bol_iso_diff = document.getElementById('bol_iso_diff');
|
||||||
|
const bol_exp_diff = document.getElementById('bol_exp_diff');
|
||||||
|
|
||||||
|
const fstop = BOLEX.fstop || 5.6;
|
||||||
const iso = BOLEX.iso || 100;
|
const iso = BOLEX.iso || 100;
|
||||||
|
const prism = BOLEX.prism || 0.8;
|
||||||
|
|
||||||
const cFstop = exif.AperatureValue || exif.FNumber;
|
const cFstop = exif.ApertureValue || exif.FNumber;
|
||||||
const cExposure = exif.ShutterSpeedValue ? (1 / exif.ShutterSpeedValue) * 1000 : exif.ExposureTime * 1000;
|
const cExposure = exif.ExposureTime * 1000;
|
||||||
const cISO = exif.ISOSpeedRatings[0];
|
const cIso = exif.ISOSpeedRatings[0];
|
||||||
|
|
||||||
|
//convert fstop to "fnumber", an absolute scale where stops are scaled to 1.0
|
||||||
|
const f = mobile.fnumber(cFstop);
|
||||||
|
const target = mobile.fnumber(fstop); //bolex
|
||||||
|
|
||||||
|
let exposure = cExposure;
|
||||||
|
let isoStops = 0;
|
||||||
|
let fStops = 0;
|
||||||
|
let scale_elem;
|
||||||
|
let exposure_elem;
|
||||||
|
let proceed;
|
||||||
|
let e1;
|
||||||
|
let e2;
|
||||||
|
|
||||||
|
mobile.exif = exif;
|
||||||
|
console.dir(exif);
|
||||||
|
|
||||||
|
console.log(`fstop : ${fstop}`);
|
||||||
|
console.log(`iso : ${iso}`);
|
||||||
|
bol_f.value = fstop;
|
||||||
|
bol_iso.value = iso;
|
||||||
|
|
||||||
|
console.log(`cExposure : ${cExposure}`);
|
||||||
|
console.log(`cFstop : ${cFstop}`);
|
||||||
|
console.log(`cIso : ${cIso}`);
|
||||||
|
cam_exp.value = cExposure;
|
||||||
|
cam_f.value = cFstop;
|
||||||
|
cam_iso.value = cIso;
|
||||||
|
|
||||||
|
console.log(`f : ${f}`);
|
||||||
|
console.log(`target : ${target}`);
|
||||||
|
|
||||||
|
//Determine if fstop of phone camera "f"
|
||||||
|
if (target !== f) {
|
||||||
|
fStops = f - target;
|
||||||
|
exposure = exposure / Math.pow(2, fStops);
|
||||||
|
}
|
||||||
|
bol_f_diff.innerHTML = Math.round(parseFloat(-fStops) * 10) / 10;
|
||||||
|
console.log(`fstops : ${fStops}`);
|
||||||
|
console.log(`exposure => ${exposure}`);
|
||||||
|
|
||||||
|
if (cIso != iso) {
|
||||||
|
isoStops = (Math.log(cIso) / Math.log(2)) - (Math.log(iso) / Math.log(2));
|
||||||
|
}
|
||||||
|
bol_iso_diff.innerHTML = Math.round(parseFloat(isoStops) * 10) / 10;
|
||||||
|
console.log(`isoStops : ${isoStops}`)
|
||||||
|
|
||||||
|
//Double or halve exposure based on the differences in ISO stops
|
||||||
|
exposure = exposure * Math.pow(2, isoStops);
|
||||||
|
console.log(`exposure => ${exposure}`);
|
||||||
|
|
||||||
|
console.log(`prism : ${prism}`);
|
||||||
|
//Compensate for Bolex prism
|
||||||
|
exposure = exposure * Math.pow(2, prism);
|
||||||
|
console.log(`exposure => ${prism}`);
|
||||||
|
|
||||||
|
exposure = Math.round(exposure) //round to nearest millisecond
|
||||||
|
bol_exp.value = exposure;
|
||||||
|
bol_exp_diff.value = 0;
|
||||||
|
|
||||||
|
if (exposure > 500) {
|
||||||
|
proceed = confirm(`Set camera exposure to ${exposure}ms to match photo.`);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (proceed && exposure > 500) {
|
||||||
|
e1 = new Event('change');
|
||||||
|
e2 = new Event('change');
|
||||||
|
|
||||||
|
scale_elem = document.getElementById('scale');
|
||||||
|
exposure_elem = document.getElementById('exposure');
|
||||||
|
|
||||||
|
scale_elem.value = 'ms';
|
||||||
|
scale_elem.dispatchEvent(e1);
|
||||||
|
|
||||||
|
exposure_elem.value = exposure;
|
||||||
|
exposure_elem.dispatchEvent(e2);
|
||||||
|
}
|
||||||
|
|
||||||
alert(`${fstop} ${iso} ${cFstop} ${cISO} ${cExposure}`);
|
|
||||||
/*
|
/*
|
||||||
ApertureValue: 1.6959938131099002
|
{
|
||||||
BrightnessValue: -0.3966568568788107
|
"Exif": {
|
||||||
ColorSpace: 65535
|
"DateTimeOriginal": "2018:02:02 16:59:13",
|
||||||
DateTimeDigitized: "2018:01:08 23:06:13"
|
"ExposureBiasValue": 0,
|
||||||
DateTimeOriginal: "2018:01:08 23:06:13"
|
"SensingMethod": 2,
|
||||||
ExposureBiasValue: 0
|
"BrightnessValue": -0.9969016228800144,
|
||||||
ExposureMode: 0
|
"LensMake": "Apple",
|
||||||
ExposureProgram: 2
|
"FNumber": 1.8,
|
||||||
ExposureTime: 0.2
|
"FocalLength": 3.99,
|
||||||
FNumber: 1.8
|
"ShutterSpeedValue": 2.049355412374274,
|
||||||
Flash: 24
|
"SceneType": 1,
|
||||||
FocalLenIn35mmFilm: 28
|
"ApertureValue": 1.6959938131099002,
|
||||||
FocalLength: 3.99
|
"SubjectArea": [
|
||||||
ISOSpeedRatings: [100] (1)
|
2015,
|
||||||
LensMake: "Apple"
|
1511,
|
||||||
LensModel: "iPhone 8 back camera 3.99mm f/1.8"
|
2217,
|
||||||
LensSpecification: [3.99, 3.99, 1.8, 1.8] (4)
|
1330
|
||||||
MeteringMode: 5
|
],
|
||||||
PixelXDimension: 4032
|
"ColorSpace": 65535,
|
||||||
PixelYDimension: 3024
|
"LensSpecification": [
|
||||||
SceneType: 1
|
3.99,
|
||||||
SensingMethod: 2
|
3.99,
|
||||||
ShutterSpeedValue: 2.38401125849867
|
1.8,
|
||||||
SubjectArea: [2015, 1511, 2217, 1330] (4)
|
1.8
|
||||||
SubsecTimeDigitized: "567"
|
],
|
||||||
SubsecTimeOriginal: "567"
|
"PixelYDimension": 3024,
|
||||||
WhiteBalance: 0
|
"WhiteBalance": 0,
|
||||||
|
"DateTimeDigitized": "2018:02:02 16:59:13",
|
||||||
|
"ExposureMode": 0,
|
||||||
|
"ISOSpeedRatings": [
|
||||||
|
100
|
||||||
|
],
|
||||||
|
"PixelXDimension": 4032,
|
||||||
|
"LensModel": "iPhone 8 back camera 3.99mm f/1.8",
|
||||||
|
"ExposureTime": 0.25,
|
||||||
|
"Flash": 24,
|
||||||
|
"SubsecTimeDigitized": "209",
|
||||||
|
"SubsecTimeOriginal": "209",
|
||||||
|
"ExposureProgram": 2,
|
||||||
|
"FocalLenIn35mmFilm": 28,
|
||||||
|
"MeteringMode": 5
|
||||||
|
}
|
||||||
|
}
|
||||||
*/
|
*/
|
||||||
};
|
};
|
||||||
mobile.cameraValues = function () {
|
|
||||||
document.querySelectorAll('.iso').forEach(input => {
|
mobile.refreshExposure = function () {
|
||||||
input.onchange = function () {
|
if (typeof mobile.exif.ExposureTime !== 'undefined') {
|
||||||
var val = this.value;
|
mobile.cameraExposure(mobile.exif);
|
||||||
document.querySelectorAll('.iso').forEach(e => {
|
}
|
||||||
e.value = val;
|
};
|
||||||
})
|
|
||||||
}
|
mobile.fnumber = function (fstop) {
|
||||||
})
|
return Math.log(fstop) / Math.log(Math.sqrt(2));
|
||||||
}
|
};
|
||||||
|
|
||||||
|
mobile.EV = function (fstop, shutter) {
|
||||||
|
const sec = shutter / 1000; //shutter in ms => seconds
|
||||||
|
const square = Math.pow(fstop, 2);
|
||||||
|
return Math.log(square / sec);
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mobile helper functions
|
* Mobile helper functions
|
||||||
|
@ -493,11 +610,12 @@ mobile.cameraValues = function () {
|
||||||
|
|
||||||
function bytesToString (buffer) {
|
function bytesToString (buffer) {
|
||||||
return String.fromCharCode.apply(null, new Uint8Array(buffer));
|
return String.fromCharCode.apply(null, new Uint8Array(buffer));
|
||||||
};
|
}
|
||||||
|
|
||||||
function stringToBytes(string) {
|
function stringToBytes(string) {
|
||||||
var array = new Uint8Array(string.length);
|
var array = new Uint8Array(string.length);
|
||||||
for (var i = 0, l = string.length; i < l; i++) {
|
for (var i = 0, l = string.length; i < l; i++) {
|
||||||
array[i] = string.charCodeAt(i);
|
array[i] = string.charCodeAt(i);
|
||||||
}
|
}
|
||||||
return array.buffer;
|
return array.buffer;
|
||||||
};
|
}
|
Loading…
Reference in New Issue