Skip to content

negaflow 1.0.3

Choose a tag to compare

@habinsong habinsong released this 29 Jul 12:54

English · 한국어 · 日本語 · 简体中文 · Français · Deutsch

Downloads

  • Most Macs: negaflow-1.0.3-1-macOS-universal.pkg
  • Apple Silicon only: negaflow-1.0.3-1-macOS-arm64.pkg
  • ZIP and DMG files for manual installation are provided as well.

Important: signing and notarization status

These artifacts are ad-hoc signed and are not notarized by Apple. macOS may block the first launch. Verify the download against the accompanying SHA256SUMS file, try to open it once, and allow it in System Settings → Privacy & Security → Open Anyway.

Updated July 29, 2026 at 12:53 UTC

Changes

  • A roll now carries the shooting record. Camera, lens, film, ISO, shutter, aperture and focal length are written once on the roll and applied to its frames, filling only the fields a frame leaves empty, so a lens swapped in the middle of a roll stays as that frame records it. The roll also carries the code written on the negative sleeve and a note of its own.
  • The camera, lens and film written by hand are searched with the same standing as the EXIF of an imported file. A film camera writes no EXIF at all, so what is written down is that frame's camera, and a frame that carries a record no longer reports its camera and lens as unknown.
  • Exported file names can use the roll code, the film and the camera, so a file carries the same code as the sleeve it came from. Quick export gains a long-edge size next to the folder it already had.
  • The film base is measured as a ratio of the pixel's own level. The test for a candidate compared channels with fixed differences — R−B of at least 0.06 for an orange mask, a spread within ±0.08 for a neutral one — while the samples are read in linear light, where dye transmission is multiplicative. A scan that lands low in the value domain, which is what a scanner raw at gamma 1.0 is, lost every candidate below roughly 0.30 in sRGB terms, and the develop fell back to a constant base: the inversion came out wrong rather than merely uncertain. The same scan now holds down to 0.03. A candidate must also reach a tenth of that scan's own base level, so an orange scene, which keeps the mask ratio at any density, cannot pass as film base.
  • An original that iCloud Drive has taken back off the disk is downloaded before the export starts, and the number still on the way is reported while it runs. Opening such a file blocks the thread until the download finishes, so an export used to look frozen on one frame for tens of seconds with nothing on screen to explain it. An export that cannot get its originals now stops with that reason instead of stalling.
  • An export no longer decodes the same cleaned raw twice. Confirming that the cached cleaned raw was usable read the whole TIFF and threw the result away, so an export that waited for that check then decoded the same file again from the start.
  • Export verification has a standard and a strict level. Both write the real SHA-256 into the journal, so crash recovery and rollback are decided exactly as before; what changes is how many times the same file is hashed again inside one successful export. Standard fixes the generation with the first hash and rechecks with the stat identity, falling back to a full hash the moment anything about the file differs. Strict rehashes at every checkpoint, which is what every export did up to 1.0.2.
  • A frame proposed on a flatbed preview follows the way the film lies on the glass. Format dimensions are written for a strip lying across, so on a bed taller than it is wide every proposed frame came out rotated by ninety degrees and had to be redrawn by hand. The frame now advances along the long axis of the scan area, a frame added after the first one copies its size and direction and lands in the next slot two millimetres on, and the size is measured against the area the preview actually scanned rather than against the whole bed.
  • A frame drawn or resized by hand snaps to the aspect of the selected film format, measured in millimetres rather than screen pixels, because nothing on screen tells you whether a rectangle is 6×7. The orientation follows the shape being drawn, dragging one edge drives the other axis around the unchanged centre, and holding Option draws freely for a format the list does not carry. Adding and removing a frame are in the Scanner menu with shortcuts.
  • The divider of a before/after comparison is dragged. Left/right and top/bottom each keep their own position as a fraction of the image, so zooming or resizing the window does not move it, and VoiceOver moves the line in steps. The line follows the hand from wherever it was taken hold of instead of snapping under the pointer, a click that does not move leaves it where it is, and the resize cursor is now an AppKit cursor rect — it can no longer stay on screen after the pointer has left the line, which read as the app having stopped responding to clicks.
  • Two-finger scrolling pans the canvas. Dragging inside the canvas belongs to the tools — drawing a scan frame, cropping, brushing — so with a tool on there was no way left to move a zoomed image.
  • The scan progress card is an opaque card instead of glass. What it reports has to stay readable over any photograph.

Verified

  • Full strict-concurrency suite passes: 1,720 tests, 17 conditionally skipped. The GitHub CI quality gate passes with it: contracts, provenance, boundary checks and the GUI test build
  • The GUI end-to-end suite passes on CI. An export commit journal used to be written outside the temporary root a GUI test owns, so an export cut short by one test blocked the library of the next launch with the recovery screen; the journal now lives inside that root, and the run is green again
  • The film base measurement is covered by tests across the exposure range: an orange mask, a neutral base and the weak-strip fallback, each measured on synthetic negatives down to where the estimate is expected to give up
  • The flatbed frame placement and the aspect lock are covered by unit tests that measure in millimetres: the long axis, the next slot, the row wrap at the end of a strip, sizing against the preview area, and the snap with its anchors
  • The roll record is covered by tests: filling only empty fields, a frame joining a roll, a catalog round trip, the search by camera, lens and film, and the roll code in a file name
  • Both export verification levels are covered by tests, including a source replaced before the commit, an in-place rewrite of the same length, and the fall back to a full hash when the stat identity differs
  • The iCloud path is covered by tests for eviction detection, deduplication and progress
  • arm64 and Universal ZIP, DMG, PKG and dSYM release builds pass
  • Local SHA-256 verification of all 10 release assets passes
  • The divider drag and scroll panning were not exercised by hand in a running app; they are interaction changes without automated coverage
  • Real scanner optical, motor and USB behavior still requires device QA

한국어

English · 한국어 · 日本語 · 简体中文 · Français · Deutsch

다운로드

  • 대부분의 Mac: negaflow-1.0.3-1-macOS-universal.pkg
  • Apple Silicon 전용: negaflow-1.0.3-1-macOS-arm64.pkg
  • 수동 설치용 ZIP과 DMG도 함께 제공합니다.

중요: 서명 및 공증 상태

이 배포 파일은 ad-hoc 서명되었으며 Apple 공증을 받지 않았습니다. macOS가 최초 실행을 차단할 수 있습니다. 다운로드한 파일을 함께 제공된 SHA256SUMS와 대조한 뒤 한 번 열기를 시도하고, 시스템 설정 → 개인정보 보호 및 보안 → 그래도 열기에서 직접 허용하십시오.

2026년 7월 29일 21:53 KST 갱신

변경 사항

  • 촬영 기록을 롤에 적습니다. 카메라, 렌즈, 필름, ISO, 셔터, 조리개, 초점 거리를 롤에 한 번 적고 그 롤의 프레임에 적용하면 프레임이 비워 둔 칸만 채웁니다. 롤 중간에 렌즈를 바꿔 적어 둔 프레임은 적힌 그대로 남습니다. 롤에는 네거티브 봉투에 적는 코드와 메모도 함께 둡니다.
  • 손으로 적은 카메라·렌즈·필름은 가져온 파일의 EXIF와 같은 자격으로 검색됩니다. 필름 카메라는 EXIF를 남기지 않으므로 적어 둔 값이 곧 그 프레임의 카메라이며, 기록이 있는 프레임은 카메라·렌즈를 더 이상 미상으로 보고하지 않습니다.
  • 내보내는 파일 이름에 롤 코드, 필름, 카메라를 쓸 수 있습니다. 봉투에 적은 코드가 파일 이름에 그대로 남습니다. 빠른 내보내기에는 기존 폴더 설정 옆에 긴 변 크기가 생겼습니다.
  • 필름 베이스를 그 픽셀 자신의 밝기에 대한 비율로 잽니다. 후보 판정은 채널 차이를 고정값으로 비교했습니다 — 오렌지 마스크는 R−B 0.06 이상, 무채색 베이스는 채널 폭 ±0.08 이내 — 그런데 표본은 선형 광에서 읽고, 색소 투과는 곱셈입니다. 값 영역에서 낮게 내려앉는 스캔, 즉 감마 1.0의 스캐너 raw가 그러한데, sRGB로 0.30 언저리 아래에서는 후보가 하나도 남지 않았고 현상은 상수 베이스로 물러났습니다 — 반전이 불확실해지는 게 아니라 틀리게 나왔습니다. 같은 스캔이 이제 0.03까지 버팁니다. 후보는 그 스캔 자신의 베이스 밝기의 10분의 1도 넘어야 하므로, 밀도와 무관하게 마스크 비율을 유지하는 오렌지 장면이 필름 베이스로 통과하지 못합니다.
  • iCloud Drive가 로컬에서 내려 둔 원본은 내보내기를 시작하기 전에 먼저 받아두고, 진행 중에는 남은 개수를 표시합니다. 그런 파일은 여는 순간 다운로드가 끝날 때까지 스레드가 막혀, 지금까지는 특정 프레임에서 아무 설명 없이 수십 초 멈춘 것처럼 보였습니다. 원본을 받지 못하면 그 이유와 함께 중단합니다.
  • 내보내기가 같은 cleaned raw를 두 번 디코드하지 않습니다. 캐시된 cleaned raw가 쓸 수 있는지 확인하면서 TIFF 전체를 읽고는 결과를 버렸기 때문에, 그 확인을 기다린 내보내기가 같은 파일을 처음부터 다시 디코드했습니다.
  • 내보내기 검증에 표준과 엄격 두 수준이 생겼습니다. 두 수준 모두 저널에는 실제 SHA-256을 기록하므로 크래시 복구와 롤백 판정은 전과 같습니다. 달라지는 것은 한 번의 성공적인 내보내기 안에서 같은 파일을 몇 번 다시 해시하느냐뿐입니다. 표준은 최초 해시로 세대를 고정하고 이후에는 stat identity로 재확인하며, 하나라도 다르면 그 자리에서 전체 해시로 되돌아가 판정합니다. 엄격은 모든 확인 지점에서 전체 바이트를 다시 해시합니다 — 1.0.2까지의 동작입니다.
  • 평판 프리뷰에서 제안하는 프레임이 유리면에 놓인 필름 방향을 따릅니다. 규격 치수는 스트립을 가로로 놓았을 때 기준이라, 세로로 긴 유리면에서는 제안된 프레임이 항상 90° 틀어져 직접 그려야 했습니다. 이제 프레임은 스캔 영역의 긴 축을 따라 진행하고, 첫 프레임 다음에 추가하는 프레임은 그 크기와 방향을 이어받아 2mm 간격으로 다음 칸에 놓이며, 크기는 전체 유리면이 아니라 프리뷰로 실제 훑은 영역을 기준으로 계산합니다.
  • 손으로 그리거나 크기를 조정한 프레임은 선택한 필름 규격의 비율로 맞춰집니다. 화면 픽셀이 아니라 밀리미터로 따집니다 — 화면만 봐서는 그 사각형이 6×7인지 알 수 없기 때문입니다. 방향은 그리는 형태를 따르고, 한 변을 끌면 반대 축이 중심을 지키며 따라오며, ⌥를 누르고 그리면 목록에 없는 규격을 위해 자유 비율로 그립니다. 프레임 추가와 제거는 스캐너 메뉴에 단축키와 함께 있습니다.
  • 원본/현상본 비교의 분할선을 끌어서 옮깁니다. 좌/우와 상/하가 각자의 위치를 이미지 기준 비율로 기억하므로 확대하거나 창 크기를 바꿔도 그대로이고, VoiceOver에서는 단계적으로 움직입니다. 선은 포인터 밑으로 튀지 않고 잡은 지점 그대로 손을 따라오며, 움직이지 않은 클릭은 선을 그 자리에 둡니다. 리사이즈 커서는 AppKit의 cursor rect가 되어, 포인터가 선을 벗어난 뒤에도 화면에 남아 앱이 클릭을 받지 않는 것처럼 보이는 일이 없습니다.
  • 두 손가락 스크롤로 캔버스를 이동합니다. 캔버스 안의 드래그는 프레임 그리기·크롭·브러시 같은 도구가 쓰기 때문에, 도구를 켜면 확대한 이미지를 옮길 방법이 없었습니다.
  • 스캔 진행률 카드는 유리 대신 불투명한 카드입니다. 거기 적히는 내용은 어떤 사진 위에서도 읽혀야 합니다.

검증

  • 전체 strict-concurrency 스위트 통과: 1,720개, 조건부 건너뜀 17개. 같은 내용의 GitHub CI 품질 게이트도 통과: 계약·프로비넌스·경계 검사와 GUI 테스트 빌드
  • GUI end-to-end 스위트 CI 통과. 내보내기 커밋 저널이 GUI 테스트가 소유한 임시 루트 밖에 적혀, 한 테스트가 끊은 내보내기가 다음 실행의 라이브러리를 복구 화면으로 막았습니다. 저널을 그 루트 안으로 옮겨 다시 통과합니다.
  • 필름 베이스 측정은 노출 범위 전반을 테스트로 확인: 오렌지 마스크, 무채색 베이스, 약한 스트립 폴백을 각각 합성 네거티브에서 추정이 포기해야 하는 지점까지 측정
  • 평판 프레임 배치와 비율 고정은 밀리미터로 재는 단위 테스트로 확인: 긴 축, 다음 칸, 스트립 끝의 줄바꿈, 프리뷰 영역 기준 크기, 스냅과 앵커
  • 롤 기록은 테스트로 확인: 빈 칸만 채우기, 롤에 새로 들어온 프레임, 카탈로그 왕복, 카메라·렌즈·필름 검색, 파일 이름의 롤 코드
  • 내보내기 검증 두 수준 모두 테스트로 확인: 커밋 전에 바뀐 원본, 길이가 같은 제자리 덮어쓰기, stat identity가 다를 때 전체 해시로 되돌아가는 판정
  • iCloud 경로는 축출 감지, 중복 제거, 진행률을 테스트로 확인
  • arm64 및 Universal ZIP, DMG, PKG, dSYM 릴리즈 빌드 통과
  • 릴리즈 자산 10개의 로컬 SHA-256 검증 통과
  • 분할선 드래그와 스크롤 이동은 실행 중인 앱에서 손으로 확인하지 않았습니다. 자동 검사가 없는 상호작용 변경입니다.
  • 실제 스캐너의 광학·모터·USB 동작은 실기 QA가 필요합니다.

日本語

English · 한국어 · 日本語 · 简体中文 · Français · Deutsch

ダウンロード

  • ほとんどのMac: negaflow-1.0.3-1-macOS-universal.pkg
  • Apple Silicon専用: negaflow-1.0.3-1-macOS-arm64.pkg
  • 手動インストール用のZIPとDMGも提供します。

重要:署名と公証の状態

これらの成果物はad-hoc署名で、Appleの公証を受けていません。初回起動が止められた場合は、SHA256SUMSでダウンロードを確認し、一度開いてからシステム設定 → プライバシーとセキュリティ → このまま開くで許可してください。

2026年7月29日 21:53 JST 更新

変更点

  • 撮影記録をロールに書けます。カメラ、レンズ、フィルム、ISO、シャッター、絞り、焦点距離をロールに一度書いて適用すると、コマが空けている欄だけが埋まります。ロールの途中でレンズを替えて書いたコマは、そのコマの記録のまま残ります。ロールにはネガの袋に書くコードとメモも持たせます。
  • 手で書いたカメラ・レンズ・フィルムは、取り込んだファイルのEXIFと同じ資格で検索されます。フィルムカメラはEXIFを残さないので、書き留めた値がそのコマのカメラです。記録があるコマは、カメラとレンズを不明として報告しなくなりました。
  • 書き出すファイル名にロールコード、フィルム、カメラを使えます。袋に書いたコードがそのままファイル名に残ります。クイック書き出しには、これまでのフォルダー設定の隣に長辺サイズが加わりました。
  • フィルムベースを、その画素自身の明るさに対する比で測ります。候補の判定はチャンネル差を固定値で比べていました——オレンジマスクはR−Bが0.06以上、無彩色ベースはチャンネル幅が±0.08以内——しかし標本は線形光で読み、色素の透過は乗算です。値域の低いところに収まるスキャン、つまりガンマ1.0のスキャナーrawがそうですが、sRGBで0.30あたりを下回ると候補が一つも残らず、現像は定数ベースに後退しました——反転が不確かになるのではなく、誤って出ていました。同じスキャンが今は0.03まで持ちます。候補はそのスキャン自身のベース明度の10分の1も超える必要があるため、濃度によらずマスク比を保つオレンジの場面がフィルムベースとして通ることはありません。
  • iCloud Driveがローカルから取り下げた原本は、書き出しを始める前にまとめて取得し、実行中は残りの数を表示します。そうしたファイルは開いた瞬間にダウンロードが終わるまでスレッドを止めるため、これまでは特定のコマで何の説明もなく数十秒固まったように見えていました。原本を取得できない場合は、その理由とともに中止します。
  • 書き出しが同じcleaned rawを二度デコードしなくなりました。キャッシュされたcleaned rawが使えるかの確認でTIFF全体を読んだうえで結果を捨てていたため、その確認を待った書き出しが同じファイルを最初からもう一度デコードしていました。
  • 書き出し検証に標準と厳格の二段階が加わりました。どちらも実際のSHA-256をジャーナルに記録するので、クラッシュ復旧とロールバックの判定はこれまでと同じです。変わるのは、一度の成功した書き出しの中で同じファイルを何度ハッシュし直すかだけです。標準は最初のハッシュで世代を固定し、以降はstat identityで再確認し、少しでも違えばその場で全体ハッシュに戻して判定します。厳格はすべての確認地点で全バイトを再ハッシュします——1.0.2までの動作です。
  • フラットベッドのプレビューで提案されるコマが、ガラス面に置かれたフィルムの向きに従います。規格の寸法はストリップを横に置いた場合の値なので、縦に長いガラス面では提案されるコマが常に90°ずれ、手で描き直す必要がありました。これからはスキャン領域の長い軸に沿ってコマが進み、最初のコマの次に追加するコマはその大きさと向きを引き継いで2mm間隔で次の位置に置かれ、大きさはガラス面全体ではなくプレビューが実際に読み取った領域を基準に決まります。
  • 手で描いたコマやサイズを変えたコマは、選んだフィルム規格の比率に合わせられます。画面のピクセルではなくミリメートルで判断します——画面を見ただけでは、その四角が6×7かどうか分からないからです。向きは描いている形に従い、一辺を引くと反対の軸が中心を保ったまま追従し、⌥を押しながら描けば一覧にない規格のために自由な比率で描けます。コマの追加と削除はスキャナーメニューにショートカット付きで並びます。
  • 元画像と現像結果を比べる分割線をドラッグして動かせます。左右と上下がそれぞれの位置を画像基準の比率で覚えるので、拡大しても、ウインドウの大きさを変えても動きません。VoiceOverでは段階的に動かせます。線はポインターの下へ飛ばず、つかんだ位置のまま手に追従し、動かないクリックは線をその場に残します。リサイズカーソルはAppKitのcursor rectになり、ポインターが線を離れたあとも画面に残ってクリックを受け付けないように見えることはなくなりました。
  • 二本指のスクロールでキャンバスを移動します。キャンバス内のドラッグはコマの作成、切り抜き、ブラシといったツールが使うため、ツールを有効にすると拡大した画像を動かす方法がありませんでした。
  • スキャン進行状況のカードはガラスではなく不透明なカードになりました。そこに出る内容は、どんな写真の上でも読めなければなりません。

検証

  • strict-concurrency全スイート成功:1,720件、条件付きスキップ17件。同じ内容のGitHub CI品質ゲートも成功:契約・来歴・境界の検査とGUIテストビルド
  • GUIのend-to-endスイートがCIで成功。書き出しのコミットジャーナルがGUIテストの持つ一時ルートの外に書かれていたため、あるテストが打ち切った書き出しが次の起動のライブラリを復旧画面で止めていました。ジャーナルをそのルート内に移し、再び通ります。
  • フィルムベースの測定は露出域全体を単体テストで確認:オレンジマスク、無彩色ベース、弱いストリップの代替経路を、それぞれ合成ネガで推定が諦めるべき点まで測定
  • フラットベッドのコマ配置と比率固定は、ミリメートルで測る単体テストで確認:長い軸、次の位置、ストリップ終端での折り返し、プレビュー領域基準の大きさ、スナップとアンカー
  • ロール記録は単体テストで確認:空欄だけを埋めること、ロールに加わったコマ、カタログの往復、カメラ・レンズ・フィルムでの検索、ファイル名のロールコード
  • 書き出し検証は二段階とも単体テストで確認:コミット前に差し替えられた原本、同じ長さの上書き、stat identityが異なるときに全体ハッシュへ戻る判定
  • iCloud経路は取り下げ検出、重複除去、進行状況を単体テストで確認
  • arm64とUniversalのZIP、DMG、PKG、dSYMのリリースビルド成功
  • リリース資産10個のローカルSHA-256検証成功
  • 分割線のドラッグとスクロール移動は、実行中のアプリで手作業では確認していません。自動検査のない操作の変更です。
  • 実機の光学・モーター・USB動作は実機QAが必要です。

简体中文

English · 한국어 · 日本語 · 简体中文 · Français · Deutsch

下载

  • 大多数 Mac:negaflow-1.0.3-1-macOS-universal.pkg
  • 仅 Apple Silicon:negaflow-1.0.3-1-macOS-arm64.pkg
  • 同时提供用于手动安装的 ZIP 与 DMG。

重要:签名与公证状态

这些文件仅为 ad-hoc 签名,未经过 Apple 公证。若 macOS 阻止首次启动,请先用随附的 SHA256SUMS 校验下载文件,尝试打开一次,再到系统设置 → 隐私与安全性 → 仍要打开手动放行。

2026年7月29日 20:53 CST 更新

变更

  • 拍摄信息可以记在胶卷上。把相机、镜头、胶片、ISO、快门、光圈与焦距在胶卷上写一次并应用,只会填补画幅留空的字段;在一卷中途换过镜头而单独写过的画幅,仍保留它自己的记录。胶卷还带有写在负片袋上的编号和一段备注。
  • 手写的相机、镜头与胶片,与导入文件的 EXIF 拥有同等的检索资格。胶片相机根本不写 EXIF,所以写下来的就是那一张的相机;带有记录的画幅不再把相机与镜头报告为未知。
  • 导出文件名可以使用胶卷编号、胶片与相机,让文件带上与负片袋相同的编号。快速导出在原有的文件夹设置旁增加了长边尺寸。
  • 片基以像素自身亮度的比例来测量。此前判断候选点用的是固定的通道差值——橙色片基要求 R−B 不小于 0.06,中性片基要求通道跨度在 ±0.08 以内——但采样是在线性光下读取的,而染料透射是乘性的。落在数值域低处的扫描,也就是伽马 1.0 的扫描仪 raw,在 sRGB 约 0.30 以下就一个候选点都不剩,显影只能退回常数片基:反转不是变得不确定,而是直接算错。同一份扫描现在可以撑到 0.03。候选点还必须达到该扫描自身片基亮度的十分之一,因此在任何密度下都保持橙色比例的橙色场景,不会被当作片基。
  • 被 iCloud Drive 从本地移除的原始文件,会在导出开始前先行取回,并在过程中显示仍在下载的数量。这类文件一旦打开就会阻塞线程直到下载完成,因此过去导出会在某一张上毫无提示地卡住几十秒。若无法取回原始文件,导出会带着原因停止,而不是一直等待。
  • 导出不再对同一份 cleaned raw 解码两次。此前确认缓存的 cleaned raw 是否可用时会读完整个 TIFF 再丢弃结果,于是等待该确认的导出又从头解码了同一个文件。
  • 导出校验分为标准与严格两级。两级都会把真实的 SHA-256 写入日志,因此崩溃恢复与回滚的判定与以往完全相同;变化的只是一次成功导出中同一个文件被重新哈希的次数。标准级以首次哈希固定版本,之后用 stat identity 复核,一旦有任何差异立即回退到完整哈希再判定。严格级在每个检查点重新哈希全部字节——这正是 1.0.2 之前的做法。
  • 平板预览中给出的画幅,会顺着胶片在玻璃上的摆放方向。规格尺寸是以胶卷横放为准写的,所以在纵向更长的玻璃面上,给出的画幅总是偏转 90°,只能手动重画。现在画幅沿扫描区域的长轴推进,在第一格之后添加的画幅会沿用它的尺寸与方向、间隔 2 毫米落在下一格,尺寸也以预览实际扫过的区域为准,而不是整块玻璃。
  • 手动绘制或调整大小的画幅会吸附到所选胶片规格的比例,并以毫米而非屏幕像素来计算——因为光看屏幕无法判断一个矩形是不是 6×7。方向跟随正在绘制的形状,拖动一条边时另一轴围绕不变的中心跟随,按住 ⌥ 则可为列表之外的规格自由绘制。添加与删除画幅位于扫描仪菜单中,并配有快捷键。
  • 原图与显影结果对比的分割线可以拖动。左右与上下各自以图像比例记住自己的位置,因此缩放或改变窗口大小都不会移动它;VoiceOver 可按步长移动该线。分割线不会跳到指针下方,而是从抓住的位置跟随手移动;没有移动的点击会让它留在原处。缩放光标改用 AppKit 的 cursor rect,指针离开分割线后不会继续留在屏幕上,也就不会让人以为应用不再响应点击。
  • 双指滚动即可平移画布。画布内的拖动属于工具——绘制画幅、裁剪、笔刷——因此启用工具后就没有别的方式移动放大的图像了。
  • 扫描进度卡片改为不透明卡片,不再使用玻璃效果。上面的内容必须在任何照片之上都清晰可读。

验证

  • strict-concurrency 全套测试通过:1,720 项,条件跳过 17 项。内容相同的 GitHub CI 质量门禁同样通过:契约、来源、边界检查与 GUI 测试构建
  • GUI 端到端测试在 CI 上通过。导出提交日志此前写在 GUI 测试所拥有的临时根目录之外,因此一次被中断的导出会让下次启动的图库停在恢复界面;日志改为写在该根目录内后,测试重新通过。
  • 片基测量在整个曝光范围内由单元测试覆盖:橙色片基、中性片基与弱片基回退路径,均在合成负片上测到估计应当放弃的位置
  • 平板画幅的摆放与比例锁定由以毫米度量的单元测试覆盖:长轴、下一格、条带末端换行、以预览区域为准的尺寸、吸附与锚点
  • 胶卷记录由单元测试覆盖:只填补空白字段、新加入胶卷的画幅、目录往返、按相机与镜头与胶片检索、文件名中的胶卷编号
  • 两级导出校验均由单元测试覆盖:提交前被替换的原始文件、等长的原地覆写、stat identity 不一致时回退到完整哈希
  • iCloud 路径由单元测试覆盖:移除检测、去重与进度
  • arm64 与 Universal 的 ZIP、DMG、PKG、dSYM 发布构建通过
  • 10 个发布文件的本地 SHA-256 校验通过
  • 分割线拖动与滚动平移未在运行中的应用里手动实测;它们是没有自动化覆盖的交互改动。
  • 真实扫描仪的光学、马达与 USB 行为仍需实机 QA。

Français

English · 한국어 · 日本語 · 简体中文 · Français · Deutsch

Téléchargements

  • La plupart des Mac : negaflow-1.0.3-1-macOS-universal.pkg
  • Apple Silicon uniquement : negaflow-1.0.3-1-macOS-arm64.pkg
  • Des fichiers ZIP et DMG sont également fournis pour l’installation manuelle.

Important : signature et notarisation

Ces fichiers sont signés en ad-hoc et ne sont pas notarisés par Apple. Si macOS bloque le premier lancement, vérifiez le téléchargement avec le fichier SHA256SUMS, tentez de l’ouvrir une fois, puis autorisez-le dans Réglages Système → Confidentialité et sécurité → Ouvrir quand même.

Mis à jour le 29 juillet 2026 à 14:53 CEST

Modifications

  • Le rouleau porte désormais les notes de prise de vue. Appareil, objectif, film, ISO, vitesse, ouverture et focale s’écrivent une fois sur le rouleau puis s’appliquent à ses vues, en ne remplissant que les champs qu’une vue laisse vides : un objectif changé en cours de rouleau reste tel que la vue l’indique. Le rouleau porte aussi le code inscrit sur la pochette du négatif et une note.
  • L’appareil, l’objectif et le film saisis à la main sont recherchés au même titre que l’EXIF d’un fichier importé. Un appareil argentique n’écrit aucun EXIF : ce qui est noté est l’appareil de cette vue, et une vue qui porte une note ne déclare plus son appareil et son objectif comme inconnus.
  • Les noms de fichiers exportés peuvent utiliser le code du rouleau, le film et l’appareil, afin qu’un fichier porte le même code que la pochette dont il vient. L’export rapide gagne une taille de bord long, à côté du dossier qu’il avait déjà.
  • La base du film se mesure en proportion du niveau du pixel lui-même. Le test d’un candidat comparait les canaux avec des écarts fixes — R−B d’au moins 0,06 pour un masque orangé, une dispersion dans ±0,08 pour une base neutre — alors que les échantillons sont lus en lumière linéaire, où la transmission des colorants est multiplicative. Une numérisation qui se place bas dans le domaine des valeurs, ce qu’est un raw de scanner en gamma 1,0, perdait tout candidat en dessous d’environ 0,30 en sRGB, et le développement retombait sur une base constante : l’inversion sortait fausse plutôt qu’incertaine. La même numérisation tient maintenant jusqu’à 0,03. Un candidat doit en outre atteindre un dixième du niveau de base propre à cette numérisation, si bien qu’une scène orangée, qui conserve le rapport du masque à n’importe quelle densité, ne peut pas passer pour la base du film.
  • Un original qu’iCloud Drive a retiré du disque est rapatrié avant le début de l’export, et le nombre restant est indiqué pendant l’opération. Ouvrir un tel fichier bloque le fil d’exécution jusqu’à la fin du téléchargement : un export semblait donc figé sur une vue pendant des dizaines de secondes sans rien à l’écran pour l’expliquer. Un export qui ne peut pas obtenir ses originaux s’arrête maintenant en le disant, au lieu de s’enliser.
  • Un export ne décode plus deux fois le même raw nettoyé. Vérifier que le raw nettoyé en cache était utilisable lisait tout le TIFF puis jetait le résultat : l’export qui avait attendu cette vérification décodait ensuite le même fichier depuis le début.
  • La vérification d’export a deux niveaux, standard et stricte. Les deux inscrivent le vrai SHA-256 dans le journal : la reprise après incident et le rollback se décident donc exactement comme avant ; ce qui change est le nombre de fois qu’un même fichier est ré-haché à l’intérieur d’un export réussi. Le niveau standard fixe la génération au premier hachage et revérifie par l’identité stat, en revenant au hachage complet dès que quelque chose diffère. Le niveau strict ré-hache à chaque point de contrôle, ce que faisait tout export jusqu’à la 1.0.2.
  • Une vue proposée sur un aperçu à plat suit la façon dont le film repose sur la vitre. Les dimensions d’un format sont écrites pour une bande posée en travers : sur une vitre plus haute que large, chaque vue proposée sortait pivotée de quatre-vingt-dix degrés et devait être redessinée. La vue progresse maintenant le long du grand axe de la zone de numérisation, une vue ajoutée après la première reprend sa taille et sa direction et se place dans l’emplacement suivant à deux millimètres, et la taille est mesurée sur la zone réellement balayée par l’aperçu plutôt que sur la vitre entière.
  • Une vue dessinée ou redimensionnée à la main s’aligne sur le rapport du format de film choisi, mesuré en millimètres et non en pixels d’écran, puisque rien à l’écran ne dit si un rectangle fait 6×7. L’orientation suit la forme dessinée, tirer un bord entraîne l’autre axe autour du centre inchangé, et maintenir ⌥ dessine librement pour un format absent de la liste. Ajouter et retirer une vue figurent dans le menu Scanner, avec des raccourcis.
  • La ligne de séparation d’une comparaison avant/après se déplace à la souris. Gauche/droite et haut/bas conservent chacune leur position en fraction de l’image : zoomer ou redimensionner la fenêtre ne la déplace pas, et VoiceOver la déplace par paliers. La ligne suit la main depuis l’endroit où elle a été saisie au lieu de sauter sous le pointeur, un clic sans déplacement la laisse en place, et le curseur de redimensionnement est désormais un cursor rect AppKit : il ne peut plus rester à l’écran une fois le pointeur parti, ce qui donnait l’impression que l’application ne répondait plus aux clics.
  • Le défilement à deux doigts déplace le canevas. Le glissement dans le canevas appartient aux outils — dessiner une vue, recadrer, retoucher au pinceau —, si bien qu’un outil actif ne laissait plus aucun moyen de déplacer une image agrandie.
  • La carte de progression de numérisation est une carte opaque, et non plus du verre. Ce qu’elle indique doit rester lisible par-dessus n’importe quelle photographie.

Vérification

  • Suite strict-concurrency complète réussie : 1 720 tests, 17 ignorés sous condition. La même barrière qualité passe sur la CI GitHub : contrats, provenance, contrôles de frontière et build des tests d’interface
  • La suite d’interface de bout en bout passe sur la CI. Le journal de validation d’export s’écrivait hors du dossier temporaire que possède un test d’interface : un export interrompu par un test bloquait donc la photothèque du lancement suivant sur l’écran de récupération. Le journal vit maintenant dans ce dossier et la série repasse au vert.
  • La mesure de la base du film est couverte par des tests sur toute la plage d’exposition : masque orangé, base neutre et repli sur bande faible, mesurés sur des négatifs de synthèse jusqu’au point où l’estimation doit renoncer
  • Le placement de la vue à plat et le verrouillage du rapport sont couverts par des tests unitaires qui mesurent en millimètres : le grand axe, l’emplacement suivant, le passage à la bande suivante, la taille rapportée à la zone de l’aperçu, l’alignement et ses ancrages
  • La fiche de pellicule est couverte par des tests : ne remplir que les champs vides, une vue rejoignant une pellicule, un aller-retour dans le catalogue, la recherche par appareil, objectif et film, et le code de pellicule dans un nom de fichier
  • Les deux niveaux de vérification d’export sont couverts par des tests : un original remplacé avant la validation, une réécriture sur place de même longueur, et le retour au hachage complet quand l’identité stat diffère
  • Le chemin iCloud est couvert par des tests : détection de l’éviction, déduplication et progression
  • Builds de publication ZIP, DMG, PKG et dSYM arm64 et Universal réussis
  • Vérification SHA-256 locale réussie pour les 10 fichiers
  • Le glissement de la ligne de comparaison et le défilement n’ont pas été essayés à la main dans l’application en fonctionnement ; ce sont des changements d’interaction sans couverture automatique.
  • Le comportement optique, moteur et USB exige encore une QA sur appareils réels.

Deutsch

English · 한국어 · 日本語 · 简体中文 · Français · Deutsch

Downloads

  • Die meisten Macs: negaflow-1.0.3-1-macOS-universal.pkg
  • Nur Apple Silicon: negaflow-1.0.3-1-macOS-arm64.pkg
  • ZIP und DMG für die manuelle Installation sind ebenfalls enthalten.

Wichtig: Signatur und Notarisierung

Diese Dateien sind ad-hoc signiert und nicht von Apple notarisiert. Falls macOS den ersten Start blockiert, prüfen Sie den Download mit SHA256SUMS, versuchen Sie ihn einmal zu öffnen und erlauben Sie ihn unter Systemeinstellungen → Datenschutz & Sicherheit → Trotzdem öffnen.

Aktualisiert am 29. Juli 2026 um 14:53 MESZ

Änderungen

  • Die Aufnahmedaten stehen jetzt an der Rolle. Kamera, Objektiv, Film, ISO, Verschluss, Blende und Brennweite werden einmal an der Rolle notiert und auf ihre Bilder angewendet; gefüllt werden nur die Felder, die ein Bild leer lässt. Ein mitten in der Rolle gewechseltes Objektiv bleibt so, wie das Bild es festhält. Die Rolle trägt außerdem den Code von der Negativhülle und eine eigene Notiz.
  • Von Hand notierte Kamera, Objektiv und Film werden mit demselben Rang durchsucht wie die EXIF einer importierten Datei. Eine Filmkamera schreibt überhaupt keine EXIF — was notiert ist, ist die Kamera dieses Bildes, und ein Bild mit Notiz meldet Kamera und Objektiv nicht länger als unbekannt.
  • Exportierte Dateinamen können den Rollencode, den Film und die Kamera verwenden, damit eine Datei denselben Code trägt wie die Hülle, aus der sie stammt. Der Schnellexport erhält neben dem bisherigen Ordner eine Größe für die lange Kante.
  • Die Filmbasis wird als Verhältnis zum eigenen Pegel des Pixels gemessen. Die Prüfung eines Kandidaten verglich die Kanäle mit festen Differenzen — R−B von mindestens 0,06 für eine orange Maske, eine Spanne innerhalb ±0,08 für eine neutrale — während die Proben in linearem Licht gelesen werden, wo die Farbstoffdurchlässigkeit multiplikativ ist. Ein Scan, der tief im Wertebereich landet, und genau das ist ein Scanner-Raw bei Gamma 1,0, verlor unterhalb von etwa 0,30 in sRGB jeden Kandidaten, und die Entwicklung fiel auf eine konstante Basis zurück: die Umkehrung kam falsch heraus, nicht bloß unsicher. Derselbe Scan hält jetzt bis 0,03. Ein Kandidat muss außerdem ein Zehntel des Basispegels dieses Scans erreichen, sodass eine orange Szene, die das Maskenverhältnis bei jeder Dichte behält, nicht als Filmbasis durchgeht.
  • Ein Original, das iCloud Drive von der Platte genommen hat, wird vor dem Start des Exports geholt, und währenddessen wird gemeldet, wie viele noch unterwegs sind. Das Öffnen einer solchen Datei blockiert den Thread bis zum Ende des Downloads, weshalb ein Export bisher an einem Bild zig Sekunden lang eingefroren wirkte, ohne dass etwas es erklärte. Ein Export, der seine Originale nicht bekommt, hält nun mit genau dieser Begründung an, statt hängen zu bleiben.
  • Ein Export decodiert dasselbe bereinigte Raw nicht mehr zweimal. Die Prüfung, ob das zwischengespeicherte bereinigte Raw brauchbar ist, las das ganze TIFF und warf das Ergebnis weg, sodass ein Export, der auf diese Prüfung gewartet hatte, dieselbe Datei anschließend von vorn decodierte.
  • Die Exportprüfung hat eine Stufe Standard und eine Stufe Streng. Beide schreiben die echte SHA-256 ins Journal, Absturzwiederherstellung und Rollback werden also genau wie bisher entschieden; anders ist nur, wie oft dieselbe Datei innerhalb eines erfolgreichen Exports erneut gehasht wird. Standard fixiert die Generation mit dem ersten Hash und prüft danach über die stat-Identität nach, mit sofortigem Rückfall auf den vollen Hash, sobald etwas abweicht. Streng hasht an jedem Prüfpunkt alle Bytes neu — das taten bis 1.0.2 alle Exporte.
  • Ein in der Flachbett-Vorschau vorgeschlagenes Bild folgt der Lage des Films auf dem Glas. Die Maße eines Formats sind für einen quer liegenden Streifen notiert, weshalb auf einer Glasfläche, die höher als breit ist, jedes vorgeschlagene Bild um neunzig Grad gedreht herauskam und neu gezeichnet werden musste. Das Bild rückt jetzt entlang der langen Achse des Scanbereichs vor, ein nach dem ersten hinzugefügtes Bild übernimmt dessen Größe und Richtung und landet zwei Millimeter weiter im nächsten Platz, und die Größe misst sich an der Fläche, die die Vorschau tatsächlich erfasst hat, nicht am gesamten Glas.
  • Ein von Hand gezeichnetes oder verändertes Bild rastet auf das Seitenverhältnis des gewählten Filmformats ein, gemessen in Millimetern statt in Bildschirmpunkten — am Bildschirm sieht man einem Rechteck nicht an, ob es 6×7 ist. Die Ausrichtung folgt der gezeichneten Form, das Ziehen einer Kante führt die andere Achse um die unveränderte Mitte, und mit gehaltener ⌥ wird für ein Format außerhalb der Liste frei gezeichnet. Bild hinzufügen und entfernen stehen mit Kurzbefehlen im Menü Scanner.
  • Die Trennlinie eines Vorher/Nachher-Vergleichs lässt sich ziehen. Links/rechts und oben/unten merken sich ihre Position jeweils als Anteil des Bildes, Zoomen oder Ändern der Fenstergröße verschiebt sie also nicht, und VoiceOver bewegt die Linie in Schritten. Die Linie folgt der Hand von der Stelle aus, an der sie gefasst wurde, statt unter den Zeiger zu springen, ein Klick ohne Bewegung lässt sie stehen, und der Größenänderungs-Cursor ist jetzt ein AppKit-Cursor-Rechteck — er kann nicht mehr auf dem Bildschirm bleiben, nachdem der Zeiger die Linie verlassen hat, was wirkte, als nähme die App keine Klicks mehr an.
  • Zweifinger-Scrollen verschiebt die Leinwand. Das Ziehen in der Leinwand gehört den Werkzeugen — Bild aufziehen, beschneiden, retuschieren —, sodass bei aktivem Werkzeug kein Weg blieb, ein vergrößertes Bild zu bewegen.
  • Die Karte des Scanfortschritts ist eine deckende Karte statt Glas. Was dort steht, muss über jedem Foto lesbar bleiben.

Geprüft

  • Vollständige strict-concurrency-Suite bestanden: 1.720 Tests, 17 bedingt übersprungen. Dieselbe Qualitätsschranke besteht in der GitHub-CI: Verträge, Provenienz, Grenzprüfungen und der Build der GUI-Tests
  • Die GUI-End-to-End-Suite besteht in der CI. Das Export-Commit-Journal wurde außerhalb des temporären Verzeichnisses geschrieben, das ein GUI-Test besitzt, sodass ein von einem Test abgebrochener Export die Bibliothek des nächsten Starts im Wiederherstellungsbildschirm festhielt; das Journal liegt nun in diesem Verzeichnis, und der Lauf ist wieder grün
  • Die Messung der Filmbasis ist über den ganzen Belichtungsbereich durch Tests abgedeckt: orange Maske, neutrale Basis und der Rückfall auf den schwachen Streifen, jeweils an synthetischen Negativen bis zu dem Punkt gemessen, an dem die Schätzung aufgeben soll
  • Die Platzierung des Flachbett-Bildes und die Verhältnissperre sind durch Unit-Tests abgedeckt, die in Millimetern messen: lange Achse, nächster Platz, Umbruch am Streifenende, Größe bezogen auf die Vorschaufläche, Einrasten samt Ankern
  • Die Rollennotiz ist durch Tests abgedeckt: nur leere Felder füllen, ein Bild, das zur Rolle stößt, ein Katalogdurchlauf, die Suche nach Kamera, Objektiv und Film sowie der Rollencode im Dateinamen
  • Beide Stufen der Exportprüfung sind durch Tests abgedeckt: ein vor dem Commit ersetztes Original, eine gleich lange Überschreibung an Ort und Stelle und der Rückfall auf den vollen Hash, wenn die stat-Identität abweicht
  • Der iCloud-Weg ist durch Tests abgedeckt: Erkennung der Auslagerung, Entdopplung und Fortschritt
  • arm64- und Universal-Release-Builds für ZIP, DMG, PKG und dSYM bestanden
  • Lokale SHA-256-Prüfung aller 10 Release-Dateien bestanden
  • Das Ziehen der Vergleichslinie und das Verschieben per Scrollen wurden nicht von Hand in der laufenden App erprobt; es sind Interaktionsänderungen ohne automatische Abdeckung.
  • Optik, Motor und USB erfordern weiterhin QA mit echten Scannern.

Full Changelog: v1.0.2...v1.0.3