Friday, November 6, 2015

Hyperfocal distance with cropped image cheatsheet

TLDR: Hyperfocal distance is proportional to enlargement.

What happens to the hyperfocal distance if you intend to print a crop at the same size for the same viewing distance?

Back to basic assumptions:
  • Visual acuity of 5lp/mm at 25cm viewing distance. This is equivalent to a final print circle of confusion of 0.2mm.
  • Print size is 8x12. Enlargement = 12"/36mm = 8.47. Circle of confusion = 0.2mm/8.47 = 0.0236mm.
  • If you crop and print at the same size, you increase enlargement and decrease the circle of confusion.

Hyperfocal distance is inversely proportional to circle of confusion and is proportional to enlargement.


35mm full frame fixed focal length camera
f8.0 aperture
8x12 print size

Hyperfocal distance = 35 * 35 / 8 / 0.0236 = 6.5m.
With 1.5x crop (simulated 52mm), hyperfocal distance = 9.7m.
With 2x crop (simulated 70mm), hyperfocal distance = 13m.


Viewing distance is traditionally supposed to depend on the focal length (to get the same perspective), but these days, everything is viewed at phone distance :)

Thursday, November 5, 2015

Fix Whatsapp picture capture time

Whatsapp strips all EXIF info from any pictures sent through it. Without any EXIF info, Lightroom uses the file modification time as the capture time. If for some reason, the file modification time is wrong, then Lightroom gets confused. Luckily, Whatsapp puts the date in the filename. But Lightroom doesn't know about it.

So, here's a little Go program that changes the file modification time of files to the date in the filenames. Since the exact time is unknown, it is set to 3am local time.

Public domain. Use at your own risk.

package main

import (

var trial = flag.Bool("n", true, "trail run")

func main() {
        for _, f := range flag.Args() {

var re = regexp.MustCompile(`^([^-]*-)([0-9][0-9][0-9][0-9])([0-9][0-9])([0-9][0-9])(-WA.*)$`)

func fix(f string) {
        match := re.FindStringSubmatch(f)
        if len(match) > 0 {
                y, _ := strconv.Atoi(match[2])
                m, _ := strconv.Atoi(match[3])
                d, _ := strconv.Atoi(match[4])
                update(f, y, m, d)

func update(f string, y int, m int, d int) {
        s, err := os.Stat(f)
        if err != nil {
                fmt.Printf("Unable to stat file %v\n", f)
        oldy, oldm, oldd := s.ModTime().Date()
        if y != oldy || time.Month(m) != oldm || d != oldd {
                t := time.Date(y, time.Month(m), d, 3, 0, 0, 0, time.Local)
                fmt.Printf("%v: %v -> %v\n", f, s.ModTime(), t)
                if !*trial {
                        err := os.Chtimes(f, time.Now(), t)
                        if err != nil {
                                fmt.Printf("Failed to change time on %v\n", f)

Wednesday, September 12, 2012

Hyperfocal Distance Cheat

This post was from before the big reset. I keep coming back to this post to recompute the magic number for various lenses. I hope somebody finds this useful.

The magic number for Canon 5D mk II with 40mm 2.8 STM is 53 which is twice that of X100 with 23mm.


Once upon a time, I stumbled upon this concept called hyperfocal distance. For each given focal length, aperture and size of the circle of confusion, you can calculate a special number called the hyperfocal distance. When you focus the lens at the hyperfocal distance, everything from half the distance to infinity will be acceptably sharp. This maximizes the depth of field. This is useful for landscapes or groups of people.

There is only one problem. I have to memorize a table of values for each focal length and aperture. Yucks! Sure, I can carry a little pre-calculated table of values. Better but still yucks! Or use a phone app that will calculate it on the fly. That's too slow. Still yucks.

The X100 only has one focal length, 23mm. That's easy. I only need to memorize one chart:
f/2       13.2m
f/2.8     9.37m
f/4        6.64m
f/5.6     4.7m
f/8        3.33m
(computed online using DOFmaster)

Easier, but I'm no Tiger mom trained memorizing machine.

Oh, wait. If I multiply the aperture number by the hyperfocal distance, I get a number slightly above 26. All I need to remember is the number 26! That I can do!

It can't be a coincidence. So, I plugged in numbers into DOFmaster for 5D Mk II at 50mm. The product is about 83. That's when I finally went for the formula. Yes, I should have done it years ago. Stupid me. Wikipedia says:
H = f * f / N / c
(ignoring the irrelevant +f)
H is the hyperfocal distance
f is the focal length
N is the aperture number
c is the size of the circle of confusion
Using 0.02mm for circle of confusion, 23mm for focal length, I reproduced the table for X100. That checked out. Since f and c are constant, the formula reduces to:
H = C / N
C = f * f / c
For the X100, C = 23mm * 23mm / 0.02mm = 26450mm = 26.45m!

So, to find the hyperfocal length for any aperture, just divide 26.45m by the aperture number! Piece of cake!

Also notice that if you double the focal length, the hyperfocal distance goes up by 4.

For 5D Mk II with a 24mm wide angle lens, the magic number is 19.2m. For 50mm normal, you won't be too far off if you guessed it is about 80m (50 * 50 / 0.03 = 83.33m).

Interestingly, if I'm shooting at f/5.6 on the X100, everything from 2.3m will be in focus if I focus at 4.7m. I can just pre-focus at 4.7m, switch to manual focus to lock it and forget about focusing altogether! This will also be great for videos. The X100's movie mode does not track faces and it tends to shift the focus unnecessarily especially if the background has some high-contrast items like lights.

Hello world!

Hello, world
Hello, 世界