Skip to content
Back to the blog
· 8 min read · Alexander Nassian

Scanora 0.11.0: Why Photos Came Out Wrong – and What the Sensor Actually Measures

Scanora 0.11.0 is on the Mac App Store. Why photos came out too bright, too dark or cropped, what linear sensor data has to do with it, and what the update changes for documents.

In short: Scanora 0.11.0 is on the Mac App Store. It is mostly about photos: until now they came out too bright or too dark, and cut off at the edges. Behind that were three assumptions that hold for documents and not for photos – and a property of the sensor that affected documents too. A profile can now be set to “Original: Photo”, and documents come out with clean paper and natural colour. This post describes what lay behind it and what we found at the device along the way.

The occasion: photos that did not look like the print

Scanora is our macOS app for the KODAK E1030, a sheetfed scanner for which the manufacturer offers no macOS driver. The app speaks the device’s USB protocol directly and turns the sensor image into finished pages: it finds the sheet, straightens it, balances the white and reads the text.

In early November a customer wrote to us that their photo prints came out sometimes too bright, sometimes too dark, and as if zoomed in. Each of those processing steps had been tuned on paper with writing on it, and a photo contradicts three of their assumptions at once: its edge can be dark, it has no white paper, and it holds no lines of text to measure the skew from. On top of that came a property of the sensor that only showed when we measured again.

First: dark edges taken for the backing

Behind the sheet the sensor sees an almost black backing. Scanora finds the sheet where the image is brighter than that backing. Until now the red channel alone decided, against a threshold of 40. For white paper that is plenty. A photo, though, is often darker than that at its edge – shadow, foliage, a dark sky, a band of deep blue. The detected edge moved into the picture, and the crop followed it. A synthetic 10 × 15 print with a shadowed side kept 37 % of its area; a flyer with a dark blue header lost the header.

Now every pixel counts by its brightest colour channel, and the threshold is 16, twice the strongest noise we have ever measured on the backing. In the tests that solved it. At the device it did not.

The check with a real Polaroid found a line running through the whole frame: two pixels wide, about 31 bright in every channel – dust or a scratch on the scanner glass. The old threshold had missed it by a single count; the new one took it for the right edge of the sheet in every row. The Polaroid, 88 mm wide, measured 149.8 mm. Since then an edge is only a pixel that begins a millimetre of brightness, twelve pixels in a row at 300 dpi. A line on the glass is a few pixels across; paper never is.

That second condition allowed one more step. A business card printed almost black read only 12 to 23 at its edge, the backing beside it 0 to 3. At a threshold of 16, half its rows found no millimetre of brightness, the left edge landed on the lettering, and the card came out 80.5 mm wide and turned by 2.8° it did not have. The threshold is now 10. That is close to the noise and safe only because twelve pixels in a row above 10 do not occur in the backing. The same raw data, measured again: 85.0 × 54.4 mm, whole and straight.

One last cut had nothing to do with brightness. The scanner starts and stops capturing on its paper sensor, not on the corners of the sheet. When an original goes in crooked, a corner is missing at each end. Scanora took the length from the captured rows – the largest rectangle that fits inside them – and so cut 3 to 4 mm off the top and 2 to 3 mm off the bottom of the crooked Polaroid. On a borderless print that would have been picture. Now the length is the extent of the captured paper along the sheet’s own axis, and what the sensor never saw is filled in white. The Polaroid measures 88.6 × 107.8 mm, with a 6.6 mm border at the top and 22 mm at the bottom, as on the print.

Second: a white balance without white

The white balance used to take every page on its own: whatever lifted its brightest half percent to 247 was applied, per colour channel and with no upper limit. On a document the brightest half percent is the paper, and that is exactly what should turn white. A photo has no paper white. A synthetic evening scene got factors of 1.9, 2.6 and 3.2 for red, green and blue that way, and a warm brown (103, 75, 56) became a uniform grey (164, 164, 164).

The correction is now anchored on what this sensor reads for paper, and a page may lift a channel to at most 1.3 times that. Thermal paper that reads only 171 still turns white; the evening scene stays warm. With “Original: Photo” a picture gets only the device’s correction and nothing measured on the page itself: 103, 75, 56 comes out as 100, 73, 54.

Third: the sensor measures light, not a picture

This is why photos came out too dark – and it affected documents too. The sensor counts light linearly: twice the light, twice the value. Image files and displays expect values encoded for the eye (sRGB), which give the dark tones far more steps. The scanner applies such a tone curve only when one is loaded into it, and Scanora loaded none. The linear values were stored as they came.

On a document that hardly shows; black type on white paper even gains contrast from it. On a photo every mid-tone and every shadow is far too dark. The dark trees on the Polaroid read 8 against its paper at 219 – the few per cent of light such a print reflects. They were stored as 9 of 255, nearly black. Encoded they sit at about a fifth of the range, as on the print. With “Original: Photo” Scanora now encodes with the sRGB curve, to a sixteenth of a count: at the dark end one linear count is several encoded ones, and rounding early would show there.

But the linear rendering had its cost on documents as well: creases and shading came out as grey mottle, the back showed through, colour logos looked heavy. At the device we compared a thermal receipt and a letter with a colour logo in three renderings: linear, the plain sRGB curve, and the curve with a black point at the ink. The plain curve cleaned the paper and turned the type grey. With the black point at 5 % of the paper’s brightness the type stayed as black as linear, the paper came out as clean as with the curve, and the colours looked as they do on the letter. That is now the document curve. The letter’s image file got a fifth smaller on top.

What is stored and what is read

The new curve had one drawback: on faint thermal print the text recognition read worse. On the receipt “0,45” became “0.45”, and the date and the dotted logo came out wrong where the linear rendering had read them right.

So text recognition now reads a linear rendering of the same page – same crop, same turn, so the text layer in the PDF sits exactly on the stored image – and the rendering with the curve is what is kept. Both test documents then read word for word as before. The second rendering is made only when a profile asks for text recognition.

The new settings

  • Original: Document or Photo, per profile. A photo gets only the device’s colour correction, is never flattened, and is straightened by its edge: a print sits square on its paper, and measuring the skew from the picture’s content finds an angle over blinds or a horizon that is not there.
  • Crop automatically, on by default. Switched off, Scanora keeps the whole sensor frame, unturned – for originals whose edge is as dark as the scanner’s backing. Straightening is greyed out then.
  • Existing profiles open as Document with cropping switched on.

The complete release notes are on the product page.

What this means for device projects

Scanora is a small product, but the faults in this release are typical of any device with a sensor. Four things we take from it:

  1. Know what the sensor delivers. Linear measurements and encoded image values look the same in a file and are not. Tune processing on data whose encoding you do not know, and you tune it on an accident – here on black type, which even benefited from the linear rendering.
  2. Check at the device, with real originals. The synthetic test images all passed. The line on the glass and the black card only showed at the scanner; both are now in the tests with their measured values.
  3. A threshold close to the noise needs a second criterion. Brightness alone does not tell paper from dust. Brightness over a minimum width does – and is what makes the low threshold possible at all.
  4. What you store and what you analyse need not be the same image. The eye wants a curve; text recognition on faint print does not. Making both from the same raw data costs a little computing time and saves a compromise.

How to check software against the real device regularly, rather than against test data alone, is covered in our article on hardware-in-the-loop testing.


Scanora is an independent product of bitshift dynamics GmbH and is not affiliated with the owner of the KODAK trademark. The model name says only which device the app works with.

Frequently asked questions

How do I get Scanora 0.11.0?
Through the Mac App Store. If automatic updates are switched on there, the update arrives by itself; otherwise you will find it under Updates in the App Store. The requirements are unchanged: macOS 13 or later and a Mac with Apple silicon.
When do I choose Photo, and when Document?
Photo for photographic prints and other pictures without white paper: colours and brightness stay as they are on the original, and it is straightened by its edge. Document for anything with writing on paper: the paper turns white, and it is straightened by the writing. The setting belongs to the profile; a profile of its own for photos is the easiest way.
Do my existing profiles change?
Their settings do not: profiles from earlier versions open as Document with cropping switched on. The pages still look different from before – clean paper, natural colour, and the type stays black.
My photo still gets cropped. What helps?
Feed photos one at a time with the guides set close, so the print goes in straight. If the original's edge is as dark as the scanner's backing, no threshold finds it; then switch off Crop automatically in the profile. Scanora then keeps the whole sensor frame, unturned.

Alexander Nassian

Managing Director, bitshift dynamics

Builds hardware-adjacent software for embedded products with his team – C++, Qt/QML, Embedded Linux and the Yocto Project. bitshift dynamics has worked in this field since 2005.

Related articles

11 min read

Yocto BSP: How to Build a Board Support Package That Lasts

How a Yocto BSP layer is structured – machine configuration, kernel and device tree, U-Boot, image layout – and the rules that keep it maintainable from one Yocto LTS release to the next.

  • Yocto
  • BSP
  • Embedded Linux
Read more

Facing a similar challenge?

We support embedded teams with exactly these questions – from the architecture decision through to production readiness. Tell us briefly what you're working on.

Start a project