Skip to content

Instantly share code, notes, and snippets.

@bencholmes
Last active September 20, 2018 16:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bencholmes/6f688874a97ff662db007ab4d3111058 to your computer and use it in GitHub Desktop.
Save bencholmes/6f688874a97ff662db007ab4d3111058 to your computer and use it in GitHub Desktop.
A javascript calculator to compare full frame to crop sensor equivalents for focal length, aperture, and ISO.
Calculate full frame to cropped equivalent. First order approximations only. Designed as described by <a href="https://northrup.photo/gear-basics/camera-body-features/sensor-size-crop-factor/">Chelsea and Tony Northrup</a>.
<form name="cropCalculator" action="" method="get">
<table>
<tr>
<td>Crop factor:</td>
<td><input type="text" name="cropFactor" value="1.53"></td>
</tr>
<tr>
<td>Direction:</td>
<td><input type="radio" name="direction" value="toCrop" checked="true" onchange="changeDirection(this);"> to crop</td>
<td><input type="radio" name="direction" value="to35mm" onchange="changeDirection(this);"> to full frame</td>
</tr>
<tr><td><br></td></tr>
<tr>
<th></th>
<th>Min</th>
<th>Max</th>
</tr>
<tr>
<td><span id="cropOrFFLabelfocal">Crop</span> focal length:</td>
<td><input type="text" name="inputFocalMin" value="20"></td>
<td><input type="text" name="inputFocalMax" value="70"></td>
</tr>
<tr>
<td><span id="cropOrFFLabelaperture">Crop</span> aperture:</td>
<td><input type="text" name="inputApMin" value="1.8"></td>
<td><input type="text" name="inputApMax" value="16"></td>
</tr>
<tr>
<td><span id="cropOrFFLabeliso">Crop</span> ISO noise:</td>
<td><input type="text" name="inputIsoMin" value="100"></td>
<td><input type="text" name="inputIsoMax" value="1600"></td>
</tr>
<tr><td><i>is equivalent to</i></td></tr>
<tr>
<td>Crop Focal Length:</td>
<td><span id="outputFocalMin"></span></td>
<td><span id="outputFocalMax"></span></td>
</tr>
<tr>
<td>Crop Aperture:</td>
<td><span id="outputApMin"></span></td>
<td><span id="outputApMax"></span></td>
</tr>
<tr>
<td>Crop ISO noise:</td>
<td><span id="outputIsoMin"></span></td>
<td><span id="outputIsoMax"></span></td>
</tr>
</table>
<br>
<input type="button" value="Calculate" onClick="calculateCrop(this.form)">
</form>
<script>
function changeDirection(radio) {
var toCrop = radio.value == "toCrop";
var doc = radio.ownerDocument;
var typeString = "Full Frame";
if (toCrop){
typeString = "Crop";
}
var allSpans = doc.getElementsByTagName("span");
for(ii=0; ii<allSpans.length; ii++) {
if (allSpans[ii].id.includes("cropOrFFLabel")) {
allSpans[ii].innerHTML = typeString;
}
}
}
function roundFstop(x) {
var localError = [1e10, 1e9];
var ii = 0;
while( (ii<15) && (localError[0]>localError[1]) ) {
localError[0] = localError[1];
localError[1] = Math.abs(x - Math.pow(1.414, ii));
ii++;
}
var y = Math.round(Math.pow(1.414, ii-2)*10)*0.1;
return y.toFixed(1);
}
function roundISO(x) {
commonISOs = [100, 200, 400, 800, 1600, 3200, 6400];
var ii=0;
var err = [1e10, 1e9];
while( (ii<commonISOs.length) && (err[0]>err[1]) ) {
err[0] = err[1];
err[1] = Math.abs(x - commonISOs(ii));
ii++;
}
}
function calculateCrop (form) {
var cf = form.cropFactor.value;
var toCrop = form.direction.value == "toCrop";
var scalingFactor = cf;
if(!toCrop){
scalingFactor = 1/cf;
}
var document = form.ownerDocument;
document.getElementById("outputFocalMin").innerHTML = (form.elements.namedItem("inputFocalMin").value*scalingFactor).toFixed(0);
document.getElementById("outputFocalMax").innerHTML = (form.elements.namedItem("inputFocalMax").value*scalingFactor).toFixed(0);
document.getElementById("outputApMin").innerHTML = roundFstop(form.elements.namedItem("inputApMin").value*scalingFactor);
document.getElementById("outputApMax").innerHTML = roundFstop(form.elements.namedItem("inputApMax").value*scalingFactor);
document.getElementById("outputIsoMin").innerHTML = roundFstop(form.elements.namedItem("inputIsoMin").value*scalingFactor*scalingFactor);
document.getElementById("outputIsoMax").innerHTML = roundFstop(form.elements.namedItem("inputIsoMax").value*scalingFactor*scalingFactor);
}
calculateCrop(cropCalculator);
</script>
</p>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment