branch-coexist: 3 neue decks 223015b-2026 / 223015c-2026 / dhbw-2026 daneben main
per user-request einen branch der main-content UND rewrite-content trägt — saubere separierung statt symlink/merge-conflict. struktur: - slides/<course>/ → main-content restored, eigene assets (kein new-demo-leak) - slides/<course>-2026/ → rewrite-content, eigene assets (komplett kopiert + new demos) Makefile: COURSES += 223015b-2026 223015c-2026 dhbw-2026 mit eigenen NAME/KAPITEL/DEPLOY/KLAUSUR-konfig. Klausur für b+c=1, dhbw=leer. Deploy-paths /hdm/223015b-2026 etc. make build durchlaufen für alle 6 decks, 0 fehler. dedup: 223015c+dhbw assets identisch in beiden ordnern (kein neu-demos auf b ergänzt). 223015b 86 → 120 files in -2026 (= +34 neue eroeffner/usb-c-drei-achsen/container-vs-codec/etc).
No files matched your search
@@ -0,0 +1,192 @@
|
||||
---
|
||||
marp: true
|
||||
theme: gaia
|
||||
paginate: true
|
||||
backgroundColor: #fff
|
||||
header: "Dateiformate, Schnittstellen, Speichermedien & Distributionswege (223015b)"
|
||||
footer: "Michael Czechowski – HdM Stuttgart – SoSe 2026"
|
||||
title: Dateiformate, Schnittstellen, Speichermedien & Distributionswege
|
||||
---
|
||||
|
||||
<style>
|
||||
:root {
|
||||
--color-foreground: #1a1a2e;
|
||||
--color-highlight: #1e5f8a;
|
||||
--color-dimmed: #4a4a6a;
|
||||
}
|
||||
section.invert {
|
||||
--color-foreground: #fff;
|
||||
}
|
||||
section {
|
||||
font-size: 1.7rem;
|
||||
}
|
||||
h1 {
|
||||
color: #1e5f8a;
|
||||
}
|
||||
section.invert h1 {
|
||||
color: #fff;
|
||||
}
|
||||
h2 {
|
||||
color: #1f2937;
|
||||
}
|
||||
pre {
|
||||
background: #0f0f23;
|
||||
color: #5fb3e4;
|
||||
border-radius: 8px;
|
||||
border-left: 3px solid #1e5f8a;
|
||||
}
|
||||
pre code {
|
||||
background: transparent;
|
||||
color: inherit;
|
||||
}
|
||||
code {
|
||||
background: #0f0f23;
|
||||
padding: 0.15em 0.4em;
|
||||
border-radius: 4px;
|
||||
font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
|
||||
}
|
||||
section code:not(.hljs) { color: #5fb3e4 !important; }
|
||||
section code.hljs { color: #f8f8f8 !important; }
|
||||
a {
|
||||
color: var(--color-highlight);
|
||||
}
|
||||
section.klausur {
|
||||
background: repeating-linear-gradient(
|
||||
135deg,
|
||||
#e3f2fd,
|
||||
#e3f2fd 40px,
|
||||
#fff 40px,
|
||||
#fff 80px
|
||||
) !important;
|
||||
}
|
||||
@media print {
|
||||
section.klausur {
|
||||
background: #e3f2fd !important;
|
||||
}
|
||||
}
|
||||
section.aufgabe {
|
||||
background: #e3f2fd !important;
|
||||
}
|
||||
section.aufgabe footer {
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
|
||||
<!-- _class: invert -->
|
||||
<!-- _header: '' -->
|
||||
<!-- _backgroundColor: #000 -->
|
||||
|
||||

|
||||
|
||||
# Dateiformate, Schnittstellen, Speichermedien & Distributionswege
|
||||
|
||||
**223015b** · Modul "Technik 1" · 1. Semester
|
||||
Digital- und Medienwirtschaft
|
||||
Hochschule der Medien Stuttgart
|
||||
|
||||
**Sommersemester 2026**
|
||||
|
||||
[https://librete.ch/hdm/223015b/](https://librete.ch/hdm/223015b/)
|
||||
|
||||
---
|
||||
|
||||
<!-- _header: '' -->
|
||||
<!-- _footer: '' -->
|
||||
|
||||

|
||||
|
||||
---
|
||||
|
||||
<!-- _class: lead -->
|
||||
|
||||
# Herzlich willkommen!
|
||||
## Einführung
|
||||
|
||||
---
|
||||
|
||||
# Über mich
|
||||
|
||||
**Michael Werner Czechowski**
|
||||
|
||||
- Systems and Platform Engineer
|
||||
- Schwerpunkte:
|
||||
- Web-Technologien, Barriere-Armut, Systemarchitektur, Open Source
|
||||
- Hintergrund:
|
||||
- Philosophie (Uni Stuttgart)
|
||||
- Wirtschaftsinformatik (Leibniz-FH Hannover)
|
||||
- Kontakt: lb-czechowski@hdm-stuttgart.de
|
||||
|
||||
---
|
||||
|
||||
# Warum dieses Modul?
|
||||
|
||||
**Digitale Medien sind überall.**
|
||||
|
||||
* Warum enthalten Fotos oft Informationen über den Aufnahmeort?
|
||||
* Warum lassen sich gelöschte Dateien wiederherstellen?
|
||||
* Warum benötigt eine Minute 4K-Video unkomprimiert 45 GB Speicher?
|
||||
* Warum zeigt eine "1 TB"-Festplatte nur 931 GB an?
|
||||
* Warum ist USB-C nicht gleich USB-C?
|
||||
* Ziel: **→ Mitreden können!**
|
||||
|
||||
<!--
|
||||
1. EXIF (Exchangeable Image File Format)-Metadaten speichern GPS-Koordinaten, Kameramodell und Zeitstempel automatisch. Die meisten wissen nicht, dass diese Daten beim Versenden mitgeschickt werden. → Kapitel 4: Metadaten
|
||||
|
||||
2. Beim Löschen wird nur der Verzeichniseintrag im Dateisystem entfernt, nicht die Daten selbst. Die Bits bleiben auf dem Datenträger, bis sie überschrieben werden. → Kapitel 3: Dateisysteme
|
||||
|
||||
3. 3840 × 2160 Pixel × 3 Byte (RGB) × 30 Bilder/Sek × 60 Sek = ~45 GB. Codecs wie H.264/H.265 komprimieren um Faktor 100+. → Kapitel 1+2: Kompression
|
||||
|
||||
4. Hersteller rechnen dezimal (1 TB = 10¹² Bytes), Betriebssysteme binär (1 TiB = 2⁴⁰ Bytes). Die Differenz beträgt bei Terabyte bereits ~10%. → Kapitel 1: Dateneinheiten
|
||||
|
||||
5. USB-C ist nur die Steckerform. Dahinter können USB 2.0 (480 Mbit/s), USB 3.2 (20 Gbit/s) oder Thunderbolt 4 (40 Gbit/s) laufen — gleiches Kabel, völlig unterschiedliche Leistung. → Kapitel 3: Schnittstellen
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
# Kurze Umfrage
|
||||
|
||||
**Bitte Hand heben:**
|
||||
|
||||
* Wer kennt den Unterschied zwischen analog und digital?
|
||||
* Wer hat schon mal eine Datei von einem Format in ein anderes konvertiert?
|
||||
* Wer hat schon mal Metadaten aus einem Foto entfernt?
|
||||
* Wer hat schon mal ein Backup verloren?
|
||||
* Wer hat schon mal ein Backup wiederhergestellt?
|
||||
|
||||
<!--
|
||||
Niveau der Gruppe einschätzen
|
||||
Keine falschen Antworten
|
||||
Zeigt, wo wir starten
|
||||
API = Application Programming Interface
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
# Kursübersicht
|
||||
|
||||
**Kapitel:**
|
||||
|
||||
* 1. **Grundlagen**, Text & Audio (Bits, Bytes, Zeichenkodierung, MP3)
|
||||
* 2. Bild- & Video-**Kompression** (JPEG, PNG, H.264/H.265)
|
||||
* 3. **Speichermedien** & **Schnittstellen** (HDD, SSD, USB, Thunderbolt)
|
||||
* 4. **Distribution** und Verteilung (Streaming, REST, Cloud)
|
||||
* Vertiefung & offene Fragen
|
||||
|
||||
|
||||
---
|
||||
|
||||
<!-- _class: klausur -->
|
||||
<!-- _header: '' -->
|
||||
<!-- _footer: '' -->
|
||||
<!-- _backgroundColor: #e3f2fd -->
|
||||
|
||||
# Prüfungsleistung
|
||||
|
||||
**Nach aktuellem Kenntnisstand:**
|
||||
|
||||
* 90 min insg. (Technik 1)
|
||||
* Schriftliche Klausur (digital)
|
||||
* Teils offene Fragen
|
||||
* Kein Coding/Programmieren
|
||||
* **Prüfungsrelevante Folien:**
|
||||
- Gestreift oder Vollton (PDF) markiert
|
||||
@@ -0,0 +1,935 @@
|
||||
---
|
||||
marp: true
|
||||
theme: gaia
|
||||
paginate: true
|
||||
backgroundColor: #fff
|
||||
header: "Dateiformate, Schnittstellen, Speichermedien & Distributionswege (223015b)"
|
||||
footer: "Michael Czechowski – HdM Stuttgart – SoSe 2026"
|
||||
title: Dateiformate, Schnittstellen, Speichermedien & Distributionswege
|
||||
---
|
||||
|
||||
<style>
|
||||
@import url('https://fonts.googleapis.com/css2?family=Noto+Sans+JP:wght@400;700&family=Noto+Sans+SC:wght@400;700&display=swap');
|
||||
:root {
|
||||
--color-foreground: #1a1a2e;
|
||||
--color-highlight: #1e5f8a;
|
||||
--color-dimmed: #4a4a6a;
|
||||
}
|
||||
section.invert {
|
||||
--color-foreground: #fff;
|
||||
}
|
||||
section {
|
||||
font-size: 1.7rem;
|
||||
font-family: system-ui, -apple-system, "Segoe UI", Roboto, "Noto Sans JP", "Noto Sans SC", "Apple Color Emoji", "Segoe UI Emoji", sans-serif;
|
||||
}
|
||||
h1 {
|
||||
color: #1e5f8a;
|
||||
}
|
||||
section.invert h1 {
|
||||
color: #fff;
|
||||
}
|
||||
h2 {
|
||||
color: #1f2937;
|
||||
}
|
||||
pre {
|
||||
background: #0f0f23;
|
||||
color: #5fb3e4;
|
||||
border-radius: 8px;
|
||||
border-left: 3px solid #1e5f8a;
|
||||
}
|
||||
pre code {
|
||||
background: transparent;
|
||||
color: inherit;
|
||||
}
|
||||
code {
|
||||
background: #0f0f23;
|
||||
padding: 0.15em 0.4em;
|
||||
border-radius: 4px;
|
||||
font-family: ui-monospace, "SF Mono", Menlo, Consolas, "Noto Sans JP", "Noto Sans SC", "Apple Color Emoji", "Segoe UI Emoji", monospace;
|
||||
}
|
||||
section code:not(.hljs) { color: #5fb3e4 !important; }
|
||||
section code.hljs { color: #f8f8f8 !important; }
|
||||
a {
|
||||
color: var(--color-highlight);
|
||||
}
|
||||
section.klausur {
|
||||
background: repeating-linear-gradient(
|
||||
135deg,
|
||||
#e3f2fd,
|
||||
#e3f2fd 40px,
|
||||
#fff 40px,
|
||||
#fff 80px
|
||||
) !important;
|
||||
}
|
||||
@media print {
|
||||
section.klausur {
|
||||
background: #e3f2fd !important;
|
||||
}
|
||||
}
|
||||
section.aufgabe {
|
||||
background: #e3f2fd !important;
|
||||
}
|
||||
section.aufgabe footer {
|
||||
display: none;
|
||||
}
|
||||
section.erklaerung :not(header),
|
||||
section.erklaerung :not(footer)
|
||||
{
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
section.erklaerung h1 {
|
||||
font-size: 1.5rem;
|
||||
color: #1e5f8a;
|
||||
margin-bottom: 0.3rem;
|
||||
}
|
||||
section.erklaerung ul,
|
||||
section.erklaerung ol {
|
||||
font-size: 1.0rem;
|
||||
line-height: 1.4;
|
||||
}
|
||||
section.erklaerung p {
|
||||
font-size: 1.0rem;
|
||||
line-height: 1.4;
|
||||
}
|
||||
section.erklaerung table {
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
</style>
|
||||
|
||||
<!-- _class: invert -->
|
||||
<!-- _header: '' -->
|
||||
<!-- _backgroundColor: #000 -->
|
||||
|
||||

|
||||
|
||||
# Dateiformate, Schnittstellen, Speichermedien & Distributionswege
|
||||
|
||||
**223015b** · Modul "Technik 1" · 1. Semester
|
||||
Digital- und Medienwirtschaft
|
||||
Hochschule der Medien Stuttgart
|
||||
|
||||
[https://librete.ch/hdm/223015b/](https://librete.ch/hdm/223015b/)
|
||||
|
||||
---
|
||||
|
||||

|
||||
|
||||
---
|
||||
|
||||
<!-- _class: lead -->
|
||||
|
||||
# Kapitel 1
|
||||
## Daten-Grundlagen + Vom Signal zum Byte
|
||||
|
||||
<!--
|
||||
Eine Stunde, eine Frage: *Was steckt in einer Datei — und wie kommt es da rein?*
|
||||
|
||||
Roter Faden:
|
||||
1. Foto, Sprachnachricht, PDF — drei vertraute Dinge, alle haben dasselbe Innenleben
|
||||
2. Hex-Editor auf — Zahlen, nichts als Zahlen
|
||||
3. Wie man die Zahlen liest (Bit/Byte/Hex als drei Schreibweisen)
|
||||
4. Was die Zahlen bedeuten (ASCII → Unicode → Magic Numbers)
|
||||
5. PIVOT — aber wie kommen die Zahlen überhaupt rein?
|
||||
6. Sampling + Quantisierung — zwei Schritte, die jedes Signal digitalisieren
|
||||
7. Nyquist als Begründung für 44,1 kHz
|
||||
8. Aliasing als „was schiefgehen kann" — Audio-Knack und Moiré als gleiches Phänomen
|
||||
|
||||
Das Kapitel hat zwei Strangs, die sich an der Mitte (= Byte) treffen.
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
<!-- _class: lead -->
|
||||
|
||||
# Was steckt eigentlich in einer Datei?
|
||||
|
||||
<!--
|
||||
Beispiele aus dem Alltag der Studis:
|
||||
- Foto auf dem Smartphone
|
||||
- Sprachnachricht in WhatsApp
|
||||
- PDF im Studi-Mailfach
|
||||
|
||||
Frage: Wenn wir die alle aufmachen würden — was würden wir sehen? Was haben die *gemeinsam*?
|
||||
|
||||
Antwort kommt auf der nächsten Folie.
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
<!-- _header: '' -->
|
||||
<!-- _footer: '' -->
|
||||
|
||||

|
||||
|
||||
<!--
|
||||
Aufdeckung: Foto · Sprachnachricht · PDF sehen außen ganz verschieden aus. Aber wenn man den ersten Byte-Block anschaut: alle haben eine Visitenkarte (Magic Number) und bestehen ab da nur aus Byte.
|
||||
|
||||
- Foto: 89 50 4E 47 = PNG
|
||||
- Sprachnachricht: 49 44 33 = ID3 (MP3-Tag)
|
||||
- PDF: 25 50 44 46 = %PDF
|
||||
|
||||
Aussage: Außen verschieden, innen dieselbe Sprache. Egal ob Bild, Ton oder Dokument — eine Datei ist immer eine Folge von Byte.
|
||||
|
||||
Was ein Byte ist und wie man es liest — kommt in den nächsten Folien.
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||

|
||||
|
||||
# WTF!?
|
||||
|
||||
```
|
||||
89 50 4E 47 0D 0A 1A 0A
|
||||
00 00 00 0D 49 48 44 52
|
||||
00 00 01 90 00 00 01 2C
|
||||
```
|
||||
|
||||
<!--
|
||||
Schock-Hook: das hier ist eine PNG-Datei. So sieht sie wirklich aus, wenn man sie im Hex-Editor öffnet.
|
||||
|
||||
Studis sollen sich kurz wundern: das ist ein Bild? Es sieht aus wie Matrix-Code.
|
||||
|
||||
Auflösung kommt Stück für Stück.
|
||||
|
||||
Tool, das Studis benutzen können: hexed.it (Browser, kein Install).
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
# Eine Datei ist ein Byte-Strom
|
||||
|
||||
**Vorne nach hinten. Ein Byte nach dem anderen.**
|
||||
|
||||
Egal welches Format — die Datei beginnt mit Byte 1 und endet irgendwann.
|
||||
|
||||
Jedes Byte ist eine Zahl zwischen `0` und `255`. *Mehr ist da nicht.*
|
||||
|
||||
<!--
|
||||
Mentales Bild: Datei = Lokomotive aus Waggons. Jeder Waggon = 1 Byte = 1 Zahl 0..255.
|
||||
|
||||
- Festplatte/SSD: speichert byteweise
|
||||
- Speicher (RAM): liest byteweise
|
||||
- CPU: adressiert byteweise (siehe nächste Folie)
|
||||
|
||||
Wichtig: Es gibt keine "halben Byte" auf der Hardware. Die kleinste Adresse ist immer ein Byte. Bit gibts logisch, aber nicht physisch adressierbar.
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
<!-- _header: '' -->
|
||||
<!-- _footer: '' -->
|
||||
|
||||

|
||||
|
||||
<!--
|
||||
Warum gerade 8 Bit (nicht 7, nicht 16)?
|
||||
- CPU adressiert byteweise — kleinste adressierbare Einheit
|
||||
- 8 Bit = 2 Hex-Ziffern (elegante Darstellung)
|
||||
- 1964: IBM System/360 setzte den 8-Bit-Standard
|
||||
- Vorher: 6-Bit + 7-Bit-Systeme parallel im Einsatz
|
||||
- 1 Bit = 2 Zustände, 2 Bit = 4, ... 8 Bit = 256
|
||||
|
||||
Eselsbrücke: 2 hoch (Anzahl Bit) = Anzahl Zustände.
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
<!-- _header: '' -->
|
||||
<!-- _footer: '' -->
|
||||
|
||||

|
||||
|
||||
<!--
|
||||
Drei Schreibweisen, ein Inhalt:
|
||||
- Fenster 1 (Bin): rohe 0/1 — was tatsächlich auf der Platte steht
|
||||
- Fenster 2 (Hex): 2 Ziffern pro Byte — kompakt lesbar (1 Byte = 2 Hex-Ziffern)
|
||||
- Fenster 3 (Text): ASCII-Zeichen wenn Byte ≤ 126, sonst ✗
|
||||
|
||||
Daraus folgt eine Klausurfrage: schon ein Byte > 126 → Binärdatei (PNG, MP3, ZIP).
|
||||
Nur Werte ≤ 126 → reine Textdatei (.txt, .csv, .md).
|
||||
|
||||
In diesem Kapitel reden wir nicht (nur) über die ROHEN Byte. Wir reden über die drei Brillen, mit denen man dieselben Byte anschauen kann.
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
<!-- _header: '' -->
|
||||
<!-- _footer: '' -->
|
||||
|
||||

|
||||
|
||||
<!--
|
||||
Kernidee: jedes Byte lässt sich sauber in zwei 4-Bit-Hälften (Nibbles) zerlegen. Jede Hälfte hat 2⁴ = 16 Zustände — und genau 16 Symbole hat Hex (0–F). Deshalb passt Hex perfekt:
|
||||
|
||||
- 1 Nibble = 1 Hex-Ziffer
|
||||
- 1 Byte = 2 Hex-Ziffern
|
||||
|
||||
Keine krumme Umrechnung. Hex ist die menschenfreundliche Schreibweise des Maschinenformats.
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
<!-- _header: '' -->
|
||||
<!-- _footer: '' -->
|
||||
|
||||

|
||||
|
||||
<!--
|
||||
Hex ↔ Dezimal Lookup:
|
||||
- 0..9 wie gewohnt
|
||||
- A = 10, B = 11, C = 12, D = 13, E = 14, F = 15
|
||||
|
||||
Studis müssen das nicht auswendig wissen. Aber sie sollen erkennen: Hex ist nicht Magic — es ist eine Schreibweise mit 16 Symbolen statt 10.
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
# 01010000 oder 50 — was liest sich leichter?
|
||||
|
||||
**Binär:** `01010000 01001110 01000111`
|
||||
|
||||
**Hex:** `50 4E 47`
|
||||
|
||||
Drei Byte. Dasselbe Inhalt. Hex ist nur **handlicher**.
|
||||
|
||||
**Wo trifft man Hex im Alltag?** Beim CSS-Farbcode:
|
||||
`#FF5733` — das sind 3 Byte (Rot, Grün, Blau).
|
||||
|
||||
<!--
|
||||
Anker im Alltag: CSS-Farbe `#FF5733`. Jede:r hat das mal gesehen — im Designtool, in der dev console, beim Theme-Eintippen.
|
||||
|
||||
Auflösung:
|
||||
- #FF = 255 = Rot voll
|
||||
- #57 = 87 = Grün mittel
|
||||
- #33 = 51 = Blau wenig
|
||||
- Ergibt ein warmes Orange.
|
||||
|
||||
Klausurrelevant: wenn jemand sagt "lila ist B399FF", können wir die drei Byte sofort als RGB lesen.
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
# Hex begegnet euch überall
|
||||
|
||||
| Kontext | Beispiel |
|
||||
|---------|----------|
|
||||
| CSS-Farben | `#FF5733` |
|
||||
| MAC-Adressen | `00:1A:2B:3C:4D:5E` |
|
||||
| Speicheradressen | `0xA04F20` |
|
||||
| Windows-Fehlercodes | `0x80070005` |
|
||||
| Unicode-Codepoints | `U+00E4` (ä) |
|
||||
| Datei-Signaturen | `89 50 4E 47` (PNG) |
|
||||
|
||||
<!--
|
||||
Präfixe:
|
||||
- `0x` = "das ist Hex" (in C, JS, Python)
|
||||
- `U+` = Unicode-Codepoint
|
||||
- `#` = CSS-Konvention
|
||||
|
||||
Lebensweltanker: jede:r Studi hat mindestens drei dieser Kontexte schon real gesehen. Hex ist nicht eine akademische Übung, sondern die Lesart, in der Computer mit Menschen über Byte reden.
|
||||
|
||||
MAC-Adresse: 6 Byte = 6 Paare Hex-Ziffern. Eindeutige Hardware-Kennung der Netzwerkkarte.
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
<!-- _header: '' -->
|
||||
<!-- _footer: '' -->
|
||||
|
||||

|
||||
|
||||
<!--
|
||||
1 Byte = 8 Bit = 2 Hex-Ziffern = max. 1 ASCII-Zeichen.
|
||||
|
||||
Dieselbe Datei, drei Schreibweisen — Byte für Byte parallel angezeigt.
|
||||
- Jeder Rahmen = ein Byte.
|
||||
- Byte ändern sich nicht, nur unsere Anzeige.
|
||||
- `0x0A` = Zeilenumbruch, nicht druckbar → Hex-Editoren zeigen `.` als Platzhalter.
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
<!-- _header: '' -->
|
||||
<!-- _footer: '' -->
|
||||
|
||||

|
||||
|
||||
<!--
|
||||
Dieselben 8 Byte (PNG-Dateianfang: 89 50 4E 47 0D 0A 1A 0A) — drei Perspektiven:
|
||||
|
||||
1. Bitstream — was wirklich gespeichert wird (unleserlich)
|
||||
2. Hex — gruppiert in 8-Bit-Häppchen (kompakt)
|
||||
3. Bedeutung — was die Byte signalisieren:
|
||||
- 89: Magic Byte (>127 → "ich bin Binärdatei")
|
||||
- 50 4E 47: P · N · G (ASCII-Format-Kürzel)
|
||||
- 0D 0A 1A 0A: Carriage Return · Line Feed · End-of-File · Line Feed (erkennt kaputte Übertragung)
|
||||
|
||||
Aussage: dieselbe Datei, je nach Brille sehe ich anderes. Die Datei selbst ändert sich nicht.
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
<!-- _class: lead -->
|
||||
|
||||
# Was bedeutet die Zahl `80`?
|
||||
|
||||
<!--
|
||||
Strang-Wechsel: bis hier haben wir Byte als NOTATION gelernt (Bin/Hex parallele Schreibweisen). Jetzt fragen wir: was *bedeuten* die Byte?
|
||||
|
||||
Die Zahl 80 in einer Textdatei ist der Buchstabe „P". Das ist ASCII.
|
||||
|
||||
Auflösung kommt mit der ascii-Tabelle.
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
<!-- _header: '' -->
|
||||
<!-- _footer: '' -->
|
||||
|
||||

|
||||
|
||||
<!--
|
||||
US-ASCII (1967) Code Chart:
|
||||
- 7 Bit = 128 Zeichen
|
||||
- Erste 32 Zeichen: Steuerzeichen (nicht druckbar) — z.B. Tab, Newline, Backspace
|
||||
- Zeichen 32–126: druckbar (Buchstaben, Ziffern, Satzzeichen)
|
||||
- Zeichen 127: DEL
|
||||
- Keine Umlaute, kein ñ, kein é, kein chinesisches Zeichen
|
||||
|
||||
Geschichte:
|
||||
- 1963 als US-amerikanischer Standard
|
||||
- 7 Bit, weil Fernschreiber 7-Bit-Codes nutzten + Paritätsbit für Fehlererkennung
|
||||
- 60 Jahre alt, lebt aber weiter — siehe UTF-8 (ASCII-kompatibel)
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
<!-- _class: lead -->
|
||||
|
||||
# ASCII reicht für Englisch.
|
||||
## Aber was ist mit *ä, é, 中, 🌸*?
|
||||
|
||||
<!--
|
||||
Bridge: ASCII löst das Problem nur für englischen Text.
|
||||
Sobald Umlaute, Akzente, asiatische Schriften oder Emoji ins Spiel kommen, sprengt es den 7-Bit-Raum.
|
||||
|
||||
Quizfrage an die Studis: Wie viel Speicher braucht ein „ä"? Antwort: Kommt drauf an, welches Encoding. ASCII kann es gar nicht; UTF-8 braucht 2 Byte.
|
||||
|
||||
Lösung: Unicode + UTF-8 (nächste Folie).
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
# Unicode: ein Standard für alle
|
||||
|
||||
**Unicode (1991):** jedes Schriftsystem der Welt.
|
||||
**> 150.000 Zeichen.** Latein, Kyrillisch, Arabisch, Chinesisch, Japanisch, mathematische Symbole, Emoji.
|
||||
|
||||
**UTF-8** speichert Unicode mit *variabler Länge:*
|
||||
|
||||
- Zeichen 0–127: **1 Byte** (identisch mit ASCII — Abwärtskompatibilität!)
|
||||
- Westeuropäische Umlaute: **2 Byte**
|
||||
- Chinesisch/Japanisch: **3 Byte**
|
||||
- Emoji: **4 Byte**
|
||||
|
||||
<!--
|
||||
- Unicode Consortium: Non-Profit, gegründet 1991
|
||||
- Unicode 16.0 (2024): 154.998 Zeichen
|
||||
- UTF-8 = Unicode Transformation Format, 8-bit (Ken Thompson & Rob Pike, 1992)
|
||||
- Die ersten 128 Zeichen in UTF-8 sind exakt ASCII — Grund warum ASCII nie verschwinden wird
|
||||
- UTF-8 ist seit 2008 das häufigste Encoding im Web (W3Techs)
|
||||
|
||||
Pädagogisch wichtig: variable Länge heißt, dass „Zeichen zählen" und „Byte zählen" NICHT dasselbe sind. Das ist die Brücke zur nächsten Folie.
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
# Beispiel: Byte zählen
|
||||
|
||||
**Text:** `"Hello·🌸·こんにちは·(Kon-ni-chi-wa)"`
|
||||
|
||||
| Zeichen | Byte |
|
||||
|---------|-------|
|
||||
| `Hello·` | 6 × 1 = **6 Byte** (ASCII) |
|
||||
| `🌸` | **4 Byte** (Emoji) |
|
||||
| `·` | **1 Byte** |
|
||||
| `こんにちは` | 5 × 3 = **15 Byte** (Hiragana) |
|
||||
| `·(Kon-ni-chi-wa)` | **16 Byte** (ASCII) |
|
||||
|
||||
**Gesamt: 42 Byte für 29 sichtbare Zeichen.**
|
||||
|
||||
<!--
|
||||
Klausurfähig: gegeben ein Text mit ASCII, Umlauten, CJK und Emoji — wie viel Byte ist das?
|
||||
|
||||
- ASCII (Hello, Klammern) = 1 Byte pro Zeichen
|
||||
- Emoji 🌸 (Cherry Blossom U+1F338) = 4 Byte
|
||||
- Hiragana こんにちは = 3 Byte pro Zeichen (U+3040–309F)
|
||||
- は wird hier „wa" ausgesprochen (Partikel), nicht „ha"
|
||||
|
||||
Pointe: 29 sichtbare Zeichen, 42 Byte. Zeichen ≠ Byte sobald Unicode > 127.
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
<!-- _class: lead -->
|
||||
|
||||
# Woher weiß der Computer, was das ist?
|
||||
|
||||
<!--
|
||||
Pivot zur dritten Bedeutungsebene: nicht „was bedeutet die Zahl 80?" (= P im ASCII), sondern „was bedeutet die *Folge* von Byte am Anfang einer Datei?".
|
||||
|
||||
Antwort: Magic Numbers. Die ersten paar Byte sind die Visitenkarte des Formats.
|
||||
|
||||
Auflösung kommt mit Magic-Numbers-Folie.
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
# Magic Numbers — die Visitenkarte der Datei
|
||||
|
||||
**Datei-Typ erkennt man an den ersten Byte:**
|
||||
|
||||
| Format | Magic Number (Hex) | Lesbar? |
|
||||
|--------|-------------------|---------|
|
||||
| PNG | `89 50 4E 47` | (89 außerhalb ASCII) P N G |
|
||||
| JPEG | `FF D8 FF` | — |
|
||||
| PDF | `25 50 44 46` | % P D F |
|
||||
| ZIP | `50 4B 03 04` | P K — — |
|
||||
|
||||
**Achtung:** Werte > 127 sind nicht ASCII-druckbar. *Hex-Editoren zeigen einen Punkt oder ein anderes Ersatzzeichen als Platzhalter.*
|
||||
|
||||
<!--
|
||||
- PNG nutzt absichtlich `89` (= 137 dezimal): markiert Datei eindeutig als Binär. Erkennt kaputte Übertragungen (alte Systeme schnitten Bit 7 ab).
|
||||
- "PK" bei ZIP = Phil Katz (Erfinder von PKZip, 1989)
|
||||
- DOCX, XLSX, PPTX, ODT = alles ZIP-Archive mit XML-Inhalt
|
||||
- Dateien OHNE Magic Number: TXT, HTML, CSS, JSON, XML — reiner Text, kein binäres Format
|
||||
- Sicherheitsrelevant: virus.exe → bild.jpg umbenennen täuscht nur Menschen; `file` (Linux) liest Magic Number und erkennt die echte Identität.
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
<!-- _header: '' -->
|
||||
<!-- _footer: '' -->
|
||||
<!-- _backgroundColor: #000 -->
|
||||
|
||||

|
||||
|
||||
<!--
|
||||
Echte PNG-Datei im Hex-Editor.
|
||||
|
||||
Erste Byte: 89 50 4E 47 = PNG-Signatur.
|
||||
- 89: non-printable (außerhalb ASCII)
|
||||
- 50: P
|
||||
- 4E: N
|
||||
- 47: G
|
||||
- Danach IHDR = Image Header (Breite, Höhe, Farbtiefe)
|
||||
|
||||
Tool: HxD (Windows), Hex Fiend (Mac), xxd (Linux), hexed.it (Browser).
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
<!-- _header: '' -->
|
||||
<!-- _footer: '' -->
|
||||
|
||||

|
||||
|
||||
<!--
|
||||
Zoom auf den Buchstaben „P":
|
||||
|
||||
- Hex: 50
|
||||
- Dezimal: 80
|
||||
- Binär: 01010000
|
||||
- ASCII: P
|
||||
|
||||
Ein Byte. Acht Bit. Ein Buchstabe. Drei Schreibweisen.
|
||||
|
||||
Das ist die Brücke zwischen Notation (Hex/Bin) und Bedeutung (ASCII).
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
<!-- _header: '' -->
|
||||
<!-- _footer: '' -->
|
||||
|
||||

|
||||
|
||||
# Selbstlernen — HEX Files identifizieren
|
||||
|
||||
1. Fünf Dateien ohne Dateiendung:
|
||||
<a href="https://librete.ch/hdm/223015b/materials/hex1">`hex1`</a> · <a href="https://librete.ch/hdm/223015b/materials/hex2">`hex2`</a> · <a href="https://librete.ch/hdm/223015b/materials/hex3">`hex3`</a> · <a href="https://librete.ch/hdm/223015b/materials/hex4">`hex4`</a> · <a href="https://librete.ch/hdm/223015b/materials/hex5">`hex5`</a>
|
||||
2. Lies erste 16 Byte aus und identifiziere Dateiformat (Magic Number)
|
||||
3. *Optional: Datei umbenennen und korrekte Dateiendung anhängen (z.B. `.jpg`)*
|
||||
|
||||
**Tools:** [hexed.it](https://hexed.it) · [Wikipedia-Magic-Number-Liste](https://en.wikipedia.org/wiki/List_of_file_signatures)
|
||||
|
||||
<!--
|
||||
- hex1: Plaintext (keine Magic Number — pure ASCII)
|
||||
- hex2: PNG (89 50 4E 47)
|
||||
- hex3: JPEG (FF D8 FF)
|
||||
- hex4: DOCX (50 4B 03 04 — ZIP-Container, XML drin)
|
||||
- hex5: ZIP (50 4B 03 04)
|
||||
|
||||
Pädagogisch: Studis sollen selbst sehen, dass Datei-Erkennung nicht über die Endung läuft, sondern über die Byte am Anfang. Das ist eine kleine Macht-Erfahrung — sie können mit `hexed.it` etwas, das die meisten Leute nicht können.
|
||||
|
||||
Gruppenarbeit: 3–4 Personen. ~15 Min.
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
# KB vs KiB — warum „1 TB" als 931 GB angezeigt wird
|
||||
|
||||

|
||||
|
||||
**Auf der Verpackung:** 1 TB = 10¹² Byte (dezimal).
|
||||
**Im Finder:** 931 GB = eigentlich 931 GiB (binär, 1024³).
|
||||
|
||||
Es fehlt nichts — beide Seiten zählen nur in **verschiedenen Sprachen.**
|
||||
|
||||
<!--
|
||||
- Marketing nutzt SI-Präfixe (1000³, 1000⁴) → größere Zahlen auf der Packung.
|
||||
- Betriebssysteme rechnen in Zweier-Potenzen (1024³) → kleinere angezeigte Zahl, weil Bits binär organisiert sind.
|
||||
- Korrekt wären `GiB` (Gibi-, binär) und `GB` (Giga-, dezimal). Realität: beide nennen es `GB`.
|
||||
|
||||
Rechnung: 10¹² ÷ 2³⁰ ≈ 931,3 GiB. Der Finder zeigt „931 GB".
|
||||
|
||||
Klausurfähig: warum zeigt eine 1-TB-SSD im Finder „931 GB"? Begründung mit Rechnung.
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
# Dateneinheiten — Größenordnungen
|
||||
|
||||
| Einheit | Bytes (dezimal) | Beispiel |
|
||||
|---------|------:|----------|
|
||||
| **Byte** | 1 | Farbwert eines Pixels |
|
||||
| **Kilobyte (KB)** | 1.000 | kleiner Programmcode |
|
||||
| **Megabyte (MB)** | 1 Million | Textdokument |
|
||||
| **Gigabyte (GB)** | 1 Milliarde | Kinofilm in FullHD |
|
||||
| **Terabyte (TB)** | 1 Billion | ~12h Video in 4K |
|
||||
| **Petabyte (PB)** | 1 Billiarde | Netflix-Gesamtarchiv |
|
||||
| **Exabyte (EB)** | 1 Trillion | Alle E-Mails weltweit/Tag |
|
||||
| **Zettabyte (ZB)** | 1 Trilliarde | globale Datenmenge ~heute |
|
||||
|
||||
<!--
|
||||
SI-Präfixe (Dezimal): 1 KB = 1.000 Bytes. Auf Packungen, in Marketing.
|
||||
IEC-Präfixe (Binär): 1 KiB = 1.024 Bytes (Kibibyte). In Betriebssystemen (oft ohne i geschrieben — Verwechselung!).
|
||||
|
||||
Eselsbrücke für die Reihenfolge:
|
||||
„**K**omm **M**it **G**roßem **T**ee, **P**eter **E**xte **Z**ettelt **Y**achten."
|
||||
→ Kilo, Mega, Giga, Tera, Peta, Exa, Zetta, Yotta.
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
<!-- _header: '' -->
|
||||
<!-- _footer: '' -->
|
||||
|
||||

|
||||
|
||||
<!--
|
||||
PIVOT. Wir haben die rechte Seite des Bogens abgearbeitet: aus Byte wird Bedeutung (Notation, Encoding, Format). Jetzt drehen wir um: wie kommen die Byte überhaupt rein?
|
||||
|
||||
Beispiele:
|
||||
- Wir machen ein Foto → Lichtwelle → Pixel-Byte
|
||||
- Wir reden ins Mikro → Schallwelle → Audio-Byte
|
||||
- Wir tippen Text → Tastendruck → ASCII-Byte (das ist die einfache Variante)
|
||||
|
||||
Die kontinuierliche Welt ist analog. Die Datei ist digital. Der Weg dazwischen heißt: Sampling + Quantisierung. Das schauen wir uns jetzt an, am Beispiel Audio.
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
# Analog vs. Digital — am Beispiel Schall
|
||||
|
||||

|
||||
|
||||
Eine Stimme ist eine **Druckwelle**. Kontinuierlich — keine Stufen, keine Sprünge.
|
||||
|
||||
Eine Audiodatei ist eine Folge von **Zahlen** — diskret, in Stufen.
|
||||
|
||||
Wie übersetzen wir die Welle in Zahlen?
|
||||
|
||||
**Zwei Schritte:** Sampling (wie oft) + Quantisierung (wie genau).
|
||||
|
||||
<!--
|
||||
- Schall ist physikalisch: Luftmoleküle drücken auf das Trommelfell.
|
||||
- Diese Druckschwankung folgt einer kontinuierlichen Kurve in der Zeit.
|
||||
- Analog speichern (Vinyl, Tonband): die Rille / das Magnetfeld speichern die Druckkurve direkt.
|
||||
- Digital speichern: wir messen die Welle in regelmäßigen Abständen (Sampling) und runden jede Messung auf eine Stufe (Quantisierung).
|
||||
|
||||
Beide Schritte sind notwendig. Beide haben einen Trade-off zwischen Datenrate und Genauigkeit.
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
# Sampling — wie oft messen wir?
|
||||
|
||||
**Abtastrate** (Sample Rate) = wie viele Messungen pro Sekunde.
|
||||
|
||||
| Sample Rate | Anwendung |
|
||||
|-------------|-----------|
|
||||
| 8 kHz | Telefon |
|
||||
| 22 kHz | alte Spiele-Sounds |
|
||||
| **44,1 kHz** | **CD-Qualität** |
|
||||
| 48 kHz | Video-Standard |
|
||||
| 96 kHz | Studio |
|
||||
|
||||
Je höher die Sample Rate, desto näher kommt die Datei an die kontinuierliche Welle.
|
||||
|
||||
<!--
|
||||
- 1 Hz = 1 Messung pro Sekunde
|
||||
- 44.100 Hz = 44.100 Messungen pro Sekunde
|
||||
- Warum genau 44,1 kHz? Kommt 5 Folien später (Nyquist).
|
||||
- Telefon mit 8 kHz: alles oberhalb 4 kHz fehlt — deshalb klingen Telefongespräche „dumpf"
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
<!-- _header: '' -->
|
||||
<!-- _footer: '' -->
|
||||
|
||||

|
||||
|
||||
<!--
|
||||
Visualisierung: eine kontinuierliche Welle wird mit unterschiedlichen Sample-Raten abgetastet. Niedrige Rate verliert Detail. Hohe Rate erfasst die Welle treu.
|
||||
|
||||
Konkrete Frage an Studis: bei welcher Rate erkennt man die Originalwelle noch?
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
# Quantisierung — wie genau messen wir?
|
||||
|
||||
**Bittiefe** (Bit Depth) = wie fein wir jede Messung auflösen.
|
||||
|
||||
| Bittiefe | Stufen | Dynamikumfang |
|
||||
|----------|--------|---------------|
|
||||
| 8 Bit | 256 | ~48 dB |
|
||||
| **16 Bit (CD)** | **65.536** | **~96 dB** |
|
||||
| 24 Bit (Studio) | 16,8 Mio. | ~144 dB |
|
||||
|
||||
Je mehr Bit, desto kleiner der **Quantisierungsfehler** (Differenz zur Original-Druckwelle).
|
||||
|
||||
<!--
|
||||
- Bittiefe sagt: wie viele verschiedene Lautstärke-Stufen kennt das Format pro Messung.
|
||||
- 8 Bit = 256 Stufen: hörbar grobkörnig (Quantisierungsrauschen).
|
||||
- 16 Bit = 65.536 Stufen: für menschliches Hören mehr als genug (~96 dB Dynamik = vom Flüstern bis zum Konzertsaal-Forte).
|
||||
- 24 Bit im Studio: Headroom für Bearbeitung, kein hörbarer Unterschied beim Endprodukt (Meyer & Moran, JAES 2007).
|
||||
|
||||
Eselsbrücke: Sampling = horizontal (Zeit-Achse). Quantisierung = vertikal (Amplituden-Achse).
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
<!-- _header: '' -->
|
||||
<!-- _footer: '' -->
|
||||
|
||||

|
||||
|
||||
<!--
|
||||
Quantisierung am Bild-Beispiel: dasselbe Foto mit unterschiedlicher Farbtiefe.
|
||||
|
||||
- Original: 24-Bit-Farbe (16,8 Mio. Farben)
|
||||
- 8-Bit-Quantisierung: nur 256 mögliche Farben → sichtbare Stufen, Posterisierung
|
||||
|
||||
Das ist dasselbe Phänomen wie Audio-Quantisierungsrauschen, nur in der visuellen Modalität. Wir reden über beides später nochmal (Aliasing-Folie).
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
# Datenrate = Sample Rate × Bittiefe × Kanäle
|
||||
|
||||
**Formel:**
|
||||
|
||||
```
|
||||
Datenrate (bit/s) = Sample Rate (Hz) × Bittiefe (bit) × Kanäle
|
||||
```
|
||||
|
||||
**Was bestimmt jeder Faktor?**
|
||||
|
||||
- **Sample Rate:** Bandbreite (Höhe der erfassbaren Töne)
|
||||
- **Bittiefe:** Dynamik (Stufenfeinheit)
|
||||
- **Kanäle:** Stereo, Mono, Surround
|
||||
|
||||
Daraus ergibt sich, wie groß eine Audiodatei pro Sekunde wird — *unkomprimiert*.
|
||||
|
||||
<!--
|
||||
Wichtige Klausur-Formel.
|
||||
|
||||
Anwendungsbeispiel kommt nächste Folie (CD-Audio).
|
||||
|
||||
Konsequenz: wenn ich Speicher sparen will, kann ich an einem dieser drei Parametern drehen. ABER: jede Reduktion ist hörbar.
|
||||
|
||||
Brücke zu Kap2 (Kompression): da reduzieren wir nicht die Parameter, sondern *werfen unhörbare Information weg* — das ist Psychoakustik, nicht Container-Schrumpfung.
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
# CD-Audio: die Rechnung
|
||||
|
||||
**Audio-CD (Philips/Sony 1982):**
|
||||
|
||||
```
|
||||
44.100 Hz × 16 bit × 2 Kanäle = 1.411.200 bit/s = 1,4 Mbit/s
|
||||
```
|
||||
|
||||
Pro Sekunde: ~172 KB. Pro Minute: ~10,3 MB. Pro Album (60 Min): ~635 MB.
|
||||
|
||||
*Eine ganze 90er-Festplatte für ein Album.*
|
||||
|
||||
<!--
|
||||
Diese Rechnung muss in der Klausur reproduziert werden können — Formel + Anwendung.
|
||||
|
||||
Historischer Kontext:
|
||||
- 1982: erste CD (Billy Joel – 52nd Street, Japan)
|
||||
- Festplatten der 90er: 40–500 MB → ein Album füllte die ganze Platte
|
||||
- 56k-Modem: 7 KB/s → 42 MB Song ≈ 100 Minuten Download
|
||||
- Daraus entstand der Druck zur Audio-Kompression — die wir in Kap 2 sehen werden
|
||||
|
||||
Spektrogramm-Folie als Anschluss: 44,1 kHz → wir können bis ~22 kHz erfassen. Mehr nicht. Warum genau 22 kHz? Weil Menschen bis ~20 kHz hören. Antwort kommt mit Nyquist.
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
# Nyquist — warum 2× reicht
|
||||
|
||||

|
||||
|
||||
**Sample-Rate ≥ *2× höchste Signal-Frequenz.***
|
||||
|
||||
```
|
||||
f_sample ≥ 2 · f_max
|
||||
```
|
||||
|
||||
Drei Fälle:
|
||||
|
||||
* **zu wenig** → Aliasing
|
||||
* **genau** → mathematisches Minimum
|
||||
* **mehr** → sichere Rekonstruktion
|
||||
|
||||
<!--
|
||||
Harry Nyquist (1928) + Claude Shannon (1949): Sampling-Theorem.
|
||||
|
||||
Beweis nicht klausurrelevant. Die Aussage und das visuelle Verständnis sind klausurrelevant.
|
||||
|
||||
Konsequenz:
|
||||
- 44,1 kHz Sample Rate → max. 22,05 kHz erfassbare Frequenz
|
||||
- Über 22 kHz wird *physisch nicht aufgenommen* (vor dem ADC sitzt ein Tiefpassfilter, der alles über 22 kHz abschneidet — anti-aliasing filter)
|
||||
- Studis hören diese hohen Frequenzen sowieso nicht (~20 kHz oben)
|
||||
|
||||
Anschluss zur nächsten Folie: warum hat die CD genau 44,1 kHz gewählt?
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
# Warum gerade 44,1 kHz?
|
||||
|
||||
**Menschliches Ohr hört bis ca. 20 kHz.**
|
||||
2 × 20 kHz = 40 kHz minimum für Nyquist.
|
||||
|
||||
**Plus 4,1 kHz Sicherheitsmarge** (Tiefpassfilter sind nicht perfekt).
|
||||
|
||||
**Plus historische PAL/NTSC-Kompatibilität:**
|
||||
44.100 Hz war exakt durch PAL- und NTSC-Video-Frame-Raten teilbar → CD-Master ließen sich auf den Video-Recordern jener Zeit produzieren.
|
||||
|
||||
<!--
|
||||
- Das Hörvermögen sinkt ab ~16 kHz mit dem Alter (Presbyakusis)
|
||||
- Tiefpassfilter im ADC braucht etwas Übergangsbreich — daher Sicherheitsmarge
|
||||
- 44.100 Hz ergibt sich aus: 245 × 6 × 30 (NTSC) und 245 × 8 × 25 (PAL).
|
||||
- Sony nutzte zu Beginn der CD-Entwicklung Video-Bandgeräte (Sony PCM-1600) zur digitalen Audio-Speicherung. Sample-Rate musste in NTSC + PAL-Frames passen.
|
||||
|
||||
Pointe für Studis: ein scheinbar willkürlicher Standard hat physiologische *und* historische Gründe. Technik-Geschichte ist kein Zufall.
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
<!-- _header: '' -->
|
||||
<!-- _footer: '' -->
|
||||
|
||||

|
||||
|
||||
<!--
|
||||
Aliasing als Phänomen — in Audio und Bild parallel.
|
||||
|
||||
- Audio: schriller 18-kHz-Ton, mit 22 kHz gesampelt → wird zu dumpfem 4-kHz-Brumm. Frequenz „klappt um".
|
||||
- Bild: feines Streifenmuster, in zu niedriger Auflösung gerendert → breite Moiré-Bänder erscheinen.
|
||||
|
||||
Beides ist dasselbe mathematische Phänomen: Sampling zu grob → falsche niedrige Frequenz erscheint.
|
||||
|
||||
Lebensweltanker:
|
||||
- Spotify Free 96 kbit/s → hohe Frequenzen werden weggeschnitten → kein Aliasing direkt, aber dieselbe Familie von Problemen.
|
||||
- Foto-Stroboskop / Wagenrad-Effekt im Video → klassisches Aliasing in der Zeit-Dimension.
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
<!-- _class: aufgabe -->
|
||||
|
||||
# Selbstlernen — Spotify-Bitrate vergleichen
|
||||
|
||||
Auf eurem Handy:
|
||||
1. Spotify öffnen, *Lieblings-Track laden*
|
||||
2. Audio-Qualität-Einstellung wechseln zwischen **niedrig (24 kbit/s)** und **sehr hoch (320 kbit/s)**
|
||||
3. Mit Kopfhörer auf **Höhen** achten (Becken, Zischlaute, „s"-Töne in Stimme)
|
||||
|
||||
**Was fällt auf?** Welche Frequenzen verschwinden zuerst?
|
||||
|
||||
<!--
|
||||
Pädagogisch: Studis sollen selbst hören, was Sample Rate / Bitrate praktisch bedeutet. Niedrige Bitrate = Tiefpassfilter hört früher auf zu übertragen → hohe Frequenzen weg → klingt „dumpf".
|
||||
|
||||
Spotify-Stufen (Premium):
|
||||
- niedrig: 24 kbit/s
|
||||
- normal: 96 kbit/s
|
||||
- hoch: 160 kbit/s
|
||||
- sehr hoch: 320 kbit/s
|
||||
|
||||
Ohne Premium: max. „normal".
|
||||
|
||||
Diskussion in der nächsten Vorlesungsrunde: was hat das mit MP3 zu tun? Antwort: alles. Kommt in Kap 2.
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
<!-- _class: aufgabe -->
|
||||
|
||||
# Selbstlernen — Audacity Sample-Rate-Vergleich
|
||||
|
||||
1. **Audacity** installieren (kostenlos, audacityteam.org)
|
||||
2. Eigene Stimme aufnehmen (5 s, irgendwas reinsprechen)
|
||||
3. Datei → Exportieren als WAV bei **8 kHz**, **22 kHz**, **44,1 kHz**
|
||||
4. Vergleichen: Größe der Datei + Klangqualität
|
||||
|
||||
**Beobachtung:** Größe wächst linear mit Sample Rate. Qualität auch.
|
||||
|
||||
<!--
|
||||
Diese Übung kann zuhause gemacht werden. Audacity ist FOSS.
|
||||
|
||||
- 5 Sek Mono bei 44,1 kHz × 16 bit = ~441.000 Byte ≈ 430 KB
|
||||
- Bei 8 kHz: 80.000 Byte ≈ 78 KB
|
||||
- Klang: bei 8 kHz dumpf, „Telefon-Stimme"
|
||||
|
||||
Anschlussfrage in der nächsten Folie: kann man eine Datei *kleiner* machen, ohne Sample Rate / Bittiefe zu reduzieren? Antwort: ja — durch Kompression. Das ist Kap 2.
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
<!-- _header: '' -->
|
||||
<!-- _footer: '' -->
|
||||
|
||||

|
||||
|
||||
<!--
|
||||
Zusammenfassung des Kapitels mit dem Bogen als rotem Faden.
|
||||
|
||||
Beide Strangs sind jetzt durch:
|
||||
- WELT → BYTE (links, pink): Sampling-Rate, Bittiefe + Quantisierung, Datenrate-Formel, Nyquist 2f, Aliasing & Moiré, 44,1 kHz als Anwendung.
|
||||
- BYTE → BEDEUTUNG (rechts, cyan): Bit · Byte · Hex, 256 Zustände, ASCII + UTF-8, Magic Number, KB vs KiB, Hex im Alltag.
|
||||
|
||||
Mitte: die Datei selbst — ein Strom von Byte, nichts als Zahlen.
|
||||
|
||||
Pointe: Eine Datei ist kein Mysterium. Es ist eine Reihe von Zahlen mit zwei Geschichten dran. Eine erzählt, woher die Zahlen kommen. Die andere, was sie bedeuten. Beide kennt ihr jetzt.
|
||||
|
||||
Anschluss zu Kap 2: in dieser Stunde haben wir die *unkomprimierten* Mengen gesehen (10 MB/min für CD-Audio). Im nächsten Kapitel: wie kommt man auf 1 MB/min und es klingt trotzdem fast gleich gut? Antwort: Kompression — und das ist ein eigenes Mysterium.
|
||||
-->
|
||||
@@ -0,0 +1,548 @@
|
||||
---
|
||||
marp: true
|
||||
theme: gaia
|
||||
paginate: true
|
||||
backgroundColor: #fff
|
||||
header: "Dateiformate, Schnittstellen, Speichermedien & Distributionswege (223015b)"
|
||||
footer: "Michael Czechowski – HdM Stuttgart – SoSe 2026"
|
||||
title: Kompression
|
||||
---
|
||||
|
||||
<style>
|
||||
:root {
|
||||
--color-foreground: #1a1a2e;
|
||||
--color-highlight: #1e5f8a;
|
||||
--color-dimmed: #4a4a6a;
|
||||
}
|
||||
section.invert { --color-foreground: #fff; }
|
||||
section { font-size: 1.7rem; }
|
||||
h1 { color: #1e5f8a; }
|
||||
section.invert h1 { color: #fff; }
|
||||
h2 { color: #1f2937; }
|
||||
pre {
|
||||
background: #0f0f23;
|
||||
color: #5fb3e4;
|
||||
border-radius: 8px;
|
||||
border-left: 3px solid #1e5f8a;
|
||||
}
|
||||
pre code { background: transparent; color: inherit; }
|
||||
code {
|
||||
background: #0f0f23;
|
||||
padding: 0.15em 0.4em;
|
||||
border-radius: 4px;
|
||||
font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
|
||||
}
|
||||
section code:not(.hljs) { color: #5fb3e4 !important; }
|
||||
section code.hljs { color: #f8f8f8 !important; }
|
||||
a { color: var(--color-highlight); }
|
||||
section.klausur {
|
||||
background: repeating-linear-gradient(
|
||||
135deg,
|
||||
#e3f2fd,
|
||||
#e3f2fd 40px,
|
||||
#fff 40px,
|
||||
#fff 80px
|
||||
) !important;
|
||||
}
|
||||
@media print {
|
||||
section.klausur { background: #e3f2fd !important; }
|
||||
}
|
||||
section.aufgabe { background: #e3f2fd !important; }
|
||||
section.aufgabe footer { display: none; }
|
||||
section.erklaerung :not(header),
|
||||
section.erklaerung :not(footer) { font-size: 1.1rem; }
|
||||
section.erklaerung h1 { font-size: 1.5rem; color: #1e5f8a; margin-bottom: 0.3rem; }
|
||||
section.erklaerung ul, section.erklaerung ol { font-size: 1.0rem; line-height: 1.4; }
|
||||
section.erklaerung p { font-size: 1.0rem; line-height: 1.4; }
|
||||
section.erklaerung table { font-size: 0.9rem; }
|
||||
</style>
|
||||
|
||||
<!-- _class: lead -->
|
||||
|
||||
# Kapitel 2
|
||||
## Kompression — Prinzipien und Pipelines
|
||||
|
||||
<!--
|
||||
Eine Stunde, eine Frage: *Wie machen wir Daten kleiner — und was darf dabei verloren gehen?*
|
||||
|
||||
Vorbereitung für Kapitel 3 (Inhalte: Bild/Audio/Video), wo wir die konkreten Pipelines durchgehen. Hier nur die zwei großen Prinzipien.
|
||||
|
||||
Anschluss an Kap 1: dort haben wir gesehen, wie groß unkomprimierte Audio-Daten werden (10 MB/Min für CD-Audio). Jetzt: wie kommt man auf 1 MB/Min und es klingt fast gleich?
|
||||
|
||||
Bogen: lossless (Redundanz raus) ↔ lossy (Irrelevanz raus).
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
<!-- _class: lead -->
|
||||
|
||||
# Daten sind unhandlich
|
||||
|
||||
<!--
|
||||
WhatsApp-Foto vom Wochenende: 200 KB.
|
||||
Dasselbe Bild aus der Kamera: 12 MB.
|
||||
|
||||
Spotify-Track: ~3 MB für 3 Minuten.
|
||||
Derselbe Track als Studio-WAV: ~30 MB.
|
||||
|
||||
ZIP einer Code-Sammlung: 1/3 der Originalgröße.
|
||||
|
||||
In allen drei Fällen ist die Datei *kleiner*. Aber bei manchen ist Information *weg* — und bei anderen nicht. Was ist der Unterschied?
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
# Foto-Größenschock
|
||||
|
||||
| Variante | Größe | Sichtbarer Unterschied? |
|
||||
|----------|------:|------------------------|
|
||||
| Original aus der iPhone-Kamera (HEIC) | 3,2 MB | — |
|
||||
| Foto via WhatsApp geteilt | 230 KB | kaum |
|
||||
| Instagram-Story (komprimiert) | 80 KB | minimal |
|
||||
| WhatsApp-Profilbild (klein) | 12 KB | sichtbar |
|
||||
|
||||
**Faktor: bis zu 270×.** *Wo geht die Information hin?*
|
||||
|
||||
<!--
|
||||
Diese Folie hängt das Konzept der Kompression an einem alltäglichen Beispiel auf.
|
||||
|
||||
- iPhone-Kamera: bereits H.265-komprimiert (HEIC) — aber als „Original" gehandelt.
|
||||
- WhatsApp: komprimiert nochmal, plus Resolution-Reduktion. Faktor ~13x.
|
||||
- Instagram-Story: noch aggressiver, optimiert für schnelles Laden.
|
||||
- Profilbild: max. ~96×96 Pixel, hoher JPEG-Komp-Faktor.
|
||||
|
||||
Pointe: alle vier sind „dasselbe Bild" — aber jede Stufe wirft *etwas* weg. Was genau? Und wer entscheidet, was weggeworfen wird? Antwort kommt mit dem Konzept lossy vs lossless.
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
<!-- _header: '' -->
|
||||
<!-- _footer: '' -->
|
||||
|
||||

|
||||
|
||||
<!--
|
||||
Das gleiche Phänomen in der Audio-Welt:
|
||||
- FLAC (lossless): 5,3 MB, jede Frequenz erhalten
|
||||
- MP3 (lossy, 128 kbit/s): 480 KB, hohe Frequenzen weggeworfen, Transienten geglättet
|
||||
|
||||
Wellenform-Vergleich macht es konkret:
|
||||
- Links (grün): detaillierte FLAC-Wellenform mit allen Spikes
|
||||
- Rechts (rot): MP3-Wellenform glatter, Detail-Information fehlt
|
||||
|
||||
Pointe für die Studis: auf dem Smartphone-Lautsprecher hört man den Unterschied meist nicht. Im Studio-Monitor mit Kopfhörer schon. MP3 wirft 91 % der Daten weg, die der Mensch im Alltag nicht vermisst.
|
||||
|
||||
→ Das ist „Lossy". Das Gegenteil ist „Lossless" (FLAC, ZIP).
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
<!-- _class: lead -->
|
||||
|
||||
# Erster Weg: Verlustfrei (Lossless)
|
||||
|
||||
<!--
|
||||
Prinzip: Redundanz raus, Information unverändert.
|
||||
|
||||
Beispiele:
|
||||
- ZIP-Archiv: gleiche Datei nach Entpacken
|
||||
- PNG-Bild: identisch zum Original
|
||||
- FLAC-Audio: identisch zur ursprünglichen Wellenform
|
||||
- TIFF, RAW (Camera-RAW): Foto im Rohformat
|
||||
|
||||
Trick: Wiederholungen, Muster, häufige Sequenzen werden kürzer geschrieben.
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
# Prinzip: Redundanz raus
|
||||
|
||||
Der Datenstrom enthält oft **Wiederholungen** — gleiche Pixel, gleiche Buchstaben, gleiche Frequenz-Häppchen.
|
||||
|
||||
Lossless-Kompression **erkennt** diese Redundanz und schreibt sie als **Verweis** kürzer.
|
||||
|
||||
**Umkehrbar:** beim Dekomprimieren wird die exakte Original-Datei wiederhergestellt.
|
||||
|
||||
<!--
|
||||
- Lossless ist ein Match-und-Verweise-Spiel.
|
||||
- Gegeben: 'AAAAAAAA' → kürzer als '8×A'.
|
||||
- Gegeben: ein Bild mit großem weißen Bereich → kürzer als 'Pixel 1-10000 sind weiß'.
|
||||
- Gegeben: ein Text mit häufigen Wörtern → 'der die das' bekommt kurze Codes (Huffman).
|
||||
|
||||
Wichtig zu verstehen: keine Information geht verloren. Aus der komprimierten Datei lässt sich das Original *bit-genau* wieder herstellen.
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
# RLE — Run-Length-Encoding
|
||||
|
||||
**Eine Bilderzeile in Schwarz/Weiß:**
|
||||
|
||||
```
|
||||
Original: AAAAA BBB CCCCCCCC AAAAAA
|
||||
(5×A, 3×B, 8×C, 6×A)
|
||||
|
||||
Kodiert: 5A 3B 8C 6A
|
||||
```
|
||||
|
||||
**22 Zeichen → 8 Zeichen.** Faktor: 2,75×.
|
||||
|
||||
Verlustfrei, weil ich aus `5A 3B 8C 6A` exakt `AAAAABBBCCCCCCCCAAAAAA` zurückbekomme.
|
||||
|
||||
<!--
|
||||
RLE = einfachster Lossless-Algorithmus, gut zum Verstehen des Prinzips am Whiteboard.
|
||||
|
||||
- Wirkt bei: Schwarz/Weiß-Bildern, Schwarz-auf-Weiß-Text, Faxnachrichten.
|
||||
- Wirkt NICHT bei: zufälligen Daten, schon-komprimierten Dateien (kein Muster zum Komprimieren).
|
||||
- TIFF und BMP nutzen optional RLE. Faxgeräte nutzen es exzessiv.
|
||||
|
||||
In der Praxis: moderne Lossless-Algorithmen wie Deflate (ZIP/PNG/gzip) und LZ77 sind viel cleverer als RLE — sie finden auch Wiederholungen auf weite Distanz im Datenstrom. Aber RLE zeigt das Prinzip in seiner einfachsten Form.
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
# Wo wird Lossless verwendet?
|
||||
|
||||
| Anwendung | Format | Warum verlustfrei? |
|
||||
|-----------|--------|---------------------|
|
||||
| Code-Repository, Backup | **ZIP**, **gzip**, **tar.gz** | Jedes Bit muss exakt zurück. |
|
||||
| Foto-Archiv (RAW) | **PNG**, **TIFF**, **RAW** | Nachbearbeitung soll alle Detail haben. |
|
||||
| Studio-Master-Track | **FLAC**, **WAV** | Für Mastering muss Originalqualität da sein. |
|
||||
| Logo-Grafiken | **PNG**, **SVG** | Scharfe Kanten brauchen Pixelgenauigkeit. |
|
||||
|
||||
**Faustregel:** Werkzeug → Lossless.
|
||||
|
||||
<!--
|
||||
Anschluss: wenn das Werkzeug ist, mit dem ich weiterarbeite (Foto bearbeiten, Code lesen, Audio mastern), brauche ich die Original-Daten. Lossless garantiert das.
|
||||
|
||||
PNG vs. JPEG-Konflikt: viele Studis erleben das beim Web-Hochladen. Logo als JPEG → unscharfe Ränder, weil JPEG für Fotos optimiert ist (große Farbflächen kosten wenig, Kanten erzeugen Artefakte). Logo als PNG → scharfe Ränder, weil PNG verlustfrei ist.
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||

|
||||
|
||||
# Original vs. Fälschung
|
||||
|
||||
Eine **echte Louis-Vuitton-Tasche** und ein perfekter Fake — auf einem Foto unterscheidbar?
|
||||
|
||||
Eine **lossless-komprimierte Datei** vs. das Original — bit-genau identisch.
|
||||
|
||||
**Bei Lossless gibt es keine Fälschung.** Die Kopie ist mathematisch das Original.
|
||||
|
||||
<!--
|
||||
Diese Analogie hat letztes Mal Verwirrung gestiftet (Original-Bag vs Fake). Der Punkt ist:
|
||||
|
||||
Bei echten Gegenständen (Tasche, Gemälde, Vinyl-Schallplatte) gibt es ein „echtes Original". Eine Fälschung sieht nur ähnlich aus, ist aber nicht das Original.
|
||||
|
||||
Bei digitalen Daten ist eine lossless-Kopie *exakt* gleich. Es gibt keinen Begriff von „Original" und „Kopie" — beide sind nur Folgen von Byte, und wenn diese Folgen Byte-für-Byte gleich sind, sind sie ununterscheidbar.
|
||||
|
||||
Das ist die digitale Kopier-Revolution. Vinyl → Kassette → Kassette = Generationsverlust. CD → Festplatte → USB-Stick = identisch.
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
<!-- _class: lead -->
|
||||
|
||||
# Zweiter Weg: Verlustbehaftet (Lossy)
|
||||
|
||||
<!--
|
||||
Prinzip: Irrelevanz raus. Nicht „weniger Wiederholung", sondern „Information, die der Mensch sowieso nicht wahrnimmt, wird gar nicht erst gespeichert".
|
||||
|
||||
Beispiele:
|
||||
- MP3, AAC, OPUS (Audio)
|
||||
- JPEG, WebP (Bild)
|
||||
- H.264, H.265, AV1 (Video)
|
||||
|
||||
Trick: Wahrnehmungsforschung — Psychoakustik (was hört der Mensch nicht?) und Psychovisualität (was sieht der Mensch nicht?).
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
# Prinzip: Irrelevanz raus
|
||||
|
||||
Was der Mensch **nicht wahrnehmen** kann, muss man **nicht speichern**.
|
||||
|
||||
**Lossy-Kompression** wirft genau diese Information weg.
|
||||
|
||||
**Nicht umkehrbar.** Was weg ist, kommt nie zurück. Aus einem MP3 wird nie wieder ein FLAC.
|
||||
|
||||
<!--
|
||||
Lossy hat einen anderen Charakter als Lossless:
|
||||
- Lossless: schaut auf die Daten („wo wiederholt sich was?")
|
||||
- Lossy: schaut auf den Empfänger („was nimmt er nicht wahr?")
|
||||
|
||||
Daraus folgt: Lossy braucht ein Modell vom Empfänger. Genau das liefert die Psychoakustik (Audio) und Psychovisualität (Bild).
|
||||
|
||||
Konsequenz: aus einem 128-kbit/s-MP3 lässt sich keine CD-Qualität wieder herstellen. Die Daten sind weg. Wenn jemand „Studio-Master 320 kbit/s" sagt: das war nie Studio-Master, das ist MP3 mit höherer Bitrate — die hohen Frequenzen sind trotzdem weg.
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
# Was nimmt der Mensch nicht wahr?
|
||||
|
||||
**Ohr (Audio):**
|
||||
- Töne unter ~20 Hz oder über ~20 kHz
|
||||
- Leise Töne in der Nähe lauter Töne (Maskierung)
|
||||
- Räumlich-zeitliche Maskierung (z.B. ~200 ms nach lautem Knall)
|
||||
|
||||
**Auge (Bild):**
|
||||
- Feine Farb-Detail (Chrominanz) abseits scharfer Helligkeitskanten
|
||||
- Kleinste Helligkeits-Differenzen (~1 Stufe in 256 ist unsichtbar)
|
||||
- Sehr feine Strukturen jenseits der Sehauflösung
|
||||
|
||||
Lossy-Algorithmen modellieren diese Wahrnehmungs-Grenzen — und werfen alles davor weg.
|
||||
|
||||
<!--
|
||||
Diese Folie zählt die Beschränkungen unserer Wahrnehmung auf — daraus ergibt sich, was Lossy weglassen darf.
|
||||
|
||||
Ohr-Phänomene werden in der Psychoakustik formalisiert. Die zwei wichtigsten:
|
||||
1. Frequenzmaskierung: lauter 1-kHz-Ton überdeckt benachbarte leise Töne bei 1,1 kHz.
|
||||
2. Zeitliche Maskierung: nach einem lauten Knall hört man ~200 ms keine leisen Geräusche.
|
||||
|
||||
Auge-Phänomene werden in der Psychovisualität formalisiert:
|
||||
1. Luminanz vor Chrominanz: Helligkeitsdetail ist scharf wichtig, Farbdetail darf grob sein.
|
||||
2. Kontrast-Empfindlichkeit: bei mittlerer Helligkeit sehen wir feiner als ganz hell oder ganz dunkel.
|
||||
|
||||
Die nächsten beiden Folien visualisieren diese Konzepte.
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
<!-- _header: '' -->
|
||||
<!-- _footer: '' -->
|
||||
|
||||

|
||||
|
||||
<!--
|
||||
Visualisierung der Maskierung:
|
||||
- Hörschwelle (orange gestrichelt): die untere Grenze unseres Hörens, je nach Frequenz unterschiedlich. Am empfindlichsten bei 1–4 kHz, weniger bei sehr tiefen und sehr hohen Frequenzen.
|
||||
- Lauter Ton bei 1 kHz, 90 dB („Masker"): macht die umliegenden Frequenzen unhörbar.
|
||||
- Maskierungs-Bereich (blau): in diesem Bereich werden Töne, die unter der gestrichelten Kurve liegen, durch den Masker überdeckt.
|
||||
- Grüne Punkte: hörbar, müssen kodiert werden.
|
||||
- Graue Punkte: nicht hörbar trotz „Vorhandenseins" → werden weggeworfen.
|
||||
|
||||
MP3-Pipeline:
|
||||
1. FFT — Audio in Frequenzen zerlegen
|
||||
2. Psychoakustisches Modell anwenden — berechne Maskierungsschwellen
|
||||
3. Quantisierung — alles unter Maskierungsschwelle wegwerfen
|
||||
4. Huffman-Coding — Rest verlustfrei komprimieren
|
||||
|
||||
Pointe: das alles passiert ohne dass der Mensch im normalen Hören etwas vermisst. ~90 % der Daten weg.
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
<!-- _header: '' -->
|
||||
<!-- _footer: '' -->
|
||||
|
||||

|
||||
|
||||
<!--
|
||||
Visualisierung Luminanz vs Chrominanz:
|
||||
- Links: 4:4:4 — jedes Pixel speichert Helligkeit (Y) + zwei Farb-Komponenten (Cb blau-differenz, Cr rot-differenz) in voller Auflösung.
|
||||
- Rechts: 4:2:0 — Y bleibt voll, Cb und Cr werden auf 1/4 reduziert (2×2 Pixel teilen sich einen Farbwert).
|
||||
- Beide Bilder sehen für das Auge identisch aus. Datenmenge halbiert.
|
||||
|
||||
JPEG, H.264, H.265, WebP, AVIF nutzen alle 4:2:0-Subsampling als Standard.
|
||||
|
||||
Anekdote: Würde man stattdessen die Luminanz halbieren (Y reduziert, Cb/Cr voll), würde das Bild sofort unscharf aussehen. Das Auge ist scharf für Helligkeitskanten — daher kein Spielraum dort.
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
# Wo wird Lossy verwendet?
|
||||
|
||||
| Anwendung | Format | Reduktion |
|
||||
|-----------|--------|-----------|
|
||||
| Musikstream (Spotify) | **MP3**, **AAC**, **OGG** | 10× |
|
||||
| Foto im Netz (Instagram) | **JPEG**, **WebP** | 10–30× |
|
||||
| Video (YouTube, Netflix) | **H.264**, **H.265**, **AV1** | 100–200× |
|
||||
| Sprachanruf (WhatsApp Call) | **OPUS**, **AMR** | 50× |
|
||||
|
||||
**Faustregel:** Konsum → Lossy.
|
||||
|
||||
<!--
|
||||
Wenn du etwas nur „konsumieren" (anschauen, anhören) willst — und nicht weiter bearbeiten — ist Lossy die richtige Wahl. Du sparst Speicher und Bandbreite, ohne dass der Konsum darunter leidet.
|
||||
|
||||
Sobald du bearbeiten, mastern, archivieren willst → Lossless.
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
# Vergleich: Lossless vs. Lossy
|
||||
|
||||
| Eigenschaft | Verlustfrei (Lossless) | Verlustbehaftet (Lossy) |
|
||||
|-------------|------------------------|--------------------------|
|
||||
| Was passiert? | Redundanz raus | Irrelevanz raus |
|
||||
| Umkehrbar? | Ja, bit-genau | Nein, nie wieder |
|
||||
| Trick | Wiederholungen kürzer kodieren | Wahrnehmung modellieren |
|
||||
| Typischer Faktor | 2× – 5× | 10× – 100× |
|
||||
| Anwendung | Archiv, Werkzeug, Code | Stream, Anzeige, Konsum |
|
||||
| Beispiele | ZIP · PNG · FLAC · RAW | MP3 · JPEG · H.264 · WebP |
|
||||
|
||||
<!--
|
||||
Klausurfähig: gegeben ein Anwendungsfall — soll Lossless oder Lossy verwendet werden? Mit Begründung.
|
||||
|
||||
Beispiele für Klausurfragen:
|
||||
- 4K-Stream auf Netflix → Lossy (H.265 oder AV1)
|
||||
- RAW-Datei aus der DSLR archivieren → Lossless (RAW selbst, ggf. ZIP)
|
||||
- Lecture-Capture-Aufzeichnung für Wiederverwendung → Lossless besser, aber Datenrate hoch
|
||||
- Logo-Datei für Print + Web → SVG (vektorgraphisch) oder PNG (lossless raster)
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
<!-- _header: '' -->
|
||||
<!-- _footer: '' -->
|
||||
|
||||

|
||||
|
||||
<!--
|
||||
Klassisches Bild aus Wikipedia: dieselbe Katze mit fortschreitender JPEG-Kompression.
|
||||
|
||||
- Ganz links: kaum komprimiert, hohe Qualität
|
||||
- Schritt für Schritt: mehr Artefakte, weniger Detail, Quantisierungs-Blöcke werden sichtbar
|
||||
- Ganz rechts: extreme Kompression, sichtbare 8×8-Pixel-Blöcke (DCT-Blöcke)
|
||||
|
||||
Die JPEG-Pipeline funktioniert in 8×8-Blöcken. Bei niedriger Qualität werden hohe Frequenzen innerhalb dieser Blöcke aggressiv quantisiert → die Blöcke werden sichtbar.
|
||||
|
||||
Studis erkennen das aus dem Alltag:
|
||||
- Mehrfach geforwardete WhatsApp-Bilder → JPEG-Generation-Loss
|
||||
- Screenshots in Office → manchmal als JPEG gespeichert → Schrift wird unscharf
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
# Kompressionsraten in der Praxis
|
||||
|
||||
| Inhalt | Roh | Komprimiert | Faktor |
|
||||
|--------|----:|------------:|-------:|
|
||||
| Foto (12 MP) | 36 MB RAW | 3,5 MB JPEG | ~10× |
|
||||
| Audio (30 s Stereo) | 5,3 MB WAV | 480 KB MP3 | ~11× |
|
||||
| Video (1 Min 4K) | 24 GB roh | 200 MB H.264 | ~120× |
|
||||
| Code-Repo (Java) | 15 MB Quellcode | 1,5 MB ZIP | ~10× |
|
||||
| Foto (Logo PNG) | 800 KB unkomp. | 80 KB PNG | ~10× |
|
||||
|
||||
Lossy bringt mehr — *aber Werkzeug muss roh bleiben.*
|
||||
|
||||
<!--
|
||||
Diese Folie liefert Größenordnungen für die häufigsten Kompressions-Szenarien. Studis sollen ein Bauchgefühl bekommen:
|
||||
|
||||
- Foto: roh ist 10× größer als JPEG
|
||||
- Audio: roh ist 10× größer als MP3
|
||||
- Video: roh ist 100× größer als H.264. Das ist der Grund, warum Streaming überhaupt funktioniert.
|
||||
- Code: ZIP komprimiert um 10× weil viele Wiederholungen (Imports, Whitespace, Standard-Bibliothek-Aufrufe).
|
||||
|
||||
In Kap 3 schauen wir uns die Pipelines an: WIE machen JPEG/MP3/H.264 das?
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
# Entscheidungsmatrix — wann nehme ich was?
|
||||
|
||||
| Szenario | Empfehlung | Begründung |
|
||||
|----------|------------|------------|
|
||||
| Foto-Archiv (DSLR) | **RAW** (lossless) | Nachbearbeitung muss alle Detail haben |
|
||||
| Foto im Web/Insta | **JPEG / WebP** (lossy) | Konsum, Bandbreite zählt |
|
||||
| Studio-Master | **FLAC / WAV** (lossless) | Master soll bit-genau bleiben |
|
||||
| Spotify-Track | **AAC / MP3** (lossy) | Konsum, Smartphone-Lautsprecher |
|
||||
| Code-Backup | **ZIP / tar.gz** (lossless) | Code muss exakt zurück |
|
||||
| Lecture-Video | **H.264** (lossy) | Konsum, Streaming |
|
||||
| Logo | **PNG / SVG** (lossless) | Scharfe Kanten brauchen Pixelgenauigkeit |
|
||||
|
||||
<!--
|
||||
Diese Matrix ist die zentrale Entscheidungshilfe. Vermitteln über Beispiele aus dem Studi-Alltag (Insta-Post, Spotify-Premium, GitHub-Repo, Vorlesungs-Aufnahme).
|
||||
|
||||
Pädagogisches Ziel: am Ende des Kapitels haben Studis ein Bauchgefühl, wann welche Kompression sinnvoll ist. Nicht „auswendig", sondern „begründen können".
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
<!-- _class: aufgabe -->
|
||||
|
||||
# Selbstlernen — ZIP-Test mit drei Dateitypen
|
||||
|
||||
Drei Dateien gleicher Originalgröße (~1 MB) zippen:
|
||||
|
||||
1. **Textdatei mit wiederholten Mustern** (z.B. ein Buch als TXT)
|
||||
2. **Unkomprimiertes Bitmap (BMP)** desselben Fotos
|
||||
3. **JPEG** desselben Fotos
|
||||
|
||||
**Vergleich:** Wie groß ist die ZIP-Datei in jedem Fall?
|
||||
|
||||
**Erwartung:** Textdatei wird klein (Wiederholungen), BMP wird klein (Farbflächen), JPEG bleibt fast gleich (schon komprimiert, keine Redundanz mehr).
|
||||
|
||||
<!--
|
||||
Diese Übung liefert die zentrale Aha-Erkenntnis ohne Mathematik:
|
||||
|
||||
**Schon-komprimierte Dateien lassen sich nicht weiter komprimieren.**
|
||||
|
||||
Warum? Weil Kompression die Redundanz herausnimmt. Eine bereits komprimierte Datei *hat keine Redundanz mehr*. Das wäre ein Verstoß gegen die Entropie-Grenze (Shannon), aber das brauchen die Studis nicht zu rechnen.
|
||||
|
||||
Erkenntnis: wer schon JPEG/MP3/H.264-Dateien hat, kann sie nicht „nochmal komprimieren". Wer Backup-ZIP über JPEG-Fotos macht: spart fast nichts.
|
||||
|
||||
~10 Min Selbstlernen. Ideal für ein Pärchen oder als Hausaufgabe.
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
# Warum ZIP auf JPEG nicht mehr komprimiert
|
||||
|
||||
**JPEG ist bereits maximal lossless-komprimiert.**
|
||||
|
||||
Die JPEG-Pipeline endet mit **Huffman-Coding** — derselbe Trick wie in ZIP.
|
||||
|
||||
Was ZIP machen würde (Wiederholungen finden, Häufigkeiten kürzer kodieren), hat JPEG schon getan.
|
||||
|
||||
**Resultat:** ZIP einer JPEG-Datei ist nur ~1 % kleiner. *Manchmal sogar größer* (durch ZIP-Header-Overhead).
|
||||
|
||||
<!--
|
||||
Pädagogisches Ziel: Studis verstehen, warum „Doppel-Kompression" nichts bringt.
|
||||
|
||||
Konkret:
|
||||
- JPEG-Pipeline = lossy + Huffman (lossless)
|
||||
- MP3-Pipeline = lossy + Huffman (lossless)
|
||||
- H.264-Pipeline = lossy + CABAC/Huffman (lossless)
|
||||
|
||||
In allen Fällen endet die Pipeline mit einem optimal-lossless-Schritt. Ein zusätzliches ZIP findet keine Wiederholungen mehr.
|
||||
|
||||
Folgerung: für gemischte Backups ist ZIP trotzdem nützlich — schon-komprimierte Dateien bleiben gleich, unkomprimierte werden kleiner. „Du verlierst nichts."
|
||||
|
||||
Übergang zu Kap 3: jetzt schauen wir uns die konkreten Lossy-Pipelines an. Wie genau funktioniert JPEG? Was passiert in MP3? Wie komprimiert H.264 Video?
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
<!-- _header: '' -->
|
||||
<!-- _footer: '' -->
|
||||
|
||||

|
||||
|
||||
<!--
|
||||
Zusammenfassung:
|
||||
|
||||
Zwei Wege, ein Ziel: Daten kleiner machen.
|
||||
|
||||
Verlustfrei (Lossless):
|
||||
- Was: Redundanz raus
|
||||
- Umkehrbar: ja
|
||||
- Verfahren: RLE, Huffman, Deflate
|
||||
- Formate: ZIP, PNG, FLAC, RAW
|
||||
- Faktor: 2× – 5×
|
||||
|
||||
Verlustbehaftet (Lossy):
|
||||
- Was: Irrelevanz raus
|
||||
- Umkehrbar: nein
|
||||
- Trick: Psychoakustik (Audio) / Psychovisualität (Bild)
|
||||
- Formate: MP3, JPEG, H.264, WebP
|
||||
- Faktor: 10× – 100×
|
||||
|
||||
Entscheidungsmatrix:
|
||||
- Archiv/Code → Lossless
|
||||
- Stream/Anzeige → Lossy
|
||||
|
||||
Faustregel: Werkzeug = Lossless. Konsum = Lossy.
|
||||
|
||||
In Kap 3 schauen wir uns die Pipelines konkret an (JPEG, MP3, H.264) — also wie ein Lossy-Algorithmus überhaupt entscheidet, was wegzuwerfen ist.
|
||||
-->
|
||||
@@ -0,0 +1,987 @@
|
||||
---
|
||||
marp: true
|
||||
theme: gaia
|
||||
paginate: true
|
||||
backgroundColor: #fff
|
||||
header: "Dateiformate, Schnittstellen, Speichermedien & Distributionswege (223015b)"
|
||||
footer: "Michael Czechowski – HdM Stuttgart – SoSe 2026"
|
||||
title: Inhalte — Bild, Audio, Video
|
||||
---
|
||||
|
||||
<style>
|
||||
:root {
|
||||
--color-foreground: #1a1a2e;
|
||||
--color-highlight: #1e5f8a;
|
||||
--color-dimmed: #4a4a6a;
|
||||
}
|
||||
section.invert { --color-foreground: #fff; }
|
||||
section { font-size: 1.7rem; }
|
||||
h1 { color: #1e5f8a; }
|
||||
section.invert h1 { color: #fff; }
|
||||
h2 { color: #1f2937; }
|
||||
pre {
|
||||
background: #0f0f23;
|
||||
color: #5fb3e4;
|
||||
border-radius: 8px;
|
||||
border-left: 3px solid #1e5f8a;
|
||||
}
|
||||
pre code { background: transparent; color: inherit; }
|
||||
code {
|
||||
background: #0f0f23;
|
||||
padding: 0.15em 0.4em;
|
||||
border-radius: 4px;
|
||||
font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
|
||||
}
|
||||
section code:not(.hljs) { color: #5fb3e4 !important; }
|
||||
section code.hljs { color: #f8f8f8 !important; }
|
||||
a { color: var(--color-highlight); }
|
||||
section.klausur {
|
||||
background: repeating-linear-gradient(
|
||||
135deg,
|
||||
#e3f2fd,
|
||||
#e3f2fd 40px,
|
||||
#fff 40px,
|
||||
#fff 80px
|
||||
) !important;
|
||||
}
|
||||
@media print {
|
||||
section.klausur { background: #e3f2fd !important; }
|
||||
}
|
||||
section.aufgabe { background: #e3f2fd !important; }
|
||||
section.aufgabe footer { display: none; }
|
||||
section.erklaerung :not(header),
|
||||
section.erklaerung :not(footer) { font-size: 1.1rem; }
|
||||
section.erklaerung h1 { font-size: 1.5rem; color: #1e5f8a; margin-bottom: 0.3rem; }
|
||||
section.erklaerung ul, section.erklaerung ol { font-size: 1.0rem; line-height: 1.4; }
|
||||
section.erklaerung p { font-size: 1.0rem; line-height: 1.4; }
|
||||
section.erklaerung table { font-size: 0.9rem; }
|
||||
</style>
|
||||
|
||||
<!-- _class: lead -->
|
||||
|
||||
# Kapitel 3
|
||||
## Inhalte — Bild, Audio, Video
|
||||
|
||||
<!--
|
||||
Längere Sitzung (ggf. 2 Termine): drei Modalitäten, drei Pipelines, drei Format-Politiken.
|
||||
|
||||
Anschluss an Kap 2: dort haben wir Lossy-Prinzip kennengelernt (Psychoakustik, Psychovisualität). Hier zeigen wir die konkreten Pipelines — wie genau macht JPEG/MP3/H.264 das?
|
||||
|
||||
Bogen:
|
||||
1. Bilder (Raster vs Vektor, JPEG-Pipeline, weitere Formate)
|
||||
2. Audio (MP3-Pipeline-Recap, Format-Wahl)
|
||||
3. Video (Container ≠ Codec, I/P/B-Frames, H.264 vs H.265 vs AV1)
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
<!-- _class: lead -->
|
||||
|
||||
# Drei Modalitäten, ein Prinzip
|
||||
|
||||
<!--
|
||||
Anker im Alltag: Instagram, Spotify, YouTube. Was tun diese Plattformen?
|
||||
- Instagram: zeigt Fotos (Bild)
|
||||
- Spotify: spielt Musik (Audio)
|
||||
- YouTube: streamt Video (Bild + Audio + Zeit)
|
||||
|
||||
Alle drei nutzen lossy Kompression. Alle drei nutzen Wahrnehmungs-Lücken. Aber die Pipelines sind verschieden.
|
||||
|
||||
Vorgriff: am Ende dieses Kapitels werdet ihr wissen, was in einer JPEG-Datei, in einer MP3-Datei und in einer MP4-Datei wirklich drinsteckt.
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
<!-- _header: '' -->
|
||||
<!-- _footer: '' -->
|
||||
|
||||

|
||||
|
||||
<!--
|
||||
Tabellarische Übersicht zum Reduktions-Hebel pro Modalität:
|
||||
- Bild (12-MP-Foto): RAW 36 MB → JPEG Q90 4 MB → JPEG Q50 800 KB (Faktor ×45)
|
||||
- Audio (30 s Stereo): WAV 5,3 MB → MP3 192 kbit/s 720 KB → MP3 64 kbit/s 240 KB (Faktor ×22)
|
||||
- Video (30 s 4K 30fps): Roh 12 GB → H.264 25 Mbit/s 94 MB → H.265 12 Mbit/s 45 MB (Faktor ×270)
|
||||
|
||||
Jede Reduktion nutzt eine andere Wahrnehmungs-Lücke:
|
||||
- Bild → geringere Farbschärfe (Chrominanz vs Luminanz)
|
||||
- Audio → Maskierung (lauter Ton überdeckt leise)
|
||||
- Video → Frame-zu-Frame-Ähnlichkeit (Inter-Frame)
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
<!-- _class: lead -->
|
||||
|
||||
# Sub-Sektion A: Bilder
|
||||
|
||||
<!--
|
||||
Reihenfolge:
|
||||
1. Raster vs Vektor (Konzept)
|
||||
2. JPEG-Pipeline (6 Schritte)
|
||||
3. Andere Formate (PNG, GIF, WebP, AVIF, SVG)
|
||||
4. Format-Wahl-Matrix
|
||||
5. Patent-Politik (warum WebP > JPEG XL)
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
<!-- _header: '' -->
|
||||
<!-- _footer: '' -->
|
||||
|
||||

|
||||
|
||||
<!--
|
||||
Zwei fundamentale Bild-Modelle:
|
||||
|
||||
**Raster:** Bild = Gitter aus Pixel-Farbwerten. Jede Position fest belegt.
|
||||
- Beispiele: PNG, JPEG, GIF, WebP, RAW
|
||||
- Vorteil: kann Fotos darstellen (kontinuierliche Tonwerte)
|
||||
- Nachteil: feste Auflösung. Beim Vergrößern wird es pixelig.
|
||||
|
||||
**Vektor:** Bild = mathematische Anweisungen ("Punkt 30,110 → Punkt 90,170 → Punkt 250,30, Strichbreite 14").
|
||||
- Beispiele: SVG, PDF, Schriftarten, Adobe Illustrator
|
||||
- Vorteil: scharf bei jeder Größe (wird neu berechnet)
|
||||
- Nachteil: kann keine Fotos (keine analytischen Beschreibungen für Megapixel von Pixeln)
|
||||
|
||||
Anwendung: Logo → Vektor. Foto → Raster. Icon → Vektor.
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
# Raster vs. Vektor
|
||||
|
||||
| | Raster | Vektor |
|
||||
|--|--------|--------|
|
||||
| Was | Gitter aus Pixel-Werten | Mathematische Anweisungen |
|
||||
| Speicher | wächst mit Auflösung | wächst mit Komplexität |
|
||||
| Skalierung | pixelig beim Zoom | scharf bei jeder Größe |
|
||||
| Geeignet für | Fotos, Screenshots | Logos, Icons, Schrift |
|
||||
| Formate | PNG · JPEG · GIF · WebP | SVG · PDF · Schriftarten |
|
||||
|
||||
<!--
|
||||
Klausurfähig. Geben Sie:
|
||||
- ein Format zu jeder Spalte
|
||||
- ein Anwendungsbeispiel zu jeder Spalte
|
||||
- begründen warum Vektor bei Logos und Raster bei Fotos
|
||||
|
||||
Trick-Frage: kann man ein Foto in SVG speichern? Theoretisch ja (mit Millionen winziger Rechtecke), praktisch nein — wird dann viel größer als JPEG.
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
<!-- _class: lead -->
|
||||
|
||||
# JPEG — das Foto-Workhorse seit 1992
|
||||
|
||||
<!--
|
||||
JPEG = Joint Photographic Experts Group, Standard seit 1992.
|
||||
|
||||
Bis heute das dominierende Foto-Format im Web (~70 % aller Web-Bilder). Warum?
|
||||
- Sehr gute Kompression bei akzeptabler Qualität
|
||||
- Patentfrei seit 2017 (vorher schon weitgehend lizenzfrei)
|
||||
- Universelle Unterstützung in Browsern, OS, Druck
|
||||
|
||||
Aber: lossy. Jede Speicherung erzeugt Verlust. Wer ein JPEG immer wieder bearbeitet und speichert, baut Artefakte auf (Generation Loss).
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
<!-- _header: '' -->
|
||||
<!-- _footer: '' -->
|
||||
|
||||

|
||||
|
||||
<!--
|
||||
JPEG-Pipeline in 6 Schritten:
|
||||
|
||||
1. Farbraumkonversion: RGB → Y'CbCr. Helligkeit (Y) von Farbe (Cb, Cr) trennen.
|
||||
2. Chroma-Subsampling 4:2:0: Cb und Cr auf 1/4 reduziert (Auge sieht Farbdetail nicht so scharf). LOSSY.
|
||||
3. 8×8-Blöcke: Bild in kleine Kacheln teilen, jeder Block einzeln behandelt.
|
||||
4. DCT (Diskrete Kosinus-Transformation): jeden Block in Frequenz-Komponenten zerlegen. Häufige Helligkeitsmuster werden sichtbar.
|
||||
5. Quantisierung: hohe Frequenzen (Detail) werden gerundet. HIER passiert die hauptsächliche Lossy-Reduktion. Je niedriger die Qualitätsstufe, desto aggressiver.
|
||||
6. Huffman-Coding: lossless. Häufige Werte bekommen kurze Codes, seltene Werte lange Codes.
|
||||
|
||||
Resultat: Foto-Datei ist 10× kleiner als RAW, sieht für das Auge fast identisch aus.
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
# Schritt 1: RGB → Y'CbCr
|
||||
|
||||

|
||||
|
||||
**Trick:** Helligkeit von Farbe **trennen**.
|
||||
|
||||
* **Y** = Luminanz (Helligkeit)
|
||||
* **Cb** = blau-gelb-Differenz
|
||||
* **Cr** = rot-grün-Differenz
|
||||
|
||||
Auge sieht **Y scharf**, **Cb/Cr grob.** Beide werden unabhängig komprimiert.
|
||||
|
||||
<!--
|
||||
Diese Trennung ist verlustfrei — mathematische Umrechnung zwischen Farbräumen.
|
||||
|
||||
Y'CbCr ist auch der Farbraum, in dem Fernseh- und Video-Signale übertragen werden (BT.601, BT.709). Hat historische Gründe (kompatibel mit Schwarz-Weiß-TV: Y alleine = SW-Bild).
|
||||
|
||||
Nach diesem Schritt: keine Reduktion, aber Vorbereitung für Schritt 2.
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
# Schritt 2: Chroma-Subsampling (4:2:0)
|
||||
|
||||

|
||||
|
||||
**Y bleibt voll.** **Cb und Cr werden auf 1/4 reduziert** (2×2 Pixel teilen sich einen Farbwert).
|
||||
|
||||
- 4:4:4 = keine Reduktion
|
||||
- 4:2:2 = horizontal halbiert
|
||||
- **4:2:0 = JPEG-Standard, beide Richtungen halbiert**
|
||||
|
||||
**Lossy.** Speichermenge halbiert, sichtbarer Unterschied: null.
|
||||
|
||||
<!--
|
||||
4:2:0-Notation kommt von alten Video-Standards. Erste Zahl = relative Y-Sample-Anzahl, zweite = Cb-Samples in Zeile 1, dritte = in Zeile 2.
|
||||
|
||||
Konsequenz: Bilder mit sehr feinen Farbkanten (z.B. roter Text auf grünem Hintergrund) können in 4:2:0-JPEG sichtbare Farbsäume haben. Deshalb ist JPEG für solche Inhalte schlechter als PNG.
|
||||
|
||||
Faustregel: 4:2:0 ist OK für Fotos. Für Text-Grafiken und Screenshots eher PNG nehmen.
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
# Schritt 3 & 4: 8×8 Blöcke + DCT
|
||||
|
||||
Das Bild wird in **8×8-Pixel-Blöcke** zerlegt. *Jeder Block einzeln* weiterverarbeitet.
|
||||
|
||||
**DCT** (Diskrete Kosinus-Transformation) zerlegt jeden Block in **Frequenz-Komponenten:**
|
||||
|
||||
- niedrige Frequenz = grobe Helligkeitsänderungen (Hintergrund)
|
||||
- hohe Frequenz = feines Detail (Kanten, Rauschen)
|
||||
|
||||
Beide Schritte sind **verlustfrei**. Sie bereiten Schritt 5 vor.
|
||||
|
||||
<!--
|
||||
Warum 8×8? Trade-off:
|
||||
- Größere Blöcke (z.B. 16×16): bessere Kompression, aber kostspieliger zu berechnen
|
||||
- 8×8 wurde 1992 als guter Kompromiss gewählt; passt zu der damaligen Hardware
|
||||
|
||||
DCT-Aha:
|
||||
- Ein Block, der nur eine Farbe ist → eine Frequenz-Komponente (Mittelwert)
|
||||
- Ein Block mit feinen Streifen → viele hohe Frequenzen
|
||||
- Die meisten realen Bildblöcke konzentrieren ihre Energie in den niedrigen Frequenzen
|
||||
|
||||
Pointe: nach DCT „sieht" man, was im Block wichtig ist. Schritt 5 wirft die unwichtigen hohen Frequenzen weg.
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
# Schritt 5: Quantisierung — *hier* wird weggeworfen
|
||||
|
||||
Jeder DCT-Koeffizient wird durch einen Wert aus der **Quantisierungs-Tabelle** geteilt und gerundet.
|
||||
|
||||
**Niedrige Frequenzen** (wichtig): kleine Tabellen-Werte → wenig Rundung → bleiben erhalten.
|
||||
**Hohe Frequenzen** (Detail): große Tabellen-Werte → starke Rundung → werden Null.
|
||||
|
||||
**Quality-Slider 100 → 1** ist nichts anderes als „aggressiver multiplizieren".
|
||||
|
||||
<!--
|
||||
DCT-Koeffizienten in einem Block sehen typisch so aus:
|
||||
[ 200, 50, 20, 5, 2, 1, 0, 0]
|
||||
[ 60, 15, 8, 3, 1, 0, 0, 0]
|
||||
[ 25, 8, 4, 1, 0, 0, 0, 0]
|
||||
[ ...
|
||||
|
||||
Quantisierungs-Tabelle (Q90, ähnlich JPEG-Standard):
|
||||
[ 3, 2, 2, 4, 6, 10, 13, 16]
|
||||
[ 2, 2, 3, 4, 7, 15, 16, 14]
|
||||
...
|
||||
|
||||
Division + Rundung:
|
||||
[ 67, 25, 10, 1, 0, 0, 0, 0]
|
||||
[ 30, 8, 3, 1, 0, 0, 0, 0]
|
||||
[ 8, 4, 1, 0, 0, 0, 0, 0]
|
||||
|
||||
Die hohen Frequenzen sind Null geworden. Die NULL-Sequenzen werden in Schritt 6 sehr effizient huffman-kodiert.
|
||||
|
||||
Bei Quality 50 oder 10 sind die Werte in der Tabelle viel höher → viel mehr Nullen → kleinere Datei, aber sichtbare Artefakte (8x8-Blöcke werden sichtbar).
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
# Schritt 6: Huffman-Coding (verlustfrei)
|
||||
|
||||
Die quantisierten Koeffizienten sind voller **Nullen** (die hohen Frequenzen).
|
||||
|
||||
**Huffman:** häufige Werte (= Nullen) bekommen **kurze Codes**, seltene Werte lange Codes.
|
||||
|
||||
Plus **Zigzag-Scan + RLE**: lange Null-Sequenzen → ein einziges Symbol.
|
||||
|
||||
**Resultat:** finale JPEG-Datei. Verlustfrei aus quantisierten Werten rekonstruierbar.
|
||||
|
||||
<!--
|
||||
Huffman-Coding ist ein klassisches lossless-Verfahren, das auf der Häufigkeitsverteilung beruht. Es bezeichnet das gleiche Prinzip wie in ZIP — also kompatibel mit Kap 2.
|
||||
|
||||
Zigzag: die 8×8-Koeffizienten werden in Zigzag-Reihenfolge gelesen (von niedriger zu hoher Frequenz). Dadurch landen alle Nullen am Ende → können als „Rest ist Null" kodiert werden.
|
||||
|
||||
Konsequenz: nach Schritt 6 ist die Pipeline fertig. Die JPEG-Datei kann gespeichert/gesendet werden. Beim Anzeigen läuft die Pipeline rückwärts.
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
# Memo: Die 6 JPEG-Schritte
|
||||
|
||||
| # | Schritt | Lossless / Lossy |
|
||||
|---|---------|------------------|
|
||||
| 1 | RGB → Y'CbCr (Farbraum) | Lossless |
|
||||
| 2 | Chroma-Subsampling 4:2:0 | **Lossy** |
|
||||
| 3 | 8×8 Blöcke | Lossless |
|
||||
| 4 | DCT (Frequenz-Zerlegung) | Lossless |
|
||||
| 5 | Quantisierung | **Lossy** (Haupt-Reduktion) |
|
||||
| 6 | Huffman + Zigzag + RLE | Lossless |
|
||||
|
||||
Nur **2** der 6 Schritte verlieren Information.
|
||||
|
||||
<!--
|
||||
Klausurfähig. Sechs Schritte. Reihenfolge wichtig. Lossy/Lossless-Status pro Schritt wichtig.
|
||||
|
||||
Eselsbrücke: „Farb-Sub-Block-DCT-Quant-Huff" → F-S-B-D-Q-H.
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
<!-- _header: '' -->
|
||||
<!-- _footer: '' -->
|
||||
|
||||

|
||||
|
||||
<!--
|
||||
Wikipedia-Bild: dieselbe Katze, fortschreitende JPEG-Kompression.
|
||||
|
||||
Links: kaum komprimiert (Quality ~100).
|
||||
Mitte: mittlere Quality (~50).
|
||||
Rechts: extreme Kompression (Quality ~10) → 8×8-Blöcke sichtbar, Farbsäume, Detail-Verlust.
|
||||
|
||||
Studis erkennen das aus dem Alltag:
|
||||
- WhatsApp-Bilder, die durch viele Hände gingen → JPEG-Generation-Loss
|
||||
- Screenshots, die als JPEG gespeichert wurden → unscharfe Schrift
|
||||
- Instagram-Posts, die mehrfach re-uploaded wurden → wächsende Artefakte
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
<!-- _class: lead -->
|
||||
|
||||
# Andere Bildformate
|
||||
|
||||
<!--
|
||||
JPEG ist der König — aber für bestimmte Anwendungen gibt es bessere Alternativen.
|
||||
|
||||
Übersicht:
|
||||
- PNG: lossless, mit Transparenz
|
||||
- GIF: alt, animiert, max. 256 Farben
|
||||
- WebP: Googles JPEG-Killer
|
||||
- AVIF: AV1-basiert, noch effizienter
|
||||
- SVG: vektor, skalierbar
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
# Bildformate im Überblick
|
||||
|
||||
| Format | Typ | Loss | Transparenz | Animation | Stärke |
|
||||
|--------|-----|------|------------|-----------|--------|
|
||||
| **JPEG** | Raster | Lossy | ✗ | ✗ | Fotos |
|
||||
| **PNG** | Raster | Lossless | ✓ | ✗ | Logos, Screenshots |
|
||||
| **GIF** | Raster | Lossless | 1-bit | ✓ | Memes, Sticker |
|
||||
| **WebP** | Raster | beides | ✓ | ✓ | Modern Web |
|
||||
| **AVIF** | Raster | beides | ✓ | ✓ | Höchste Qualität bei kleinster Datei |
|
||||
| **SVG** | Vektor | Lossless | ✓ | ✓ (mit JS/CSS) | Logos, Icons |
|
||||
|
||||
<!--
|
||||
- PNG: ältester moderner Lossless-Standard, seit 1996 (als Patent-freier GIF-Ersatz entstanden).
|
||||
- GIF: 1987, eingeschränkt auf 256 Farben, animationsfähig — daher heute der Meme-Veteran.
|
||||
- WebP: Google 2010, soll JPEG ersetzen. Ist 25-35% kleiner als JPEG bei gleicher Qualität.
|
||||
- AVIF: 2019, basiert auf AV1-Video-Codec. ~50% kleiner als JPEG, ~20% kleiner als WebP.
|
||||
- SVG: 2001, das einzige Vektor-Format hier. Skaliert ohne Verlust.
|
||||
|
||||
Quality-Bewusstsein: SVG ist nicht „Konkurrenz" zu Raster-Formaten — sie lösen verschiedene Probleme.
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
# Wann welches Bildformat?
|
||||
|
||||
| Anwendung | Format | Warum |
|
||||
|-----------|--------|-------|
|
||||
| Foto im Web (Insta, News) | **JPEG** oder **WebP** | klein, Foto-optimiert |
|
||||
| Foto-Archiv (RAW) | **RAW**, **TIFF**, **DNG** | nichts verlieren |
|
||||
| Logo, Icon (skalierbar) | **SVG** | wird neu berechnet |
|
||||
| Logo als Raster | **PNG** | Transparenz + scharfe Kanten |
|
||||
| Screenshot mit Text | **PNG** | scharfe Buchstaben |
|
||||
| Animiertes Sticker | **GIF** oder **WebP** | beide animierbar |
|
||||
| Foto in höchster Modern-Qualität | **AVIF** oder **WebP** | bessere Kompression als JPEG |
|
||||
|
||||
<!--
|
||||
Klausurfähig: gegeben ein Anwendungsfall, welches Format und warum?
|
||||
|
||||
Sub-Frage: was schief geht, wenn ich JPEG für ein Logo nehme? → unscharfe Ränder + sichtbare Artefakte.
|
||||
|
||||
Sub-Frage: warum nicht immer AVIF? → Browser-Support (manche ältere Browser können AVIF noch nicht), Tool-Kompatibilität, Workflow-Etablierung.
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
# Patent-Politik — warum WebP, nicht JPEG XL?
|
||||
|
||||
**WebP** (Google, 2010): lizenzfrei. Chrome supportet von Anfang an. Heute überall.
|
||||
|
||||
**JPEG XL** (2021): technisch überlegen — bessere Kompression, lossless+lossy in einem Format, JPEG-kompatibel. Sollte JPEG ablösen.
|
||||
|
||||
**Google entfernte Chrome-Support für JPEG XL im Februar 2023.** Begründung: „nicht genug ökosystem-traction". Inoffiziell: WebP ist Google's eigenes Format.
|
||||
|
||||
→ **Patent-Politik schlägt technische Überlegenheit.** Wer den Browser kontrolliert, kontrolliert das Format.
|
||||
|
||||
<!--
|
||||
Diese Geschichte zeigt: die Wahl von Bildformaten ist nicht nur technisch, sondern politisch.
|
||||
|
||||
JPEG XL hatte alles für sich:
|
||||
- Bessere Lossy-Kompression als JPEG, WebP, AVIF
|
||||
- Bessere Lossless-Kompression als PNG
|
||||
- Erlaubt lossless-Konvertierung von altem JPEG (=> zukunftssicher)
|
||||
- Patentfrei
|
||||
|
||||
Aber: Google deklarierte 2023, Chrome supportet JPEG XL nicht. Damit war das Format faktisch tot — weil >70 % aller Browser Chrome-basiert sind.
|
||||
|
||||
Bittersüße Lektion: technische Standards setzen sich nicht durch Verdienst durch, sondern durch Marktmacht. AVIF (auch Google) bleibt — JPEG XL nicht.
|
||||
|
||||
Apple supportet JPEG XL ironischerweise in macOS Sonoma + Safari 17 (2023). Ein seltener Fall, wo Apple offener ist als Google.
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
<!-- _class: lead -->
|
||||
|
||||
# Sub-Sektion B: Audio
|
||||
|
||||
<!--
|
||||
Audio ist kürzer als Bilder, weil wir die Grundlagen (Sampling, Bittiefe, Datenrate, Nyquist) bereits in Kap 1 hatten. Hier nur:
|
||||
- Recap Sampling + Bittiefe
|
||||
- MP3-Trick konkret (Maskierung)
|
||||
- Bitrate-Stufen verstehen
|
||||
- Format-Wahl-Matrix
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
# Sampling + Bittiefe — Recap aus Kap 1
|
||||
|
||||
**Sampling Rate** (Hz): wie oft messen wir pro Sekunde.
|
||||
**Bittiefe** (bit): wie fein jede Messung.
|
||||
**Datenrate** = Sample Rate × Bittiefe × Kanäle.
|
||||
|
||||
**CD-Audio:** 44,1 kHz × 16 bit × 2 = **1,4 Mbit/s** → ~10 MB/Min.
|
||||
|
||||
**Wir wollen:** ~1 MB/Min (10× kleiner). *Wie?*
|
||||
|
||||
<!--
|
||||
Anschluss zu Kap 1 (Nyquist): unkomprimierte Audio ist 10 MB/Min. Streaming geht aber mit 1 MB/Min. Lösung: MP3 (oder AAC, OPUS).
|
||||
|
||||
Diese Folie ist nur Recap. Der eigentliche Inhalt kommt nächste Folie.
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
<!-- _header: '' -->
|
||||
<!-- _footer: '' -->
|
||||
|
||||

|
||||
|
||||
<!--
|
||||
Erinnerung aus Kap 2: Maskierung.
|
||||
|
||||
Ein lauter Ton (Masker) macht in seiner Frequenz-Umgebung leise Töne unhörbar.
|
||||
|
||||
MP3-Pipeline:
|
||||
1. Audio in 32 Frequenz-Bänder unterteilen (Filterbank)
|
||||
2. Psychoakustisches Modell anwenden — pro Band: was ist hörbar?
|
||||
3. Quantisierung — nicht-hörbares wegwerfen
|
||||
4. Huffman-Coding der Rest-Daten
|
||||
|
||||
Pointe: typischerweise 90 % der Daten weggeworfen, ohne dass im Alltag etwas vermisst wird.
|
||||
|
||||
Die Pipeline selbst ist mathematisch komplexer als JPEG (echte Filterbank statt einfacher DCT), aber das Prinzip ist gleich:
|
||||
- Wahrnehmungs-Modell
|
||||
- Quantisierung (lossy)
|
||||
- Huffman (lossless)
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
# Bitrate — der Qualitäts-Knopf
|
||||
|
||||
| Bitrate | Anwendung | Hörbar? |
|
||||
|---------|-----------|---------|
|
||||
| **64 kbit/s** | Sprachnachricht WhatsApp | dumpf, hörbar schlechter |
|
||||
| **128 kbit/s** | YouTube-Audio, frühe MP3s | mittel, viele hören Unterschied |
|
||||
| **192 kbit/s** | Spotify Free | gut für Alltag |
|
||||
| **320 kbit/s** | Spotify Premium „sehr hoch" | praktisch CD-Qualität |
|
||||
| **1 411 kbit/s** | CD (unkomprimiert) | Referenz |
|
||||
|
||||
**Faustregel:** je höher die Bitrate, desto mehr Detail bleibt erhalten — *aber Diminishing Returns ab ~256 kbit/s.*
|
||||
|
||||
<!--
|
||||
Spotify-Premium-Stufen:
|
||||
- Niedrig: 24 kbit/s (selten benutzt)
|
||||
- Normal: 96 kbit/s
|
||||
- Hoch: 160 kbit/s
|
||||
- Sehr hoch: 320 kbit/s (nur Premium)
|
||||
|
||||
Spotify HiFi (lossless 1411 kbit/s): seit Jahren angekündigt, immer wieder verschoben.
|
||||
|
||||
Pointe: für die meisten Anwendungen reicht 192 kbit/s. Wer mehr will, sollte FLAC nehmen (nicht MP3).
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
# Audio-Format-Landschaft
|
||||
|
||||
| Format | Loss | Anwendung | Bitrate |
|
||||
|--------|------|-----------|---------|
|
||||
| **WAV** | Lossless | Studio-Master, Wave-Editor | 1.411 kbit/s (CD) |
|
||||
| **FLAC** | Lossless | Audiophile, Archiv | ~700 kbit/s (CD-Kompression) |
|
||||
| **MP3** | Lossy | Universalformat, älter | 128-320 kbit/s |
|
||||
| **AAC** | Lossy | Apple, YouTube, modern | 128-256 kbit/s |
|
||||
| **OGG / Vorbis** | Lossy | Open-Source, Spotify (alt) | 128-320 kbit/s |
|
||||
| **Opus** | Lossy | WhatsApp Call, Zoom | 6-510 kbit/s |
|
||||
|
||||
<!--
|
||||
Wichtig:
|
||||
- WAV ist nur ein Container. Inhalt ist roh PCM (oder seltener lossless-komprimiert).
|
||||
- FLAC = lossless, aber komprimiert (Faktor 2-3 gegenüber WAV).
|
||||
- AAC ist technisch besser als MP3 (ca. 30% kleiner bei gleicher Qualität), aber Patent-Lizenzen.
|
||||
- Opus ist der moderne Open-Source-Codec für Sprache UND Musik. Variable Bitrate.
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
# Audio-Format-Wahl
|
||||
|
||||
| Anwendung | Format | Warum |
|
||||
|-----------|--------|-------|
|
||||
| Spotify-Stream | **AAC** oder **MP3 192+** | Kompression, breite Unterstützung |
|
||||
| Studio-Master | **WAV** oder **FLAC** | Bit-genau erhalten |
|
||||
| Sprachnachricht | **Opus** oder **AAC-LD** | für Sprache optimiert, niedrige Bitrate |
|
||||
| Podcast-Distribution | **MP3 128 kbit/s** | universelle Unterstützung |
|
||||
| HiFi-Audiophile | **FLAC** | lossless, kleiner als WAV |
|
||||
| Archiv eigener Aufnahmen | **FLAC** oder **WAV** | nichts verlieren |
|
||||
|
||||
<!--
|
||||
Klausurfähig: gegeben ein Anwendungsfall, welches Format?
|
||||
|
||||
Trick-Frage: warum nicht MP3 320 für Studio? → Lossless ist immer noch verlustfrei besser. Wer mastern will, braucht das.
|
||||
|
||||
Trick-Frage 2: warum nicht WAV für Spotify? → Daten-Volumen zu hoch fürs Streaming.
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
<!-- _class: aufgabe -->
|
||||
|
||||
# Selbstlernen — Spotify-Bitrate live
|
||||
|
||||
Auf eurem Handy:
|
||||
|
||||
1. Spotify Premium-Setting auf **Niedrig (24 kbit/s)** umstellen
|
||||
2. Lieblings-Track mit **Kopfhörer** anhören. Auf Höhen achten.
|
||||
3. Auf **Sehr hoch (320 kbit/s)** umstellen
|
||||
4. Gleicher Track. Vergleichen.
|
||||
|
||||
**Was fällt auf?** Welche Frequenzen verschwinden zuerst?
|
||||
|
||||
<!--
|
||||
Pädagogisch: Studis hören selber, was der psychoakustische Codec wegwirft.
|
||||
|
||||
Erwartung:
|
||||
- 24 kbit/s: hochfrequente Detail weg (Cymbal, „s"-Töne), Stimme klingt dumpf
|
||||
- 320 kbit/s: praktisch identisch mit CD
|
||||
|
||||
Diskussion: für welche Hörsituation braucht ihr 320? (Studio-Kopfhörer, gute Anlage) Für welche reicht 96? (Smartphone-Lautsprecher).
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
<!-- _class: lead -->
|
||||
|
||||
# Sub-Sektion C: Video
|
||||
|
||||
<!--
|
||||
Video = Bild + Zeit + Audio.
|
||||
|
||||
Drei Konzepte zentral:
|
||||
1. Container ≠ Codec (DAS Missverständnis)
|
||||
2. Inter-Frame-Kompression (Frame-zu-Frame-Ähnlichkeit nutzen)
|
||||
3. Codec-Landschaft (H.264, H.265, VP9, AV1) + Patent-Politik
|
||||
|
||||
Wir bauen auf JPEG auf — Inter-Frame nutzt JPEG-ähnliche DCT-Kompression pro Frame, plus Zeitliches.
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
# Pixel × Pixel × Hz = Datenflut
|
||||
|
||||
**Roh-Video 4K @ 60 fps:**
|
||||
|
||||
```
|
||||
3 840 × 2 160 Pixel × 3 Byte × 60 fps = 1,49 GB/s
|
||||
```
|
||||
|
||||
**Pro Minute:** ~90 GB. *Pro Stunde:* ~5,3 TB.
|
||||
|
||||
Eine 1-TB-SSD wäre nach **~11 Minuten** voll.
|
||||
|
||||
→ **Ohne Kompression ist Streaming unmöglich.**
|
||||
|
||||
<!--
|
||||
Diese Rechnung ist klausurfähig und sollte beeindrucken:
|
||||
- Pixel pro Frame: 3840 × 2160 = ~8,3 Millionen
|
||||
- Byte pro Pixel: 3 (RGB)
|
||||
- Frame pro Sekunde: 60
|
||||
- Resultat: 1,5 GB/s
|
||||
|
||||
Vergleich:
|
||||
- Heim-Bandbreite: ~25 Mbit/s = 3 MB/s. 500× zu langsam für rohes 4K.
|
||||
- 4G-Mobilfunk: ~50 Mbit/s = 6 MB/s. Immer noch 250× zu langsam.
|
||||
- Netflix 4K-Stream: 25 Mbit/s. Erreicht durch Kompression. Faktor 480.
|
||||
|
||||
Die Kompression ist hier nicht „nice to have" — sie ist die Voraussetzung, dass es Video-Streaming überhaupt gibt.
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
<!-- _header: '' -->
|
||||
<!-- _footer: '' -->
|
||||
|
||||

|
||||
|
||||
<!--
|
||||
Das ist DER zentrale Missverständnis-Punkt bei Video. Studis denken oft, „MP4" oder „MKV" sei das Format des Videos. Stimmt nicht. Es ist nur die Hülle.
|
||||
|
||||
Konkretes Beispiel: zwei `.mp4`-Dateien:
|
||||
- A: H.264-Video + AAC-Audio
|
||||
- B: H.265-Video + Opus-Audio
|
||||
|
||||
Beide haben die Endung .mp4. Aber A spielt überall, B braucht moderne Player.
|
||||
|
||||
Tool: `mediainfo <datei>` zeigt Container UND Codec.
|
||||
|
||||
Klausurfähig.
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
# Was ist in einem Container?
|
||||
|
||||
```
|
||||
MP4-Container
|
||||
├── Video-Spur (H.264, codec: avc1)
|
||||
├── Audio-Spur (AAC, codec: mp4a)
|
||||
├── Untertitel-Spur (TTML, optional)
|
||||
└── Metadaten (Titel, Erstellungsdatum, Bitrate, GOP-Struktur, ...)
|
||||
```
|
||||
|
||||
Container regelt:
|
||||
- **Sync** zwischen Spuren (Audio passt zum Bild)
|
||||
- **Seeking** (Springen im Video)
|
||||
- **Streaming-Sicherheit** (Header früh genug)
|
||||
|
||||
<!--
|
||||
Container vs Codec:
|
||||
- Container = Datei-Format (.mp4, .mkv, .webm)
|
||||
- Codec = Algorithmus (H.264, H.265, AV1)
|
||||
|
||||
Vergleich aus dem Alltag:
|
||||
- Container ≈ Buchdeckel (Hardcover, Paperback, E-Book)
|
||||
- Codec ≈ Sprache des Texts (Englisch, Deutsch, übersetzt)
|
||||
|
||||
Ein und das selbe Buch (= Video) kann in verschiedenen Buchdeckeln (Containern) und verschiedenen Sprachen (Codecs) existieren.
|
||||
|
||||
Konkrete Tools:
|
||||
- ffmpeg: kann Container und Codec wechseln
|
||||
- mediainfo: zeigt was in einer Video-Datei drin ist
|
||||
- HandBrake: GUI für Encoding
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
# Inter-Frame — die zentrale Idee
|
||||
|
||||

|
||||
|
||||
Aufeinanderfolgende Frames sind **fast gleich**. Statt jedes ganz speichern: nur **Differenz**.
|
||||
|
||||
Drei Frame-Typen:
|
||||
|
||||
* **I** (Intra) — ganzes Bild
|
||||
* **P** (Predicted) — Diff zum vorigen
|
||||
* **B** (Bidirectional) — Diff zu vorigem + nächstem
|
||||
|
||||
<!--
|
||||
Inter-Frame ist DER Trick, der Video-Kompression überhaupt möglich macht.
|
||||
|
||||
Ohne Inter-Frame wäre 4K-Video ~480× kleiner als roh (nur durch Intra-Kompression). Mit Inter-Frame: ~10.000× kleiner. Das ist Streaming-tauglich.
|
||||
|
||||
GOP (Group of Pictures): typische Anordnung
|
||||
- IBBPBBPBBPBBP...IBBPBBP...
|
||||
- Alle 1-3 Sekunden ein I-Frame (Seeking-Anker)
|
||||
- Dazwischen P- und B-Frames
|
||||
|
||||
B-Frames sind effizienter als P-Frames (haben zwei Vorlagen), aber teurer zu enkodieren.
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
# I, P, B — Frame-Typen
|
||||
|
||||
| Typ | Vollname | Was drin | Größe |
|
||||
|-----|----------|----------|-------|
|
||||
| **I** | Intra-coded | Komplettes Bild (wie JPEG) | groß |
|
||||
| **P** | Predicted | „Was hat sich seit voriges I/P geändert" | mittel |
|
||||
| **B** | Bidirectional | „Was zwischen vorigem und nächstem I/P" | klein |
|
||||
|
||||
Typische GOP: `I B B P B B P B B P B B I ...` (alle 1–3 Sekunden ein I-Frame).
|
||||
|
||||
<!--
|
||||
Klausurfähig: was sind I/P/B-Frames? Welche ist die größte? Warum brauchen wir I-Frames trotzdem (Seeking, Stream-Start, Fehlerresistenz)?
|
||||
|
||||
GOP = Group of Pictures.
|
||||
|
||||
I-Frame als Seeking-Anker:
|
||||
- Wenn man im Video an einer Stelle springt, kann der Player nur an I-Frames anfangen
|
||||
- Zwischen I-Frames muss Player VOM letzten I-Frame ab dekodieren bis zur Spring-Stelle
|
||||
|
||||
Daher: I-Frames sollten nicht zu selten sein (sonst langsames Seeking), aber auch nicht zu häufig (sonst weniger Kompression).
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
# Motion Compensation
|
||||
|
||||
Ein Block aus dem vorigen Frame wird **verschoben** — nicht neu kodiert.
|
||||
|
||||
P-Frame speichert:
|
||||
1. Bewegungsvektor (z.B. „Block A: +5 Pixel rechts, +2 Pixel runter")
|
||||
2. Differenz zum verschobenen Block
|
||||
|
||||
**Resultat:** Auto-Fahrt vor stehender Kamera → P-Frames mini-klein.
|
||||
|
||||
<!--
|
||||
Motion Compensation ist der eigentliche „magic move" der Video-Kompression.
|
||||
|
||||
Bei einer Kamerafahrt (Schwenk) ist der Großteil des Bildes nur „verschoben". Der Codec sucht für jeden 16×16- oder 32×32-Block im neuen Frame den am besten passenden Block in einem Referenz-Frame und speichert nur:
|
||||
- Position dieses Referenz-Blocks
|
||||
- Differenz (das, was sich tatsächlich geändert hat)
|
||||
|
||||
Für statische Szenen mit reden den Personen: P-Frames sind oft ~5 % der I-Frame-Größe.
|
||||
|
||||
Encoding ist asymmetrisch: Encoder muss diese Block-Suche durchführen → teuer. Decoder bekommt nur die fertigen Vektoren → billig. Deshalb ist Video-Encoding viel langsamer als -Decoding.
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
<!-- _class: lead -->
|
||||
|
||||
# Die Codec-Landschaft
|
||||
|
||||
<!--
|
||||
H.264 → H.265 → AV1 → ?
|
||||
|
||||
Vier Generationen:
|
||||
- H.264 (2003): der dominierende Codec, überall, lizenzpflichtig aber gnädig
|
||||
- H.265 (2013): 50% effizienter, aber Patent-Chaos (mehrere Patent-Pools)
|
||||
- VP9 (2013): Google-Antwort, lizenzfrei
|
||||
- AV1 (2018): Industrie-Allianz, lizenzfrei, beste Kompression
|
||||
|
||||
Politik schlägt Technik. Ein guter Codec, der teuer ist, setzt sich nicht durch — siehe H.265.
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
# H.264 / AVC — der Workhorse
|
||||
|
||||
**2003** • dominierender Video-Codec seit Smartphone-Ära.
|
||||
|
||||
Wo überall verwendet:
|
||||
- YouTube (Hauptcodec)
|
||||
- Zoom, Teams, Meet
|
||||
- Netflix (HD-Streams)
|
||||
- Smartphones (alle iOS-Aufnahmen, viele Android)
|
||||
|
||||
Patente: MPEG-LA-Pool. Lizenzkosten **moderat**, viele Hersteller decken die Kosten in der Hardware ab.
|
||||
|
||||
<!--
|
||||
H.264 hat sich durchgesetzt weil:
|
||||
- Technisch deutlich besser als sein Vorgänger (MPEG-2)
|
||||
- Hardware-Decoder seit ~2010 in jedem Smartphone-Chip
|
||||
- Patente sind kostspielig, aber überschaubar (vergleichbar mit JPEG/MP3 in den 90ern)
|
||||
|
||||
Trotz Alter (~22 Jahre) immer noch der Standard. Effizienter sind H.265 und AV1, aber Kompatibilität und Patent-Klarheit halten H.264 lebendig.
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
# H.265 / HEVC — Patent-Chaos
|
||||
|
||||
**2013** • technisch ~50 % effizienter als H.264.
|
||||
|
||||
**Aber:** drei separate Patent-Pools, intransparente Lizenzkosten.
|
||||
|
||||
Resultat:
|
||||
- **Apple** macht alles in H.265 (HEIC-Fotos, iOS-Video) — bezahlt Lizenzen
|
||||
- **YouTube, Netflix** verzichten weitgehend — zu teuer + risikoreich
|
||||
- **Industrie-Reaktion:** Allianz für Open Media (AOMedia) gegründet, baut AV1
|
||||
|
||||
<!--
|
||||
H.265 ist der Lehrbuch-Fall für „technisch überlegen, kommerziell gescheitert".
|
||||
|
||||
Drei Patent-Pools (MPEG-LA, HEVC Advance, Velos Media) wollten alle separat Lizenzgebühren. Niemand wusste, was das Gesamt-Paket kostet. Software-Hersteller (Browser, Encoder) konnten kein realistisches Budget machen.
|
||||
|
||||
YouTube und Netflix haben deshalb H.265 für ihre Streaming-Operationen meiden lassen. Investierten stattdessen in VP9 (Google) und AV1 (AOMedia).
|
||||
|
||||
Apple ist mit HEIC ein Sonderfall: Apple hat genug Kapital, um die Lizenzen aller drei Pools zu zahlen, und nutzt H.265 für die kameraseitige Aufnahme.
|
||||
|
||||
Pointe: ein guter Codec ohne klare Lizenz-Situation ist tot für die Industrie.
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
# VP9 + AV1 — die offene Antwort
|
||||
|
||||
**VP9** (Google, 2013): lizenzfrei, ähnlich effizient wie H.265.
|
||||
- YouTube nutzt es für 4K-Streams (Chrome, Firefox).
|
||||
|
||||
**AV1** (Alliance for Open Media, 2018): Konsortium aus Google, Mozilla, Netflix, Amazon, Apple, ARM, Microsoft, Cisco, Intel, NVIDIA...
|
||||
- **Lizenzfrei.** **30 % effizienter als H.265.**
|
||||
- Hardware-Decoder seit ~2021 verfügbar (M1, Snapdragon 888+).
|
||||
- YouTube, Netflix, Twitch streamen schon AV1.
|
||||
|
||||
<!--
|
||||
AV1 ist die Industrie-Antwort auf das H.265-Patent-Desaster.
|
||||
|
||||
Bei AV1 standen die wichtigsten Internet-Player zusammen und sagten: „wir bauen einen Codec, der allen gehört, lizenzfrei ist und mindestens so gut wie H.265". 2018 war der Standard fertig.
|
||||
|
||||
Heute:
|
||||
- YouTube streamt 4K viel in AV1
|
||||
- Netflix streamt AV1 wo Decoder verfügbar
|
||||
- Twitch ebenfalls
|
||||
- Chrome, Firefox, Edge supportet AV1 nativ
|
||||
- Safari supportet seit macOS 13/Apple-M3-Chip
|
||||
|
||||
Hardware ist der Engpass: AV1 ist rechenintensiver zu enkodieren als H.264. Aber für die Studis, die einfach Videos schauen, ist das nicht relevant.
|
||||
|
||||
Pointe: politisch gewinnt der „offene" Codec, wenn die Industrie es will. Bei AV1 hat sie es gewollt.
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
# Patent vs. Open — warum AV1?
|
||||
|
||||
| Codec | Effizienz | Patent | Adoption (2026) |
|
||||
|-------|-----------|--------|-----------------|
|
||||
| H.264 | Baseline | Lizenz (MPEG-LA) | ~80 % aller Videos |
|
||||
| H.265 | +50 % | 3 Patent-Pools, chaotisch | nur Apple |
|
||||
| VP9 | ~H.265 | lizenzfrei (Google) | YouTube 4K |
|
||||
| **AV1** | **+30 % über H.265** | **lizenzfrei (Allianz)** | **YouTube, Netflix, Twitch** |
|
||||
|
||||
**Die Lektion:** technisch beste Lösung gewinnt nicht. *Lizenz-klare* beste Lösung gewinnt.
|
||||
|
||||
<!--
|
||||
Klausurfähig: warum hat AV1 H.265 abgelöst, wenn beide ähnlich effizient sind?
|
||||
|
||||
Antwort: Patent-Politik. H.265 hat drei Patent-Pools, AV1 ist lizenzfrei. Industrie-Konsortium hat AV1 finanziert, weil sie nie wieder einem MPEG-LA-Pool ausgeliefert sein wollten.
|
||||
|
||||
Sub-Frage: warum nicht VP9? → AV1 ist effizienter (~30 %), und alle wichtigen Player stehen dahinter (statt nur Google).
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
# 4K-Stream vs. Heim-Bandbreite
|
||||
|
||||
| Auflösung | Bitrate (H.265/AV1) | Heim-Bandbreite nötig |
|
||||
|-----------|---------------------|----------------------|
|
||||
| 480p (SD) | 1 Mbit/s | jeder Anschluss |
|
||||
| 720p (HD) | 3 Mbit/s | DSL ausreichend |
|
||||
| 1080p (Full HD) | 8 Mbit/s | DSL-25 + |
|
||||
| **4K (UHD)** | **25 Mbit/s** | **Glasfaser oder Kabel** |
|
||||
| 4K HDR | 35 Mbit/s | Kabel-Premium |
|
||||
| 8K | ~100 Mbit/s | Glasfaser-200 |
|
||||
|
||||
**Spotify-Audio dagegen:** Highest = 320 kbit/s = 0,3 Mbit/s. *80× weniger als ein 4K-Stream.*
|
||||
|
||||
<!--
|
||||
Diese Folie zeigt: Video ist die mit Abstand bandbreitenhungrigste Anwendung im Internet.
|
||||
|
||||
Konkret in DE (2026 Stand):
|
||||
- VDSL 50 Mbit/s ist Standard → reicht für 1080p, gerade so für 4K
|
||||
- Glasfaser 250 Mbit/s in Großstädten → 4K kein Problem
|
||||
- Mobilfunk 5G ~100 Mbit/s → 4K möglich
|
||||
|
||||
Konsequenz: ein 4K-Netflix-Stream allein nutzt einen typischen 50-Mbit-Anschluss zur Hälfte. Wenn der Mitbewohner auch streamt, wird's eng.
|
||||
|
||||
Anschluss zum nächsten Kapitel (Kap 4): „Wie kommen die Daten überhaupt zu meinem Gerät?" → Speichermedien und Schnittstellen.
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
<!-- _class: aufgabe -->
|
||||
|
||||
# Selbstlernen — drei Übungen
|
||||
|
||||
**Bild:**
|
||||
[Squoosh.app](https://squoosh.app) öffnen. Eigenes Foto in JPEG vs WebP vs AVIF konvertieren. Größe + Qualität vergleichen.
|
||||
|
||||
**Audio:**
|
||||
Spotify Premium-Bitrate von 24 auf 320 kbit/s wechseln. Lieblings-Track anhören. Was fällt auf?
|
||||
|
||||
**Video:**
|
||||
`mediainfo` (CLI oder GUI) auf eine eigene Video-Datei. Welcher Container? Welcher Codec? Welche Bitrate?
|
||||
|
||||
<!--
|
||||
Drei Übungen, eine pro Modalität. Jede sollte ~5-10 Min dauern.
|
||||
|
||||
Tool-Empfehlungen:
|
||||
- Squoosh.app (Browser, kein Install) — Google's Foto-Komprimierer
|
||||
- mediainfo: brew install mediainfo / sudo apt install mediainfo
|
||||
- Spotify: integriert
|
||||
|
||||
Pädagogisches Ziel: Studis sollen das Gelernte am eigenen Material durchspielen.
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
# Zusammenfassung
|
||||
|
||||
**Drei Modalitäten, ein Prinzip:** Wahrnehmungs-Lücken als Hebel.
|
||||
|
||||
| | **Bild** | **Audio** | **Video** |
|
||||
|--|----------|-----------|-----------|
|
||||
| Lossy-Trick | Chroma-Subsampling + DCT-Quantisierung | Maskierung + Hörschwelle | Inter-Frame + JPEG-pro-Frame |
|
||||
| Standardformat | JPEG | MP3/AAC | H.264 / AV1 |
|
||||
| Reduktion | ~10× | ~10× | ~100× |
|
||||
| Format-Politik | WebP > JPEG XL (Google) | MP3-Patent → AAC | H.265-Chaos → AV1 |
|
||||
|
||||
**In Kap 4** schauen wir uns an, *wie* diese Daten zu eurem Gerät kommen — und welche Schnittstelle dabei der Engpass ist.
|
||||
|
||||
<!--
|
||||
Recap:
|
||||
|
||||
Drei Modalitäten:
|
||||
- BILD: Raster vs Vektor. JPEG-Pipeline 6 Schritte (Farbraum, Chroma-Sub, Blöcke, DCT, Quant, Huffman). PNG/GIF/WebP/AVIF/SVG-Landschaft. Patent-Politik (WebP vs JPEG XL).
|
||||
- AUDIO: Sampling+Bittiefe-Recap. MP3-Maskierung. Bitrate-Stufen 128/192/320. Format-Landschaft (WAV/FLAC/MP3/AAC/Opus).
|
||||
- VIDEO: Container ≠ Codec. I/P/B-Frames. Motion Compensation. Codec-Landschaft (H.264/H.265/VP9/AV1). AV1-Patent-Politik.
|
||||
|
||||
Großes Thema dahinter: Wahrnehmung als Hebel. Was wir nicht sehen/hören → wegwerfen. Das ist die ganze Magie hinter Lossy.
|
||||
|
||||
Anschluss Kap 4: jetzt wissen wir, WAS in einer JPEG/MP3/MP4-Datei drin ist. Jetzt: wie kommt es zu uns? Speicher + Schnittstellen.
|
||||
-->
|
||||
@@ -0,0 +1,588 @@
|
||||
---
|
||||
marp: true
|
||||
theme: gaia
|
||||
paginate: true
|
||||
backgroundColor: #fff
|
||||
header: "Dateiformate, Schnittstellen, Speichermedien & Distributionswege (223015b)"
|
||||
footer: "Michael Czechowski – HdM Stuttgart – SoSe 2026"
|
||||
title: Speicher und Schnittstellen
|
||||
---
|
||||
|
||||
<style>
|
||||
:root {
|
||||
--color-foreground: #1a1a2e;
|
||||
--color-highlight: #1e5f8a;
|
||||
--color-dimmed: #4a4a6a;
|
||||
}
|
||||
section.invert { --color-foreground: #fff; }
|
||||
section { font-size: 1.7rem; }
|
||||
h1 { color: #1e5f8a; }
|
||||
section.invert h1 { color: #fff; }
|
||||
h2 { color: #1f2937; }
|
||||
pre {
|
||||
background: #0f0f23;
|
||||
color: #5fb3e4;
|
||||
border-radius: 8px;
|
||||
border-left: 3px solid #1e5f8a;
|
||||
}
|
||||
pre code { background: transparent; color: inherit; }
|
||||
code {
|
||||
background: #0f0f23;
|
||||
padding: 0.15em 0.4em;
|
||||
border-radius: 4px;
|
||||
font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
|
||||
}
|
||||
section code:not(.hljs) { color: #5fb3e4 !important; }
|
||||
section code.hljs { color: #f8f8f8 !important; }
|
||||
a { color: var(--color-highlight); }
|
||||
section.klausur {
|
||||
background: repeating-linear-gradient(
|
||||
135deg,
|
||||
#e3f2fd,
|
||||
#e3f2fd 40px,
|
||||
#fff 40px,
|
||||
#fff 80px
|
||||
) !important;
|
||||
}
|
||||
@media print {
|
||||
section.klausur { background: #e3f2fd !important; }
|
||||
}
|
||||
section.aufgabe { background: #e3f2fd !important; }
|
||||
section.aufgabe footer { display: none; }
|
||||
section.erklaerung :not(header),
|
||||
section.erklaerung :not(footer) { font-size: 1.1rem; }
|
||||
section.erklaerung h1 { font-size: 1.5rem; color: #1e5f8a; margin-bottom: 0.3rem; }
|
||||
section.erklaerung ul, section.erklaerung ol { font-size: 1.0rem; line-height: 1.4; }
|
||||
section.erklaerung p { font-size: 1.0rem; line-height: 1.4; }
|
||||
section.erklaerung table { font-size: 0.9rem; }
|
||||
</style>
|
||||
|
||||
<!-- _class: lead -->
|
||||
|
||||
# Kapitel 4
|
||||
## Speicher und Schnittstellen
|
||||
|
||||
<!--
|
||||
Eine Stunde, eine Frage: *Wo wohnen die Bytes — und wie reisen sie zwischen Geräten?*
|
||||
|
||||
Anschluss an Kap 3: dort haben wir gesehen, was in einer JPEG/MP3/MP4 drin ist (Inhalt). Hier: wo lebt diese Datei (Speicher) und wie kommt sie auf den Bildschirm (Schnittstellen).
|
||||
|
||||
Bogen:
|
||||
1. Speicher: HDD vs SSD, Filesystems, Backup
|
||||
2. PIVOT: wie reisen die Bytes?
|
||||
3. Schnittstellen: USB-C-Chaos, HDMI/DP/TB/Ethernet/WiFi
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
<!-- _header: '' -->
|
||||
<!-- _footer: '' -->
|
||||
|
||||

|
||||
|
||||
<!--
|
||||
Datei-Reise als Pipeline: SSD → Laptop → GPU → Monitor → Auge.
|
||||
|
||||
Pro Etappe ein Engpass:
|
||||
- USB 4 / Thunderbolt 4: 3 200 MB/s
|
||||
- PCIe 4.0 (intern Laptop): ~7 000 MB/s
|
||||
- HDMI 2.1 zum Monitor: 2 200 MB/s
|
||||
- Licht zum Auge: visuell
|
||||
|
||||
Pro Sekunde bei 4K60: 24 MB pro Frame × 60 fps = 1,4 GB/s reiner Pixel-Strom, der NIE als Datei vorliegt.
|
||||
|
||||
Pointe: Speicher und Schnittstelle sind keine zwei Themen — sie sind die zwei Seiten desselben Engpasses. Wo Bytes wohnen, entscheidet, wie schnell sie reisen können. Wo sie reisen, entscheidet, wo sie wohnen müssen.
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
<!-- _class: lead -->
|
||||
|
||||
# Sub-Sektion A: Speicher — wo wohnen die Bytes?
|
||||
|
||||
<!--
|
||||
Reihenfolge:
|
||||
1. HDD-Mechanik
|
||||
2. SSD-Flash
|
||||
3. HDD vs SSD: Vergleich + wann was
|
||||
4. Filesystems: FAT32 / NTFS / APFS / ext4
|
||||
5. Backup-Praxis: 3-2-1-Regel
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
# HDD — Magnetscheibe mit beweglichen Köpfen
|
||||
|
||||
**Hard Disk Drive.** Erfunden 1956 (IBM RAMAC). Bis 2010 das Standard-Speichermedium.
|
||||
|
||||
- **Magnetisierte** Bereiche auf rotierender Platter (5.400–15.000 U/min)
|
||||
- Schreib-/Lese-**Kopf** schwebt auf Luftpolster (~5 nm Abstand)
|
||||
- **Spuren** (konzentrische Kreise) + **Sektoren** (Tortenstück-Abschnitte)
|
||||
- **Bewegliche Teile** → Verschleiß, Geräusch, Stoß-empfindlich
|
||||
|
||||
<!--
|
||||
Mechanik:
|
||||
- Platter dreht permanent, Kopf bewegt sich radial
|
||||
- Latenz: Kopf muss zur richtigen Spur (Seek Time, 5-10 ms) + Platter muss richtigen Sektor unter den Kopf bringen (Rotational Latency, ~3 ms bei 7200 rpm)
|
||||
- Sequenzieller Zugriff schnell (Kopf bleibt auf Spur), zufälliger Zugriff langsam
|
||||
|
||||
Lebensdauer: typisch 5-10 Jahre bei moderater Nutzung. MTBF ~1 Mio Stunden. Lagerung ohne Strom: Magnetfeld hält jahrzehntelang.
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
# SSD — Speicher ohne Mechanik
|
||||
|
||||
**Solid State Drive.** Massentauglich seit ~2010. Heute Standard für OS-Disks.
|
||||
|
||||
- **Flash-Speicher** (NAND): Elektronen in Floating Gates speichern Bits
|
||||
- **Keine beweglichen Teile** → kein Geräusch, kein Stoß-Risiko
|
||||
- **NVMe-Protokoll** (PCIe-direkt) → 5–14 GB/s im Vergleich zu HDD-200 MB/s
|
||||
- **Schreibzyklen begrenzt** (TLC: ~3 000 P/E-Zyklen pro Zelle)
|
||||
|
||||
<!--
|
||||
Flash-Technik:
|
||||
- Floating Gate Transistor speichert Ladung
|
||||
- TLC = Triple-Level Cell, 3 Bits pro Zelle = 8 Spannungs-Stufen
|
||||
- Wear Leveling: Controller verteilt Schreibvorgänge gleichmäßig über alle Zellen
|
||||
- TRIM: OS sagt Controller welche Blöcke „nicht mehr gebraucht" → Garbage Collection
|
||||
|
||||
Lebensdauer in der Praxis: ~5-10 Jahre bei Consumer-Nutzung. Höher bei Enterprise.
|
||||
|
||||
NVMe vs SATA:
|
||||
- SATA-SSD: max. ~600 MB/s (Bus-Limit)
|
||||
- NVMe-SSD über PCIe 4.0: ~7 000 MB/s
|
||||
- PCIe 5.0 (neuere Macs): bis ~14 000 MB/s
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
# HDD vs. SSD
|
||||
|
||||

|
||||
|
||||
| | HDD | SSD |
|
||||
|--|-----|-----|
|
||||
| Technik | Mechanik | Flash |
|
||||
| Geschwindigkeit | 50–250 MB/s | 500–14.000 MB/s |
|
||||
| Latenz | ~10 ms | ~0,1 ms |
|
||||
| Preis/TB (2026) | ~20 € | ~70 € |
|
||||
| Lebensdauer | ~5–10 Jahre | ~5–10 Jahre |
|
||||
| Geräusch | hörbar | lautlos |
|
||||
| Stoß-empfindlich | ja | nein |
|
||||
|
||||
<!--
|
||||
HDD-Vorteile: viel Kapazität für wenig Geld. Lange archivierbar im Schrank.
|
||||
SSD-Vorteile: schnell, leise, robust. Aber teurer pro TB.
|
||||
|
||||
Klausurfähig: gegeben ein Anwendungsfall, HDD oder SSD?
|
||||
|
||||
- Betriebssystem: SSD (schnell)
|
||||
- Backup-Archiv: HDD (billig)
|
||||
- Server für Foto-Speicher: HDD (Kapazität)
|
||||
- Laptop (mobil): SSD (Stoß)
|
||||
- Video-Bearbeitung: SSD (Throughput)
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
# Wann nehme ich was?
|
||||
|
||||
| Anwendung | Empfehlung | Begründung |
|
||||
|-----------|------------|------------|
|
||||
| Betriebssystem auf dem Laptop | **NVMe-SSD** | Geschwindigkeit, Boot |
|
||||
| Eigene Foto-Library (10 TB+) | **HDD** | Kapazität, Preis |
|
||||
| Server für Logfiles | **HDD oder SSD** | je nach Schreib-Last |
|
||||
| Externes Backup-Archiv | **HDD** | billig, ok wenn langsam |
|
||||
| Mobile Workstation (Reise) | **SSD** | Stoß, Geräusch |
|
||||
| Edit-Drive für 4K-Schnitt | **NVMe-SSD** | Throughput für Video |
|
||||
| Langzeitarchiv 10+ Jahre | **LTO-Band + M-DISC** | Langlebigkeit |
|
||||
|
||||
<!--
|
||||
Klausurfähig. Trick-Frage: warum nicht alles SSD? → Preis pro TB. Faktor 3-5× teurer.
|
||||
|
||||
Cloud-Speicher (iCloud, Google Drive, Dropbox) ist physisch HDD/SSD/LTO in Rechenzentren — kein eigenes Medium, sondern Zugriffsmethode.
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
<!-- _class: lead -->
|
||||
|
||||
# Filesystems — die Sprache des Speichers
|
||||
|
||||
<!--
|
||||
Filesystem = Buchhaltungs-System des Speichermediums.
|
||||
|
||||
Welche Datei wo wohnt, welche Blöcke frei sind, wer welche Datei darf lesen.
|
||||
|
||||
Studierende kommen damit in Kontakt:
|
||||
- USB-Stick formatieren (Dialog frägt: FAT32 / exFAT / NTFS / APFS?)
|
||||
- "warum kann ich 5-GB-Video nicht auf USB ziehen?" — FAT32-Limit
|
||||
- "Mac kann von Windows-USB lesen aber nicht schreiben" — NTFS-Asymmetrie
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
# Was macht ein Filesystem?
|
||||
|
||||
**Vier zentrale Aufgaben:**
|
||||
|
||||
1. **Datei-Tabelle:** welche Datei wohnt wo? (Block-Adressen)
|
||||
2. **Frei-Liste:** welche Blöcke sind ungenutzt?
|
||||
3. **Verzeichnisbaum:** Ordner-Hierarchie
|
||||
4. **Metadaten:** Berechtigung, Erstell-Zeit, Letzt-Änderung, Eigentümer
|
||||
|
||||
Ein Speichermedium **ohne Filesystem** ist nur ein langer Strom von Bytes — niemand weiß, was wo ist.
|
||||
|
||||
<!--
|
||||
Analog: ein Buch ohne Inhaltsverzeichnis. Du müsstest jede Seite durchblättern um zu wissen, wo Kapitel 5 anfängt.
|
||||
|
||||
Filesystem = Inhaltsverzeichnis + Stichwortregister + Wer-darf-was-Liste.
|
||||
|
||||
Wenn du einen USB-Stick „formatierst", wird das Filesystem neu angelegt — die existierenden Daten sind dann logisch weg (aber physisch oft noch da, deshalb Sicherheitslücke bei Verkauf).
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
# Filesystem-Landschaft
|
||||
|
||||
| Filesystem | Wo verbreitet | Max. Dateigröße | Besonderheit |
|
||||
|-----------|---------------|----------------:|--------------|
|
||||
| **FAT32** | USB-Sticks, SD-Karten alt | **4 GB** | universell, alt |
|
||||
| **exFAT** | USB-Sticks modern | 16 EB | wie FAT, ohne 4-GB-Limit |
|
||||
| **NTFS** | Windows | 16 EB | Standard seit Win 2000 |
|
||||
| **APFS** | macOS seit 2017 | 8 EB | snapshots, schnell |
|
||||
| **ext4** | Linux | 16 TB | klassisch, robust |
|
||||
| **ZFS** | Server, FreeBSD | 16 EB | checksum, snapshots |
|
||||
|
||||
**FAT32 4-GB-Grenze** ist der häufigste Alltags-Knack: USB-Stick noch nie umformatiert → kein 4K-Video drauf.
|
||||
|
||||
<!--
|
||||
Klausurfähig: warum kann ich 5 GB Video nicht auf den USB-Stick ziehen? Antwort: FAT32 hat 4-GB-Dateigrößen-Limit. Lösung: USB-Stick auf exFAT umformatieren (Mac und Windows lesen/schreiben beide).
|
||||
|
||||
Asymmetrien:
|
||||
- Mac kann NTFS nur lesen, nicht schreiben (ohne Drittpartei-Treiber)
|
||||
- Windows kann APFS gar nicht
|
||||
- Linux kann mit Plugins fast alles
|
||||
|
||||
Konsequenz für Studis: für Datentransfer zwischen Mac und Windows → exFAT. Für reinen Mac → APFS. Für Backup auf USB-Disk, die nur am eigenen Gerät benutzt wird → natives FS.
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
<!-- _class: lead -->
|
||||
|
||||
# Backup — die unangenehme Pflicht
|
||||
|
||||
<!--
|
||||
Backup-Disaster-Stories als Hook:
|
||||
- Pixar verlor 1998 fast „Toy Story 2" durch ein versehentliches `rm -rf` auf dem Server. Nur weil eine Mitarbeiterin (Galyn Susman) zu Hause an einem Mutterschafts-Backup gearbeitet hatte, konnten 30 % des Films gerettet werden.
|
||||
- Maersk wurde 2017 durch NotPetya-Ransomware getroffen, 50.000 PCs verschlüsselt. Globale Schifffahrt stand 10 Tage. Recovery: dank einem Domain-Controller in Ghana, der zum Zeitpunkt des Angriffs ohne Strom war und deshalb nicht infiziert wurde.
|
||||
|
||||
Pointe: Backup ist kein Optional. Es ist die einzige Verteidigung gegen Hardware-Crash, Diebstahl, Ransomware und menschliches Versagen.
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||

|
||||
|
||||
# Pixar verlor Toy Story 2 fast
|
||||
|
||||
**1998.** Ein Mitarbeiter führte ein Maintenance-Skript aus, das per `rm -rf /` ausversehen die Hauptdatenbank löschte.
|
||||
|
||||
90 % des Films weg. Backup-Tapes? Defekt seit Monaten — niemand merkte es.
|
||||
|
||||
**Glück:** Galyn Susman, im Mutterschutz, hatte privat ein Backup auf dem Heim-PC. *Daraus wurde der Film rekonstruiert.*
|
||||
|
||||
<!--
|
||||
Diese Story zeigt zwei Backup-Wahrheiten:
|
||||
1. „Wir haben Backup" reicht nicht. Du musst regelmäßig PRÜFEN dass die Backups funktionieren (Restore-Tests).
|
||||
2. Backup auf einem System, das selbst betroffen sein kann, ist kein Backup. Galyn's Heim-PC war NICHT mit dem Pixar-Server verbunden — das hat den Film gerettet.
|
||||
|
||||
Daraus folgt die 3-2-1-Regel.
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
# Die 3-2-1-Backup-Regel
|
||||
|
||||
**3** Kopien deiner Daten
|
||||
|
||||
**2** verschiedene **Medien** (z.B. SSD + HDD)
|
||||
|
||||
**1** Kopie **off-site** (außerhalb deines Wohnorts)
|
||||
|
||||
Beispiel:
|
||||
|
||||
```
|
||||
Original → Foto-Library auf der MacBook-SSD
|
||||
Kopie 1 → Time Machine auf externer HDD (zuhause)
|
||||
Kopie 2 → Backblaze in der Cloud (off-site)
|
||||
```
|
||||
|
||||
<!--
|
||||
Diese Regel löst drei Risiken:
|
||||
- Hardware-Crash: 3 Kopien, 2 davon auf anderen Geräten
|
||||
- Diebstahl/Brand: 1 Kopie off-site (Cloud oder bei Familie)
|
||||
- Ransomware: off-site-Kopie schreibgeschützt oder versioniert
|
||||
|
||||
Klausurfähig: was ist die 3-2-1-Regel? Beispiele für jede Ebene.
|
||||
|
||||
Cloud-Backup-Anbieter (off-site Option):
|
||||
- Backblaze: ~7 USD/Monat unlimited (Mac/Windows)
|
||||
- iCloud / Google One / OneDrive: integriert, aber begrenzt
|
||||
- Self-hosted: Synology / QNAP bei einer Person im Vertrauen
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
# Backup-Typen
|
||||
|
||||
| Typ | Was wird gesichert | Restore-Aufwand | Speicher |
|
||||
|-----|---------------------|-----------------|----------|
|
||||
| **Full** | Alles, jedes Mal | klein (eine Datei) | viel (jedes Mal alles) |
|
||||
| **Incremental** | Nur Änderungen seit *letztem Backup* | groß (Kette aufrollen) | klein |
|
||||
| **Differential** | Alle Änderungen seit *letztem Full* | mittel | mittel |
|
||||
| **Snapshot** (APFS, ZFS) | Filesystem-Stand zu einem Zeitpunkt | sofort | Copy-on-Write |
|
||||
|
||||
**In der Praxis:** Mix aus 1× Full pro Woche + Incremental täglich.
|
||||
|
||||
<!--
|
||||
Time Machine (Mac) und Windows-Backup machen automatisch incremental + Snapshots im Hintergrund.
|
||||
|
||||
Restic, BorgBackup (CLI): dedupliziertes incremental Backup mit Verschlüsselung. Ideal für Cloud-Off-site.
|
||||
|
||||
Pointe: nicht überdenken. Time Machine + Backblaze reicht für 95 % der Studis.
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
<!-- _class: lead -->
|
||||
|
||||
# Sub-Sektion B: Schnittstellen — wie reisen die Bytes?
|
||||
|
||||
<!--
|
||||
PIVOT. Speicher = wo. Jetzt: wie kommt's vom einen Speicher zum anderen?
|
||||
|
||||
Drei zentrale Kategorien:
|
||||
1. USB-C (das Berührungs-Phänomen, der zentrale Aha)
|
||||
2. Video-Schnittstellen (HDMI, DisplayPort, Thunderbolt)
|
||||
3. Netzwerk (Ethernet, WiFi)
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
<!-- _class: lead -->
|
||||
|
||||
# USB-C — und seine drei Achsen
|
||||
|
||||
<!--
|
||||
Warum lädt mein Laptop am einen Port und nicht am anderen?
|
||||
Warum überträgt der eine Kabel 40 Gbit/s und der andere nur 480 Mbit/s?
|
||||
Warum erkennt der Monitor an USB-C kein Bild?
|
||||
|
||||
Antwort: USB-C ist nicht eine Sache. Es ist drei.
|
||||
|
||||
Diese Folie ist DER Aha-Moment des Kapitels.
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
<!-- _header: '' -->
|
||||
<!-- _footer: '' -->
|
||||
|
||||

|
||||
|
||||
<!--
|
||||
USB-C hat drei unabhängige Achsen, die alle zur „Verwirrung beim Stecker" beitragen:
|
||||
|
||||
1. STECKER (Mechanik): die Form. Beidseitig steckbar, 24 Pins. Es gibt nur EINE Sorte USB-C.
|
||||
|
||||
2. KABEL (was elektrisch durchgeht):
|
||||
- Charge-only: nur Strom, ~5 W
|
||||
- USB 2.0: 480 Mbit/s + 60 W (3 A)
|
||||
- USB 3.2 Gen 2: 10 Gbit/s + 100 W
|
||||
- Thunderbolt 4 / USB 4: 40 Gbit/s + 240 W (mit USB-PD 3.1)
|
||||
|
||||
3. PROTOKOLL (was gesprochen wird):
|
||||
- USB Power Delivery (Laden mit Verhandlung)
|
||||
- USB 2.0 / 3.x / 4 (Datenübertragung)
|
||||
- Thunderbolt 3 / 4 (Daten + Display tunneled)
|
||||
- DisplayPort Alt Mode (Monitor anschließen)
|
||||
- HDMI Alt Mode
|
||||
|
||||
Konsequenz: wenn etwas nicht funktioniert, checke in dieser Reihenfolge:
|
||||
1. Stecker physisch okay? (USB-C, nicht Mini-USB)
|
||||
2. Kabel-Spec ausreichend? (auf der Verpackung steht meist die Klasse)
|
||||
3. Beide Geräte sprechen das gleiche Protokoll? (z.B. Thunderbolt-Hub mit USB-Mac → reduzierte Funktionen)
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
# HDMI — Video + Audio + Kopierschutz
|
||||
|
||||
**High-Definition Multimedia Interface.** 2002. Standard für Heim-Elektronik.
|
||||
|
||||
| Version | Bandbreite | Max. Video |
|
||||
|---------|-----------|-----------|
|
||||
| HDMI 1.4 | 10 Gbit/s | 4K @ 30 Hz |
|
||||
| HDMI 2.0 | 18 Gbit/s | 4K @ 60 Hz |
|
||||
| HDMI 2.1 | 48 Gbit/s | 8K @ 60 Hz oder 4K @ 120 Hz |
|
||||
|
||||
**HDCP:** Kopierschutz, der „illegale" Aufnahmen verhindern soll. Manchmal die Ursache für „Bildschirm bleibt schwarz, wenn Netflix läuft."
|
||||
|
||||
<!--
|
||||
HDMI ist der Standard im Heim-Bereich. PCs, TVs, Blu-ray-Player, Konsolen — alle haben HDMI.
|
||||
|
||||
HDCP (High-bandwidth Digital Content Protection) ist eine Verschlüsselung der Übertragung. Wird gebrochen, wenn Geräte nicht „kompatibel" sind (z.B. Bild-Capture-Hardware).
|
||||
|
||||
Studis-Erfahrung: AirPlay/Chromecast geht meist NICHT mit HDCP-Inhalten. „Ich kann meinen Bildschirm beamen, aber wenn ich Netflix öffne wird er schwarz."
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
# DisplayPort — HDMIs offenes Pendant
|
||||
|
||||
**Open-Source-Industrie-Standard.** Hauptsächlich PC-Welt (Monitore).
|
||||
|
||||
- Versionen 1.4 (32 Gbit/s) bis 2.1 (80 Gbit/s)
|
||||
- **MST (Multi-Stream Transport):** ein Kabel → mehrere Monitore
|
||||
- **Adaptive Sync:** flüssige Bildraten bei Gaming (FreeSync, G-Sync)
|
||||
|
||||
In USB-C steckt fast immer ein **DisplayPort Alt Mode**, sodass dasselbe Kabel beides kann.
|
||||
|
||||
<!--
|
||||
DisplayPort vs HDMI:
|
||||
- HDMI: konsumieren, TV-Welt, kostenpflichtige Lizenzen
|
||||
- DisplayPort: produzieren, PC-Welt, lizenzfrei
|
||||
|
||||
Beide funktionieren technisch ähnlich. Im professionellen Bereich findet man eher DisplayPort, im Wohnzimmer eher HDMI.
|
||||
|
||||
Konvertierung: HDMI ↔ DisplayPort geht mit Adapter (passiv oder aktiv je nach Richtung).
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
# Thunderbolt — der Tunnel für alles
|
||||
|
||||
**Intel + Apple 2011, seit Version 3 (2015) auf USB-C-Stecker.**
|
||||
|
||||
Spezifikation:
|
||||
- **Thunderbolt 3 / 4:** 40 Gbit/s. PCIe + DisplayPort + USB *gleichzeitig*.
|
||||
- **Thunderbolt 5** (2024): 80–120 Gbit/s.
|
||||
|
||||
Anwendung: **externe GPU** (eGPU), 8K-Monitor, RAID-Array, ein Dock für alles.
|
||||
|
||||
<!--
|
||||
Thunderbolt ist „USB-C auf Steroiden". Der Stecker ist gleich, aber das Protokoll tunnelt mehrere Datenströme parallel:
|
||||
- PCIe-Daten (externe GPU)
|
||||
- DisplayPort (Monitor)
|
||||
- USB (Maus, Tastatur, Audio)
|
||||
- Strom (bis 240 W)
|
||||
|
||||
Hardware ist teurer (Thunderbolt-Controller). Kabel sind teurer (aktive Elektronik in den Steckern).
|
||||
|
||||
Wer Thunderbolt nutzt: Mac-Nutzer, Video-Editor, eGPU-Gaming, Photo-Pro.
|
||||
|
||||
Faustregel: Thunderbolt-Kabel = ~50€. Normal-USB-C-Kabel = ~10€.
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
# Ethernet vs. WiFi — Bandbreite + Latenz
|
||||
|
||||
| | Ethernet (Kabel) | WiFi (Funk) |
|
||||
|--|------------------|-------------|
|
||||
| Bandbreite | 1–10 Gbit/s | 0,6–9,6 Gbit/s (WiFi 6E) |
|
||||
| Latenz | < 1 ms | 5–20 ms (variabel) |
|
||||
| Stabilität | konstant | abhängig von Umgebung |
|
||||
| Setup | Kabel ziehen | App, kein Kabel |
|
||||
| Sicherheit | physisch geschützt | Passwort, abhörbar |
|
||||
|
||||
**Für Streaming:** WiFi reicht.
|
||||
**Für Gaming, Video-Call, Online-Code:** Ethernet besser (Latenz!).
|
||||
|
||||
<!--
|
||||
Latenz-Unterschied ist der oft unterschätzte Faktor:
|
||||
- Online-Spiele: Ping muss < 50 ms bleiben. Ethernet: 5 ms. WiFi: oft 30-50 ms.
|
||||
- Video-Call: Ethernet besser, weil weniger Jitter (Variabilität in der Latenz).
|
||||
- Streaming: 5-10 Sek Buffer puffert alles weg → WiFi reicht.
|
||||
|
||||
WiFi 6 / 6E (ax) bringt deutliche Verbesserung gegenüber WiFi 5 (ac), insbesondere bei vielen Geräten im selben Netz (Hörsaal, Stadion).
|
||||
|
||||
5G im Mobilfunk: ~100 Mbit/s, Latenz ~30 ms. Ähnlich wie WiFi 5.
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
# Schnittstellen-Wahl-Matrix
|
||||
|
||||
| Aufgabe | Beste Schnittstelle | Warum |
|
||||
|---------|---------------------|-------|
|
||||
| 4K-Monitor anschließen | **HDMI 2.0+** oder **DP 1.4+** | Bandbreite |
|
||||
| Online-Gaming | **Ethernet** | niedrige Latenz |
|
||||
| eGPU am Laptop | **Thunderbolt 3/4** | PCIe-Tunnel |
|
||||
| SD-Karte einlesen | **USB-A 3.0** oder **USB-C** | Kompatibilität |
|
||||
| Smartphone laden | **USB-C-PD** | Standard |
|
||||
| Heim-Streaming | **WiFi** oder **Ethernet** | reicht beides |
|
||||
| 4K-Stream mehrere Geräte | **Ethernet** | Stabilität |
|
||||
|
||||
<!--
|
||||
Klausurfähig: gegeben Anwendungsfall, welche Schnittstelle und warum?
|
||||
|
||||
Trick: warum nicht immer Thunderbolt? → Teurer Kabel, teurere Hardware. Nicht jedes Endgerät unterstützt es.
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
<!-- _class: aufgabe -->
|
||||
|
||||
# Selbstlernen — zwei Übungen
|
||||
|
||||
**1. Backup-Konzept aufschreiben**
|
||||
Inventarisiert eure Geräte: Wo wohnen welche Daten? Schreibt euer 3-2-1-Backup für eure eigene Foto-Library auf. Welches Off-site? Welche zweite Kopie?
|
||||
|
||||
**2. USB-C-Kabel-Check**
|
||||
Holt eure USB-C-Kabel raus. Was steht drauf? Was kann jedes Kabel laut Verpackung? Habt ihr ein „Charge-only"-Kabel, ohne es zu wissen?
|
||||
|
||||
<!--
|
||||
Pädagogisch: Studis sollen ihre eigenen Geräte/Kabel inventarisieren.
|
||||
|
||||
Übung 1: das 3-2-1-Konzept zwingt zur Aufschriftnahme. Realistisch: die meisten Studis haben Original + iCloud, aber kein zweites lokales Backup. Diskussion: wer hat schon mal eine Festplatte verloren? Worauf war drauf?
|
||||
|
||||
Übung 2: USB-C-Kabel haben oft kleine Aufdrucke (z.B. „USB 2.0 + 60 W" oder „USB4 240W"). Manchmal nichts — dann ist es typisch ein einfaches Charge-Kabel.
|
||||
|
||||
Tipp: Apple-Kabel haben Marker auf den Steckern (Symbole). Aldi-Kabel oft nicht.
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
# Zusammenfassung
|
||||
|
||||
**Speicher = wo wohnen die Bytes:** HDD-Mechanik vs SSD-Flash. Tradeoff Geschwindigkeit ↔ Preis/TB. Filesystem als Buchhaltung. Backup als 3-2-1.
|
||||
|
||||
**Schnittstellen = wie reisen sie:** USB-C-Stecker täuscht — drei Achsen (Stecker · Kabel · Protokoll). HDMI/DP/TB für Video. Ethernet für Latenz, WiFi für Bequemlichkeit.
|
||||
|
||||
**Der gemeinsame Hebel:** Engpass identifizieren, *bevor* man Hardware kauft.
|
||||
|
||||
→ **In Kap 5** schauen wir uns an, was eine Datei *unterwegs* mitführt — und was sie *verrät*.
|
||||
|
||||
<!--
|
||||
Recap:
|
||||
|
||||
Speicher:
|
||||
- HDD: Magnet, mechanisch, billig, langsam
|
||||
- SSD: Flash, kein Mechanik, teuer, schnell
|
||||
- Wann was: OS auf SSD, Archiv auf HDD, Backup auf beides
|
||||
- Filesystem: FAT32 (4 GB Limit), exFAT (universal), NTFS (Win), APFS (Mac), ext4 (Linux)
|
||||
- Backup: 3-2-1-Regel. Pixar-Story als Warnung.
|
||||
|
||||
Schnittstellen:
|
||||
- USB-C: drei Achsen — Stecker, Kabel, Protokoll. Wenn etwas nicht geht, eine davon checken.
|
||||
- Video: HDMI (TV-Welt, HDCP), DisplayPort (PC-Welt, offen), Thunderbolt (Tunnel für alles)
|
||||
- Netzwerk: Ethernet (Latenz, Stabilität) vs WiFi (Mobilität)
|
||||
|
||||
Großes Thema: Speicher + Schnittstelle = ein Engpass. Wo Daten wohnen, bestimmt wie schnell sie reisen können.
|
||||
|
||||
Anschluss zu Kap 5: in dieser Stunde haben wir gesehen, wo Bytes leben und wie sie reisen. Nächste Stunde: was nehmen sie mit, wenn sie reisen? EXIF, ID3, PDF-Metadaten — die unsichtbare Gepäcktasche jeder Datei.
|
||||
-->
|
||||
@@ -0,0 +1,616 @@
|
||||
---
|
||||
marp: true
|
||||
theme: gaia
|
||||
paginate: true
|
||||
backgroundColor: #fff
|
||||
header: "Dateiformate, Schnittstellen, Speichermedien & Distributionswege (223015b)"
|
||||
footer: "Michael Czechowski – HdM Stuttgart – SoSe 2026"
|
||||
title: Distribution und Metadaten
|
||||
---
|
||||
|
||||
<style>
|
||||
:root {
|
||||
--color-foreground: #1a1a2e;
|
||||
--color-highlight: #1e5f8a;
|
||||
--color-dimmed: #4a4a6a;
|
||||
}
|
||||
section.invert { --color-foreground: #fff; }
|
||||
section { font-size: 1.7rem; }
|
||||
h1 { color: #1e5f8a; }
|
||||
section.invert h1 { color: #fff; }
|
||||
h2 { color: #1f2937; }
|
||||
pre {
|
||||
background: #0f0f23;
|
||||
color: #5fb3e4;
|
||||
border-radius: 8px;
|
||||
border-left: 3px solid #1e5f8a;
|
||||
}
|
||||
pre code { background: transparent; color: inherit; }
|
||||
code {
|
||||
background: #0f0f23;
|
||||
padding: 0.15em 0.4em;
|
||||
border-radius: 4px;
|
||||
font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
|
||||
}
|
||||
section code:not(.hljs) { color: #5fb3e4 !important; }
|
||||
section code.hljs { color: #f8f8f8 !important; }
|
||||
a { color: var(--color-highlight); }
|
||||
section.klausur {
|
||||
background: repeating-linear-gradient(
|
||||
135deg,
|
||||
#e3f2fd,
|
||||
#e3f2fd 40px,
|
||||
#fff 40px,
|
||||
#fff 80px
|
||||
) !important;
|
||||
}
|
||||
@media print {
|
||||
section.klausur { background: #e3f2fd !important; }
|
||||
}
|
||||
section.aufgabe { background: #e3f2fd !important; }
|
||||
section.aufgabe footer { display: none; }
|
||||
section.erklaerung :not(header),
|
||||
section.erklaerung :not(footer) { font-size: 1.1rem; }
|
||||
section.erklaerung h1 { font-size: 1.5rem; color: #1e5f8a; margin-bottom: 0.3rem; }
|
||||
section.erklaerung ul, section.erklaerung ol { font-size: 1.0rem; line-height: 1.4; }
|
||||
section.erklaerung p { font-size: 1.0rem; line-height: 1.4; }
|
||||
section.erklaerung table { font-size: 0.9rem; }
|
||||
</style>
|
||||
|
||||
<!-- _class: lead -->
|
||||
|
||||
# Kapitel 5
|
||||
## Distribution und Metadaten
|
||||
|
||||
<!--
|
||||
Eine Stunde, eine Frage: *Wie kommen die Bytes von der Quelle zur Endnutzerin — und was verraten sie auf dem Weg?*
|
||||
|
||||
Anschluss an Kap 4: dort haben wir gesehen, wo Bytes wohnen und über welche Schnittstellen sie reisen. Jetzt: WIE reisen sie (Distribution) und WAS verraten sie dabei (Metadaten)?
|
||||
|
||||
Bogen:
|
||||
1. CDN-Prinzip (warum Netflix sofort startet)
|
||||
2. REST-APIs (wie Apps Daten austauschen)
|
||||
3. PIVOT zu Metadaten
|
||||
4. EXIF, ID3, PDF-Metadaten (was Dateien über sich verraten)
|
||||
5. Vendor-Lockin (Adobe, Apple)
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
<!-- _header: '' -->
|
||||
<!-- _footer: '' -->
|
||||
|
||||

|
||||
|
||||
<!--
|
||||
Eine Datei reist + erzählt. Smartphone-Foto Stuttgart → Tokyo zeigt drei Schichten:
|
||||
|
||||
- INHALT (links blau): das visuelle Foto, HEIC 4032×3024, 3,2 MB. Was der Empfänger sieht.
|
||||
- GEPÄCK (rechts lila): die EXIF-Daten, die mitkommen — Kamera iPhone 15 Pro, Zeitstempel, GPS-Koordinaten (pink: Stuttgart, Königstraße), iOS-Version, Farbprofil. Was die Datei über sich weiß.
|
||||
- WEG (unten orange): Route Stuttgart → DNS → TLS 1.3 → CDN-Edge Tokyo → Tokyo. HTTP-Headers: 200 OK, RTT 47 ms, cache HIT bei Edge tok-7.
|
||||
|
||||
Eine Datei = Inhalt + Gepäck + Weg. Drei Schichten, eine Datei.
|
||||
|
||||
In dieser Stunde gehen wir durch alle drei: wie reist die Datei (CDN, REST), was bringt sie mit (EXIF, ID3, PDF-Meta), und wann ist das ein Privacy-Problem (McAfee, Tony Blair).
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
<!-- _class: lead -->
|
||||
|
||||
# Sub-Sektion A: Distribution — wie reist die Datei?
|
||||
|
||||
<!--
|
||||
Reihenfolge:
|
||||
1. CDN-Prinzip (Netflix-Beispiel)
|
||||
2. REST-APIs (Wetter-App fragt Daten ab)
|
||||
3. JSON als Datenformat
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
# CDN — Content Delivery Network
|
||||
|
||||
**Idee:** Daten dort speichern, wo die Nutzer:innen sind.
|
||||
|
||||
Statt von **einem zentralen Server** in Kalifornien wird die Datei von einem **Edge-Server** in eurer Nähe geliefert.
|
||||
|
||||
Beispiel: Netflix nutzt **Open Connect** — eigene Server in 1.000+ ISP-Rechenzentren weltweit. ~15 % des globalen Internet-Verkehrs.
|
||||
|
||||
**Latenz** von Stuttgart zu Stuttgart: ~5 ms.
|
||||
**Latenz** von Stuttgart nach Kalifornien: ~150 ms.
|
||||
|
||||
<!--
|
||||
CDN-Logik:
|
||||
- Origin Server: das echte Heimatverzeichnis der Datei (z.B. Netflix-Headquarters)
|
||||
- Edge Server (PoPs = Points of Presence): Kopien, geographisch verteilt
|
||||
- Wenn ein User eine Datei anfordert: DNS leitet zur nächsten Edge-Kopie
|
||||
- Edge prüft Cache: HIT → liefert sofort. MISS → holt von Origin, cached für nächste Anfrage
|
||||
|
||||
Bekannte CDNs:
|
||||
- Cloudflare: 300+ Standorte, viele freie Websites
|
||||
- AWS CloudFront: Amazon
|
||||
- Akamai: ältester großer CDN
|
||||
- Netflix Open Connect: eigene Hardware in ISP-Rechenzentren
|
||||
|
||||
Konsequenz: ohne CDN würde Netflix einen Server in CA haben, jeder europäische Stream müsste den Atlantik queren. Mit CDN: lokal in München, Stuttgart, Hamburg.
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
# Wie sieht das im DevTools aus?
|
||||
|
||||
DevTools (F12) → Tab **Network** → reload eine Seite
|
||||
|
||||
Was ihr seht:
|
||||
- **DNS-Lookup:** ~30 ms (oder gecacht: 0)
|
||||
- **TLS-Handshake:** ~50 ms
|
||||
- **TTFB** (Time to First Byte): ~80 ms wenn CDN, sonst 300+
|
||||
- **Cache-Status:** Header `x-cache: HIT` oder `cf-cache-status: HIT`
|
||||
|
||||
→ **Selbstlernen:** öffnet eine populäre Seite, schaut die Response-Header an.
|
||||
|
||||
<!--
|
||||
DevTools-Demo live in der Vorlesung:
|
||||
1. Eine bekannte Seite öffnen (z.B. github.com)
|
||||
2. F12, Tab Network
|
||||
3. Reload
|
||||
4. Eine Request anklicken → Headers
|
||||
5. Suche nach `x-cache`, `cf-cache-status`, `age` Headers
|
||||
|
||||
Konsequenz für Studis: das ist nicht Magic — man kann es sehen.
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
<!-- _class: lead -->
|
||||
|
||||
# REST-APIs — wie Apps Daten austauschen
|
||||
|
||||
<!--
|
||||
API = Application Programming Interface = "Stelle, an der eine App mit einer anderen App redet".
|
||||
|
||||
Beispiel:
|
||||
- Wetter-App auf dem Handy braucht aktuelle Daten
|
||||
- Stellt eine HTTP-Anfrage an die Wetter-API (z.B. https://api.wetter.com/aktuell?ort=stuttgart)
|
||||
- API antwortet mit JSON-Daten
|
||||
- App rendert die Daten als hübsche Oberfläche
|
||||
|
||||
Im Hintergrund läuft das überall: Instagram (Daten von Server), Spotify (Tracks), Banking-Apps.
|
||||
|
||||
Heute: REST. Das ist DAS Standardparadigma.
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
# Was ist eine API?
|
||||
|
||||
**Application Programming Interface.** Eine standardisierte Stelle, an der zwei Programme Daten austauschen.
|
||||
|
||||
```
|
||||
HTTP-Request (GET /aktuell?ort=stuttgart)
|
||||
┌─────────────────────────────────────────────────┐
|
||||
│ ▼
|
||||
[App auf dem Handy] [API-Server]
|
||||
▲ │
|
||||
│ JSON-Response │
|
||||
└─────────────────────────────────────────────────┘
|
||||
{ "temperatur": 14, "regen": false, ... }
|
||||
```
|
||||
|
||||
**Beispiele:** Wetter, Maps, Banking, Twitter, jede Spotify-Anfrage.
|
||||
|
||||
<!--
|
||||
APIs sind die Klebstoffschicht zwischen Anwendung und Daten.
|
||||
|
||||
Frontend (App, Website): rendert die Daten
|
||||
Backend (Server): hält die Daten, beantwortet API-Anfragen
|
||||
|
||||
REST-Konvention: jede Ressource hat eine URL. Aktion drückt sich in der HTTP-Methode aus (GET = lesen, POST = neu erstellen, PUT = updaten, DELETE = löschen).
|
||||
|
||||
Konsistente Methoden + URLs → REST = "Representational State Transfer".
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
# REST: GET · POST · PUT · DELETE
|
||||
|
||||
| Methode | Was tut sie | URL-Beispiel |
|
||||
|---------|-------------|--------------|
|
||||
| **GET** | lesen | `GET /users/42` (User mit ID 42 abfragen) |
|
||||
| **POST** | neu erstellen | `POST /users` mit Daten als Body |
|
||||
| **PUT** | überschreiben | `PUT /users/42` mit kompletten neuen Daten |
|
||||
| **PATCH** | teilweise ändern | `PATCH /users/42` mit Änderungen |
|
||||
| **DELETE** | löschen | `DELETE /users/42` |
|
||||
|
||||
CRUD = **C**reate · **R**ead · **U**pdate · **D**elete.
|
||||
|
||||
<!--
|
||||
Klausurfähig: welche HTTP-Methode für welche Operation?
|
||||
|
||||
Trick-Frage: was ist der Unterschied zwischen PUT und PATCH?
|
||||
- PUT: ersetzt komplett. User wird kompletter neu gesetzt.
|
||||
- PATCH: ändert nur die mitgegebenen Felder. Rest bleibt.
|
||||
|
||||
In der Praxis nehmen viele APIs PUT auch für partielle Updates — kein RFC-konforme Strenge.
|
||||
|
||||
Werkzeuge zum Testen: curl, Postman, Hoppscotch (browser-basiert), VS-Code REST-Client-Plugin.
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
<!-- _class: aufgabe -->
|
||||
|
||||
# Selbstlernen — eine API im Browser anfragen
|
||||
|
||||
JSONPlaceholder ist eine kostenlose Fake-API zum Üben:
|
||||
|
||||
```
|
||||
https://jsonplaceholder.typicode.com/users
|
||||
https://jsonplaceholder.typicode.com/posts/1
|
||||
https://jsonplaceholder.typicode.com/posts?userId=2
|
||||
```
|
||||
|
||||
**Aufgabe:** Im Browser öffnen. Was kommt zurück? Welcher Content-Type-Header?
|
||||
|
||||
Bonus: mit `curl https://api.github.com/users/torvalds` in der Konsole.
|
||||
|
||||
<!--
|
||||
JSONPlaceholder = beste Spielwiese für API-Anfänger. Liefert fiktive Daten zu Users, Posts, Comments, Albums, Photos, Todos.
|
||||
|
||||
Live-Demo im Hörsaal:
|
||||
1. URL in den Browser-Adress-Bar eingeben
|
||||
2. JSON-Antwort sehen (Firefox/Chrome rendern es hübsch)
|
||||
3. F12, Network: Headers anschauen — content-type: application/json
|
||||
4. Curl in Terminal: ähnlich, ohne Browser-Pretty-Print
|
||||
|
||||
Daraus folgt: hinter jeder Web-App stecken API-Anfragen wie diese. Manchmal komplexer (Authentifizierung), aber im Kern dasselbe.
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
# JSON — das Standard-Datenformat
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "Torvalds",
|
||||
"alter": 56,
|
||||
"projekte": [
|
||||
{ "name": "Linux", "stars": 180000 },
|
||||
{ "name": "Git", "stars": 50000 }
|
||||
],
|
||||
"aktiv": true
|
||||
}
|
||||
```
|
||||
|
||||
- **Objekte** (`{ ... }`), **Listen** (`[ ... ]`), **Strings** (`"..."`), **Zahlen**, `true`/`false`, `null`
|
||||
- Universell: jede Programmiersprache hat JSON-Support
|
||||
- Lesbar: Mensch + Maschine
|
||||
|
||||
<!--
|
||||
JSON = JavaScript Object Notation. Erfunden 2001 von Douglas Crockford.
|
||||
|
||||
Hat XML als Standard-Datenformat im Web fast vollständig abgelöst:
|
||||
- Weniger Boilerplate als XML
|
||||
- Direkt von JavaScript-Engines parsbar
|
||||
- Streng aber einfach
|
||||
|
||||
Heute praktisch jede REST-API liefert JSON. Manchmal noch XML, selten YAML oder Protobuf.
|
||||
|
||||
Sub-formate: JSON5 (mit Kommentaren), JSONC (mit Trailing Commas), JSON-LD (für Schema.org).
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
<!-- _class: lead -->
|
||||
|
||||
# Sub-Sektion B: Metadaten — was Dateien über sich verraten
|
||||
|
||||
<!--
|
||||
PIVOT. Wir haben gesehen, wie Daten reisen (CDN, REST). Jetzt: WAS reist mit?
|
||||
|
||||
Die meisten Studis denken: "Eine JPEG-Datei ist ein Bild." Stimmt nur teilweise.
|
||||
|
||||
Tatsächlich enthält jede JPEG-Datei:
|
||||
- Das Bild selbst (visueller Inhalt)
|
||||
- EXIF-Metadaten: Kamera, Zeit, GPS, Software, Belichtung, Linse
|
||||
- Diese Metadaten reisen mit, wenn die Datei verteilt wird
|
||||
|
||||
Konsequenz: wer ein Foto verschickt, verschickt oft viel mehr als das Bild. Das ist die "Gepäck"-Seite des Bogens.
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
# EXIF — was ein Foto über sich verrät
|
||||
|
||||
**Exchangeable Image File Format.** Standard seit 1995, in JPEG/HEIC/TIFF.
|
||||
|
||||
Typische EXIF-Daten in einem Smartphone-Foto:
|
||||
|
||||
| Feld | Beispiel |
|
||||
|------|----------|
|
||||
| Kamera | Apple iPhone 15 Pro · 24 mm · ƒ/1.78 |
|
||||
| Belichtung | 1/250 s · ISO 100 |
|
||||
| **Aufnahme-Zeitstempel** | 2026-04-12 · 18:47:12 +02:00 |
|
||||
| **GPS-Koordinaten** | 48.7847°N 9.1825°E (Stuttgart, Königstraße) |
|
||||
| Software | iOS 18.4.1 · Photoshop CC 2025 |
|
||||
|
||||
<!--
|
||||
EXIF macht Fotos detektiv-tauglich.
|
||||
|
||||
Die GPS-Information ist die kritischste. Smartphones (auch Drohnen-Kameras) speichern standardmäßig die GPS-Koordinaten in jedem Foto.
|
||||
|
||||
Auch dabei: Datum/Uhrzeit auf die Sekunde genau, Software-Version (kann bei einem Hack als Forensik dienen).
|
||||
|
||||
Tools zum Auslesen:
|
||||
- `exiftool` (CLI, perl)
|
||||
- ExifTool GUI (mehrere Implementierungen)
|
||||
- Browser: exifdata.com, jeffrey.exif
|
||||
|
||||
Demo im Hörsaal: ein Foto vom Smartphone exportieren, exiftool drauf, GPS-Koordinaten in Google Maps eintippen.
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
# Der John-McAfee-GPS-Fall
|
||||
|
||||
**Dezember 2012.** John McAfee (Antivirus-Erfinder) flieht aus Belize, wo er als Mordverdächtiger gesucht wird.
|
||||
|
||||
**Vice Magazine** veröffentlicht ein Interview mit einem Foto: McAfee im T-Shirt, scheinbar in einer geheimen Location.
|
||||
|
||||
**EXIF-Koordinaten im Foto:** `15.6541° N, 88.9939° W` → **Hotel Nana Lodge, Guatemala.** Bekannt.
|
||||
|
||||
McAfee wird 36 Stunden später festgenommen.
|
||||
|
||||
<!--
|
||||
Diese Story zeigt:
|
||||
1. Smartphones speichern GPS-Daten standardmäßig
|
||||
2. Online-Plattformen STRIPPEN diese Metadaten oft NICHT (Vice damals nicht)
|
||||
3. Wer ein Bild mit GPS hochlädt, kann seinen Aufenthaltsort verraten
|
||||
|
||||
McAfee hat sich danach öffentlich darüber lustig gemacht ("yes that was the actual location"), aber der Fall wurde zum Lehrbuch-Beispiel für EXIF-Privacy.
|
||||
|
||||
2026: die meisten großen Plattformen strippen EXIF (Twitter/X, Instagram, WhatsApp), aber:
|
||||
- WhatsApp-Originaldatei via "Dokument" senden: behält EXIF
|
||||
- E-Mail-Anhang: behält EXIF
|
||||
- Direkt-Upload zu Drittpartei-Webseiten: oft mit EXIF
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
# Social-Media-EXIF-Stripping
|
||||
|
||||
| Plattform | Stripped? | Vorbehalt |
|
||||
|-----------|-----------|-----------|
|
||||
| **Instagram** | Ja | neu komprimiert |
|
||||
| **Facebook · iMessage** | Ja | — |
|
||||
| **Twitter / X** | Ja | nicht bei Direktnachricht |
|
||||
| **WhatsApp** | Ja als Foto | NEIN bei „Dokument senden" |
|
||||
| **E-Mail · Slack · Discord** | Nein | Original bleibt |
|
||||
|
||||
*Plattform-Upload = meist Stripped. Datei direkt teilen = unsicher.*
|
||||
|
||||
<!--
|
||||
Diese Tabelle ist nicht klausurrelevant, aber lebensweltlich wichtig.
|
||||
|
||||
Sub-Frage: warum strippen manche Plattformen, andere nicht?
|
||||
- Social: re-komprimieren sowieso → verlieren EXIF dabei
|
||||
- Messenger: oft komplett re-komprimieren (besseres Streaming)
|
||||
- E-Mail/Dokumenten-Sharing: schickt Original-Bytes durch
|
||||
|
||||
Privacy-Tipp: Geo-Tagging in Smartphone-Settings ausschalten, wenn ihr Fotos teilen wollt. Oder mit Apps wie "ExifEraser" reinigen.
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
# ID3 — Metadaten in MP3-Dateien
|
||||
|
||||
```
|
||||
ID3v2.4 Header:
|
||||
Titel: "Hotel California"
|
||||
Artist: "Eagles"
|
||||
Album: "Hotel California"
|
||||
Jahr: 1976
|
||||
Genre: Rock
|
||||
Cover-Art: [JPEG embedded, 250 × 250 px]
|
||||
```
|
||||
|
||||
Plus: Lyrics, Komponist, Track-Nr, ReplayGain, manchmal **ganze Lyric-Videos als Embedded-Bilder.**
|
||||
|
||||
→ Daher ist eine 4-Min MP3 manchmal **5 MB groß** statt 3 MB.
|
||||
|
||||
<!--
|
||||
ID3-Tags = Metadaten-Standard für MP3 seit 1996.
|
||||
|
||||
Versionen:
|
||||
- ID3v1: 128 Byte am Ende. Sehr begrenzt.
|
||||
- ID3v2: variabel große Tags am Anfang. Standard heute.
|
||||
|
||||
Datenbanken:
|
||||
- MusicBrainz: offene Musik-DB, vollständige Metadaten
|
||||
- AcoustID: erkennt Songs anhand Audio-Fingerprint
|
||||
- LastFM: scrobbling + Metadaten
|
||||
|
||||
Verwendet von: iTunes, Spotify, jeder Audio-Player.
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
# Der Tony-Blair-Fall (PDF-Metadaten)
|
||||
|
||||
**Februar 2003.** Britische Regierung veröffentlicht PDF-Dokument zur Begründung des Irakkriegs.
|
||||
|
||||
Ein britischer Akademiker findet im **PDF-Revisionsverlauf**: das Dokument wurde aus einer studentischen Doktorarbeit von 1991 kopiert.
|
||||
|
||||
**Plagiats-Skandal.** Plus Hinweise auf welche Mitarbeiter:innen welche Sätze überarbeitet hatten.
|
||||
|
||||
→ **PDF-Metadaten** verraten oft mehr als der Inhalt.
|
||||
|
||||
<!--
|
||||
PDF-Metadaten:
|
||||
- Autor, Erstell-Zeit, letzte Änderung
|
||||
- Software (Microsoft Word, LibreOffice, Adobe Acrobat)
|
||||
- Manchmal Revision History
|
||||
- Manchmal versteckter Text (z.B. weiße Schrift auf weißem Hintergrund)
|
||||
|
||||
Sicherheitsrelevant:
|
||||
- Schwärzungen werden manchmal nur als schwarzer Layer DRÜBER gelegt — Text bleibt extrahierbar
|
||||
- NSA-Dokumente, FBI-Reports, US-Gerichtsdokumente: viele berühmte Beispiele für gescheiterte Schwärzungen
|
||||
- Auch bei Microsoft Word: "Schwärze" via schwarzes Highlight → Text bleibt im Stream lesbar
|
||||
|
||||
Klausurfähig: ein Beispiel für PDF-Metadaten-Privacy-Verstoß nennen + Begründung.
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
<!-- _class: lead -->
|
||||
|
||||
# Vendor-Lockin — wenn das Format zum Käfig wird
|
||||
|
||||
<!--
|
||||
Manche Formate sind absichtlich proprietär. Hersteller behält die Spezifikation für sich.
|
||||
|
||||
Konsequenz:
|
||||
- Nur deren Software kann die Datei voll öffnen
|
||||
- Wer die Software lizenziert (oder ein Abo zahlt), kann arbeiten
|
||||
- Wer aus dem Ökosystem aussteigt, verliert evtl. die Daten
|
||||
|
||||
Klassiker:
|
||||
- Adobe Photoshop PSD
|
||||
- Adobe InDesign INDD
|
||||
- Apple Pages, Numbers, Keynote
|
||||
- Microsoft Word DOC (alt, vor DOCX)
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
# Beispiele: proprietäre Formate
|
||||
|
||||
| Format | Hersteller | Was nervt |
|
||||
|--------|-----------|-----------|
|
||||
| **PSD** (Photoshop) | Adobe | nur Photoshop liest Layer-Daten voll. Abo-Pflicht. |
|
||||
| **INDD** (InDesign) | Adobe | gleiches Problem |
|
||||
| **.pages** | Apple | nur in Apple-Apps voll editierbar |
|
||||
| **.numbers** | Apple | gleiches |
|
||||
| **DOC** (alt) | Microsoft | bis 2007 closed-source |
|
||||
| **PSP, AI** | Adobe | proprietäre Editor-Formate |
|
||||
|
||||
→ **Offene Alternativen:** PNG, TIFF, ODT (LibreOffice), HTML/Markdown, SVG.
|
||||
|
||||
<!--
|
||||
Vendor-Lockin-Logik:
|
||||
- Hersteller hat hohe Marktmacht
|
||||
- Hersteller-eigenes Format ist „besser" als offene Standards (richtiger oder gefühlt)
|
||||
- Migrations-Kosten sind hoch → User bleibt
|
||||
- Lock-in als Geschäftsmodell
|
||||
|
||||
Beispiel Adobe:
|
||||
- Photoshop ist standardmäßig in der Industrie
|
||||
- PSD ist DAS Format für Designer
|
||||
- Abonnement Creative Cloud: ~30€/Monat
|
||||
- Wer Photoshop kündigt: kann PSD-Dateien nicht mehr voll editieren
|
||||
|
||||
Gegenstrategien:
|
||||
- Open-Source-Tools: GIMP, Inkscape, LibreOffice
|
||||
- Export in offene Formate: PSD → TIFF (verlustlos) für Archiv
|
||||
- "Open Source Forever": Wikipedia, Sci-Hub, IPFS
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
# Vendor-Lockin als Risiko
|
||||
|
||||
**Szenario:** Du arbeitest 5 Jahre lang mit Adobe InDesign. Dann steigt der Abo-Preis um 200 % oder Adobe ändert das Format.
|
||||
|
||||
**Konsequenz:**
|
||||
- Bestehende INDD-Dateien öffnen sich noch — aber nur in Adobe-Produkten
|
||||
- Migration zu Affinity Publisher / Scribus: Daten müssen konvertiert werden, manche Details gehen verloren
|
||||
- Bei einigen Formaten gibt es keine Konverter — Vendor entscheidet komplett
|
||||
|
||||
**Schutz:** Wichtige Daten in **offenen Formaten** parallel speichern.
|
||||
|
||||
<!--
|
||||
Klausurfähig: was ist Vendor-Lockin? Beispiel + warum problematisch?
|
||||
|
||||
Diskussion: Open-Source-Tools sind oft "fast so gut" — manchmal sogar besser. Aber Industrie-Standards halten den Status quo.
|
||||
|
||||
Heimlich-Lockin: auch "Bug-für-Bug-Kompatibilität". Microsoft Office hat sich in den 90ern als Standard durchgesetzt, weil Konkurrenz-Office-Suites die exakten Bugs/Quirks nicht reproduzieren konnten.
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
<!-- _class: aufgabe -->
|
||||
|
||||
# Selbstlernen — exiftool auf eigene Fotos
|
||||
|
||||
**Installation:**
|
||||
- macOS: `brew install exiftool`
|
||||
- Linux: `sudo apt install libimage-exiftool-perl`
|
||||
- Windows: [exiftool.org](https://exiftool.org)
|
||||
|
||||
**Aufgabe:**
|
||||
```sh
|
||||
exiftool DEIN_FOTO.jpg
|
||||
```
|
||||
|
||||
Schaut, was alles drin steht. **Findet ihr GPS-Koordinaten?** Bonus: in [maps.google.com](https://maps.google.com) eintippen.
|
||||
|
||||
**Optional:** EXIF entfernen mit `exiftool -all= DEIN_FOTO.jpg`.
|
||||
|
||||
<!--
|
||||
Diese Übung ist die zentrale Aha-Erkenntnis für Studis: ihr eigenes Smartphone-Foto verrät GPS-Koordinaten.
|
||||
|
||||
Erwartung:
|
||||
- iPhone-Aufnahme: EXIF mit GPS, Kamera-Modell, Linsen-Daten
|
||||
- Foto von Android: ähnlich
|
||||
- Foto von einem Web-Download: oft schon EXIF-stripped
|
||||
|
||||
Diskussion: was bedeutet das für: einen unbekannten Hostessen-Service, ein Anonymous-Tweet mit Foto, ein Verkaufs-Foto auf eBay mit dem Foto vom Wohnzimmer?
|
||||
|
||||
Privacy-Empfehlung: Geo-Tagging im Smartphone abschalten ODER vor Upload mit exiftool/ExifEraser/Squoosh.app reinigen.
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
# Zusammenfassung
|
||||
|
||||
**Distribution — wie reist die Datei:**
|
||||
CDN bringt sie zur Edge. REST-API liefert Daten on-demand. JSON ist die Sprache.
|
||||
|
||||
**Metadaten — was bringt die Datei mit:**
|
||||
EXIF (Fotos), ID3 (Audio), PDF-Meta (Dokumente). GPS + Zeitstempel + Software.
|
||||
|
||||
**Privacy:** EXIF kann Aufenthaltsort verraten. PDF kann Revision-History verraten.
|
||||
|
||||
**Vendor-Lockin:** proprietäre Formate als Käfig. Offene Alternativen wo möglich.
|
||||
|
||||
→ Eine Datei ist nie nur Inhalt. **Inhalt + Gepäck + Weg.**
|
||||
|
||||
<!--
|
||||
Recap des Kapitels — und implizit auch des ganzen Kurses:
|
||||
|
||||
Distribution (Weg):
|
||||
- CDN: Daten dort speichern wo Nutzer sind
|
||||
- REST: standardisierte API über HTTP
|
||||
- JSON: das Datenformat
|
||||
|
||||
Metadaten (Gepäck):
|
||||
- EXIF: was Fotos verraten (GPS, Kamera, Zeit)
|
||||
- ID3: was MP3 verraten (Artist, Titel, Album)
|
||||
- PDF-Meta: Revision History, Autor, Software
|
||||
- Privacy-Cases: McAfee (GPS), Tony Blair (Revision History)
|
||||
|
||||
Vendor-Lockin:
|
||||
- Proprietäre Formate als Geschäftsmodell
|
||||
- Adobe, Apple, Microsoft
|
||||
- Schutz: offene Formate parallel
|
||||
|
||||
Synthese: Eine Datei = Inhalt + Gepäck + Weg.
|
||||
- Inhalt: was wir sehen/hören
|
||||
- Gepäck: was die Datei über sich weiß (Metadaten)
|
||||
- Weg: wie sie reist (CDN, Protokolle)
|
||||
|
||||
Alle drei sind Teil der Datei. Studis können jetzt eine JPEG/MP3/MP4/PDF als das verstehen, was sie wirklich ist: nicht ein Bild oder Song oder Dokument, sondern ein strukturierter Byte-Stream mit Inhalt + Metadaten + Distribution-Pfad.
|
||||
|
||||
Damit endet der Kurs. Die Klausur wird zeigen, was hängen geblieben ist.
|
||||
-->
|
||||
|
After Width: | Height: | Size: 220 KiB |
|
After Width: | Height: | Size: 2.0 MiB |
|
After Width: | Height: | Size: 9.2 KiB |
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 425 KiB |
|
After Width: | Height: | Size: 64 KiB |
|
After Width: | Height: | Size: 28 KiB |
|
After Width: | Height: | Size: 148 KiB |
|
After Width: | Height: | Size: 241 KiB |
|
After Width: | Height: | Size: 233 KiB |
|
After Width: | Height: | Size: 66 KiB |
|
After Width: | Height: | Size: 484 KiB |
|
After Width: | Height: | Size: 2.6 MiB |
|
After Width: | Height: | Size: 2.9 MiB |
|
After Width: | Height: | Size: 249 KiB |
|
After Width: | Height: | Size: 388 KiB |
|
After Width: | Height: | Size: 2.3 MiB |
|
After Width: | Height: | Size: 27 KiB |
|
After Width: | Height: | Size: 2.4 MiB |
|
After Width: | Height: | Size: 32 KiB |
|
After Width: | Height: | Size: 957 KiB |
|
After Width: | Height: | Size: 2.4 MiB |
@@ -0,0 +1,205 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Aliasing — derselbe Fehler in zwei Sinnen</title>
|
||||
<style>
|
||||
:root {
|
||||
--dark: #1a1a2e;
|
||||
--muted: #6b7280;
|
||||
--soft: #f8fafc;
|
||||
--border: #cbd5e1;
|
||||
--hl: #d63384;
|
||||
--audio: #ea580c;
|
||||
--bild: #2563eb;
|
||||
}
|
||||
html, body { margin: 0; padding: 0; background: #fff; font-family: system-ui, -apple-system, sans-serif; color: var(--dark); }
|
||||
body { padding: 30px 40px; }
|
||||
h1 { text-align: center; margin: 0 0 6px; font-size: 1.75rem; }
|
||||
.sub { text-align: center; color: var(--muted); margin-bottom: 24px; font-size: 1.05rem; }
|
||||
.sub strong { color: var(--dark); }
|
||||
|
||||
.pair {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 22px;
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.modality {
|
||||
border: 2px solid;
|
||||
border-radius: 12px;
|
||||
padding: 16px 18px;
|
||||
background: #fff;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 12px;
|
||||
}
|
||||
.modality.audio { border-color: var(--audio); }
|
||||
.modality.bild { border-color: var(--bild); }
|
||||
|
||||
.mod-head { display: flex; justify-content: space-between; align-items: baseline; }
|
||||
.mod-name { font-size: 1.25rem; font-weight: 700; }
|
||||
.modality.audio .mod-name { color: var(--audio); }
|
||||
.modality.bild .mod-name { color: var(--bild); }
|
||||
.mod-tag { font-size: 0.72rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.12em; color: var(--muted); }
|
||||
|
||||
.canvas {
|
||||
background: var(--soft);
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
}
|
||||
.canvas svg { display: block; }
|
||||
|
||||
.scene-pair { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
|
||||
.scene { display: flex; flex-direction: column; gap: 4px; }
|
||||
.scene-label {
|
||||
font-size: 0.68rem;
|
||||
font-weight: 700;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.1em;
|
||||
color: var(--muted);
|
||||
}
|
||||
.scene-cap {
|
||||
font-size: 0.78rem;
|
||||
color: var(--muted);
|
||||
line-height: 1.4;
|
||||
font-family: ui-monospace, monospace;
|
||||
}
|
||||
.scene-cap strong { color: var(--dark); }
|
||||
|
||||
.ear-eye {
|
||||
font-size: 0.86rem;
|
||||
line-height: 1.5;
|
||||
color: var(--dark);
|
||||
}
|
||||
.ear-eye .arrow { color: var(--hl); font-weight: 700; }
|
||||
.ear-eye-headline {
|
||||
font-size: 0.9rem;
|
||||
font-weight: 700;
|
||||
}
|
||||
.modality.audio .ear-eye-headline { color: var(--audio); }
|
||||
.modality.bild .ear-eye-headline { color: var(--bild); }
|
||||
|
||||
.verdict {
|
||||
margin-top: 22px;
|
||||
max-width: 1200px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
text-align: center;
|
||||
border: 2px solid var(--hl);
|
||||
border-radius: 12px;
|
||||
padding: 14px 22px;
|
||||
}
|
||||
.verdict-q { font-size: 1.1rem; font-weight: 700; color: var(--hl); }
|
||||
.verdict-a { font-size: 0.93rem; color: var(--dark); margin-top: 4px; }
|
||||
.verdict-a strong { color: var(--hl); }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Aliasing — derselbe Fehler in zwei Sinnen</h1>
|
||||
<div class="sub">Was im Ohr <strong>Brummen</strong> macht, macht im Auge <strong>Moiré</strong>. Wurzel: Sampling zu grob.</div>
|
||||
|
||||
<div class="pair">
|
||||
|
||||
<div class="modality audio">
|
||||
<div class="mod-head">
|
||||
<span class="mod-name">Audio</span>
|
||||
<span class="mod-tag">Unterabtastung</span>
|
||||
</div>
|
||||
|
||||
<div class="scene-pair">
|
||||
<div class="scene">
|
||||
<div class="scene-label">Original (18 kHz)</div>
|
||||
<div class="canvas">
|
||||
<svg viewBox="0 0 280 80" width="100%" height="80" preserveAspectRatio="none">
|
||||
<line x1="0" y1="40" x2="280" y2="40" stroke="#cbd5e1" stroke-width="1" stroke-dasharray="3,4"/>
|
||||
<path d="M0,40 Q7,5 14,40 T28,40 T42,40 T56,40 T70,40 T84,40 T98,40 T112,40 T126,40 T140,40 T154,40 T168,40 T182,40 T196,40 T210,40 T224,40 T238,40 T252,40 T266,40 T280,40"
|
||||
stroke="#ea580c" stroke-width="2" fill="none"/>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="scene-cap">20 Schwingungen<br>schnelle Welle</div>
|
||||
</div>
|
||||
<div class="scene">
|
||||
<div class="scene-label">Bei 22 kHz gesampelt</div>
|
||||
<div class="canvas">
|
||||
<svg viewBox="0 0 280 80" width="100%" height="80" preserveAspectRatio="none">
|
||||
<line x1="0" y1="40" x2="280" y2="40" stroke="#cbd5e1" stroke-width="1" stroke-dasharray="3,4"/>
|
||||
<path d="M0,40 Q7,5 14,40 T28,40 T42,40 T56,40 T70,40 T84,40 T98,40 T112,40 T126,40 T140,40 T154,40 T168,40 T182,40 T196,40 T210,40 T224,40 T238,40 T252,40 T266,40 T280,40"
|
||||
stroke="#fed7aa" stroke-width="1.2" fill="none"/>
|
||||
<path d="M0,40 Q70,10 140,40 T280,40"
|
||||
stroke="#ea580c" stroke-width="2.5" fill="none"/>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="scene-cap"><strong>2 Schwingungen</strong><br>Brumm-Frequenz</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="ear-eye">
|
||||
<div class="ear-eye-headline">Was das Ohr hört</div>
|
||||
Ein schriller 18-kHz-Ton wird zu einem dumpfen 4-kHz-Brumm. Das hohe ist <strong>nicht leiser</strong> — es ist <strong>verloren und falsch ersetzt</strong>.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="modality bild">
|
||||
<div class="mod-head">
|
||||
<span class="mod-name">Bild</span>
|
||||
<span class="mod-tag">Moiré-Effekt</span>
|
||||
</div>
|
||||
|
||||
<div class="scene-pair">
|
||||
<div class="scene">
|
||||
<div class="scene-label">Original (feine Streifen)</div>
|
||||
<div class="canvas">
|
||||
<svg viewBox="0 0 280 80" width="100%" height="80" preserveAspectRatio="none">
|
||||
<defs>
|
||||
<pattern id="fine-real" x="0" y="0" width="3" height="80" patternUnits="userSpaceOnUse">
|
||||
<rect x="0" y="0" width="1.5" height="80" fill="#1e3a8a"/>
|
||||
</pattern>
|
||||
</defs>
|
||||
<rect x="0" y="0" width="280" height="80" fill="url(#fine-real)"/>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="scene-cap">93 Linien<br>volle Auflösung</div>
|
||||
</div>
|
||||
<div class="scene">
|
||||
<div class="scene-label">In niedriger DPI gerendert</div>
|
||||
<div class="canvas">
|
||||
<svg viewBox="0 0 280 80" width="100%" height="80" preserveAspectRatio="none">
|
||||
<defs>
|
||||
<linearGradient id="moire-bands" x1="0" y1="0" x2="1" y2="0">
|
||||
<stop offset="0%" stop-color="#1e3a8a"/>
|
||||
<stop offset="10%" stop-color="#bfdbfe"/>
|
||||
<stop offset="20%" stop-color="#1e3a8a"/>
|
||||
<stop offset="30%" stop-color="#bfdbfe"/>
|
||||
<stop offset="40%" stop-color="#1e3a8a"/>
|
||||
<stop offset="50%" stop-color="#bfdbfe"/>
|
||||
<stop offset="60%" stop-color="#1e3a8a"/>
|
||||
<stop offset="70%" stop-color="#bfdbfe"/>
|
||||
<stop offset="80%" stop-color="#1e3a8a"/>
|
||||
<stop offset="90%" stop-color="#bfdbfe"/>
|
||||
<stop offset="100%" stop-color="#1e3a8a"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<rect x="0" y="0" width="280" height="80" fill="url(#moire-bands)"/>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="scene-cap"><strong>5 breite Bänder</strong><br>Moiré-Frequenz</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="ear-eye">
|
||||
<div class="ear-eye-headline">Was das Auge sieht</div>
|
||||
Feine Linien sind weg, dafür <strong>breite Streifen</strong>, die nie da waren. Aus 93 Linien werden 5 Bänder — das Bild lügt.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="verdict">
|
||||
<div class="verdict-q">Aliasing kennt keine Modalität. Es ist ein <strong>mathematischer</strong> Fehler — kein technischer.</div>
|
||||
<div class="verdict-a">Egal ob Ton, Bild, Video, Radar, GPS — Sampling muss immer mindestens <strong>doppelt</strong> so dicht sein wie das Signal. Sonst tauscht die Realität Frequenzen aus.</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
After Width: | Height: | Size: 100 KiB |
@@ -0,0 +1,311 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>ASCII-Tabelle</title>
|
||||
<style>
|
||||
:root {
|
||||
--hl: #1e5f8a;
|
||||
--dark: #1a1a2e;
|
||||
--muted: #6b7280;
|
||||
--border: #cbd5e1;
|
||||
--bg-soft: #f8fafc;
|
||||
--c-ctrl: #e5e7eb; /* control */
|
||||
--c-ctrl-text: #4b5563;
|
||||
--c-space: #fef3c7; /* space */
|
||||
--c-punct: #ddd6fe; /* punctuation */
|
||||
--c-digit: #bfdbfe; /* digits */
|
||||
--c-upper: #bbf7d0; /* uppercase */
|
||||
--c-lower: #fed7aa; /* lowercase */
|
||||
--c-del: #fecaca; /* DEL */
|
||||
}
|
||||
html, body { margin: 0; padding: 0; background: #fff; font-family: system-ui, -apple-system, sans-serif; color: var(--dark); }
|
||||
body { padding: 18px 24px; }
|
||||
h1 { text-align: center; margin: 0 0 2px; font-size: 1.5rem; }
|
||||
.sub { text-align: center; color: var(--muted); margin-bottom: 14px; font-size: 0.9rem; }
|
||||
.sub strong { color: var(--dark); }
|
||||
|
||||
.table-wrap { display: flex; justify-content: center; }
|
||||
|
||||
table.ascii {
|
||||
border-collapse: separate;
|
||||
border-spacing: 3px;
|
||||
font-family: ui-monospace, "SF Mono", Menlo, monospace;
|
||||
}
|
||||
table.ascii th, table.ascii td {
|
||||
width: 68px;
|
||||
height: 60px;
|
||||
padding: 0;
|
||||
text-align: center;
|
||||
vertical-align: middle;
|
||||
border-radius: 5px;
|
||||
}
|
||||
table.ascii th {
|
||||
background: var(--dark); color: #fff;
|
||||
font-size: 0.78rem;
|
||||
letter-spacing: 0.05em;
|
||||
font-weight: 700;
|
||||
width: 56px;
|
||||
height: 36px;
|
||||
}
|
||||
table.ascii th.row { width: 64px; }
|
||||
table.ascii th .b { display: block; font-size: 0.68rem; opacity: 0.7; font-weight: 400; margin-top: 2px; letter-spacing: 0.04em; }
|
||||
|
||||
table.ascii td {
|
||||
border: 1px solid var(--border);
|
||||
position: relative;
|
||||
}
|
||||
td .hex { position: absolute; top: 3px; left: 5px; font-size: 0.62rem; color: var(--muted); font-weight: 700; }
|
||||
td .dec { position: absolute; bottom: 3px; right: 5px; font-size: 0.62rem; color: var(--muted); font-weight: 400; }
|
||||
td .ch { font-size: 1.45rem; font-weight: 700; line-height: 1; }
|
||||
td.ctrl .ch { font-size: 0.82rem; font-weight: 700; }
|
||||
td.ctrl .ch small { display: block; font-size: 0.6rem; font-weight: 400; color: var(--muted); margin-top: 2px; letter-spacing: 0; }
|
||||
|
||||
td.ctrl { background: var(--c-ctrl); color: var(--c-ctrl-text); }
|
||||
td.space { background: var(--c-space); }
|
||||
td.punct { background: var(--c-punct); }
|
||||
td.digit { background: var(--c-digit); }
|
||||
td.upper { background: var(--c-upper); }
|
||||
td.lower { background: var(--c-lower); }
|
||||
td.del { background: var(--c-del); color: var(--c-ctrl-text); }
|
||||
|
||||
.legend {
|
||||
margin: 14px auto 0;
|
||||
display: flex; gap: 14px; justify-content: center; flex-wrap: wrap;
|
||||
font-size: 0.85rem;
|
||||
}
|
||||
.legend .item { display: flex; align-items: center; gap: 6px; padding: 4px 10px; border-radius: 4px; border: 1px solid var(--border); }
|
||||
.legend .swatch { width: 14px; height: 14px; border-radius: 3px; border: 1px solid var(--border); }
|
||||
.legend .swatch.ctrl { background: var(--c-ctrl); }
|
||||
.legend .swatch.space { background: var(--c-space); }
|
||||
.legend .swatch.punct { background: var(--c-punct); }
|
||||
.legend .swatch.digit { background: var(--c-digit); }
|
||||
.legend .swatch.upper { background: var(--c-upper); }
|
||||
.legend .swatch.lower { background: var(--c-lower); }
|
||||
.legend .swatch.del { background: var(--c-del); }
|
||||
|
||||
.meta-row {
|
||||
margin-top: 10px;
|
||||
display: flex; gap: 18px; justify-content: center;
|
||||
font-size: 0.85rem; color: var(--muted);
|
||||
}
|
||||
.meta-row strong { color: var(--dark); }
|
||||
.meta-row code { background: var(--dark); color: #f8f8f8; padding: 1px 6px; border-radius: 3px; font-family: ui-monospace, monospace; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>ASCII-Tabelle (1963) · 7 Bit · 128 Zeichen</h1>
|
||||
<div class="sub">Spalte = High-Nibble (Hex 0–7) · Zeile = Low-Nibble (Hex 0–F) · <strong>Hex</strong> oben, <strong>Dezimal</strong> unten</div>
|
||||
|
||||
<div class="table-wrap">
|
||||
<table class="ascii">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="row">↓ Low<br>→ High</th>
|
||||
<th>0<span class="b">0000</span></th>
|
||||
<th>1<span class="b">0001</span></th>
|
||||
<th>2<span class="b">0010</span></th>
|
||||
<th>3<span class="b">0011</span></th>
|
||||
<th>4<span class="b">0100</span></th>
|
||||
<th>5<span class="b">0101</span></th>
|
||||
<th>6<span class="b">0110</span></th>
|
||||
<th>7<span class="b">0111</span></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<th class="row">0<span class="b">0000</span></th>
|
||||
<td class="ctrl"><span class="hex">00</span><span class="ch">NUL<small>null</small></span><span class="dec">0</span></td>
|
||||
<td class="ctrl"><span class="hex">10</span><span class="ch">DLE<small>data link esc</small></span><span class="dec">16</span></td>
|
||||
<td class="space"><span class="hex">20</span><span class="ch">SP<small>space</small></span><span class="dec">32</span></td>
|
||||
<td class="digit"><span class="hex">30</span><span class="ch">0</span><span class="dec">48</span></td>
|
||||
<td class="punct"><span class="hex">40</span><span class="ch">@</span><span class="dec">64</span></td>
|
||||
<td class="upper"><span class="hex">50</span><span class="ch">P</span><span class="dec">80</span></td>
|
||||
<td class="punct"><span class="hex">60</span><span class="ch">`</span><span class="dec">96</span></td>
|
||||
<td class="lower"><span class="hex">70</span><span class="ch">p</span><span class="dec">112</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th class="row">1<span class="b">0001</span></th>
|
||||
<td class="ctrl"><span class="hex">01</span><span class="ch">SOH<small>start hdr</small></span><span class="dec">1</span></td>
|
||||
<td class="ctrl"><span class="hex">11</span><span class="ch">DC1<small>XON</small></span><span class="dec">17</span></td>
|
||||
<td class="punct"><span class="hex">21</span><span class="ch">!</span><span class="dec">33</span></td>
|
||||
<td class="digit"><span class="hex">31</span><span class="ch">1</span><span class="dec">49</span></td>
|
||||
<td class="upper"><span class="hex">41</span><span class="ch">A</span><span class="dec">65</span></td>
|
||||
<td class="upper"><span class="hex">51</span><span class="ch">Q</span><span class="dec">81</span></td>
|
||||
<td class="lower"><span class="hex">61</span><span class="ch">a</span><span class="dec">97</span></td>
|
||||
<td class="lower"><span class="hex">71</span><span class="ch">q</span><span class="dec">113</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th class="row">2<span class="b">0010</span></th>
|
||||
<td class="ctrl"><span class="hex">02</span><span class="ch">STX<small>start txt</small></span><span class="dec">2</span></td>
|
||||
<td class="ctrl"><span class="hex">12</span><span class="ch">DC2</span><span class="dec">18</span></td>
|
||||
<td class="punct"><span class="hex">22</span><span class="ch">"</span><span class="dec">34</span></td>
|
||||
<td class="digit"><span class="hex">32</span><span class="ch">2</span><span class="dec">50</span></td>
|
||||
<td class="upper"><span class="hex">42</span><span class="ch">B</span><span class="dec">66</span></td>
|
||||
<td class="upper"><span class="hex">52</span><span class="ch">R</span><span class="dec">82</span></td>
|
||||
<td class="lower"><span class="hex">62</span><span class="ch">b</span><span class="dec">98</span></td>
|
||||
<td class="lower"><span class="hex">72</span><span class="ch">r</span><span class="dec">114</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th class="row">3<span class="b">0011</span></th>
|
||||
<td class="ctrl"><span class="hex">03</span><span class="ch">ETX<small>end txt</small></span><span class="dec">3</span></td>
|
||||
<td class="ctrl"><span class="hex">13</span><span class="ch">DC3<small>XOFF</small></span><span class="dec">19</span></td>
|
||||
<td class="punct"><span class="hex">23</span><span class="ch">#</span><span class="dec">35</span></td>
|
||||
<td class="digit"><span class="hex">33</span><span class="ch">3</span><span class="dec">51</span></td>
|
||||
<td class="upper"><span class="hex">43</span><span class="ch">C</span><span class="dec">67</span></td>
|
||||
<td class="upper"><span class="hex">53</span><span class="ch">S</span><span class="dec">83</span></td>
|
||||
<td class="lower"><span class="hex">63</span><span class="ch">c</span><span class="dec">99</span></td>
|
||||
<td class="lower"><span class="hex">73</span><span class="ch">s</span><span class="dec">115</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th class="row">4<span class="b">0100</span></th>
|
||||
<td class="ctrl"><span class="hex">04</span><span class="ch">EOT<small>end trans</small></span><span class="dec">4</span></td>
|
||||
<td class="ctrl"><span class="hex">14</span><span class="ch">DC4</span><span class="dec">20</span></td>
|
||||
<td class="punct"><span class="hex">24</span><span class="ch">$</span><span class="dec">36</span></td>
|
||||
<td class="digit"><span class="hex">34</span><span class="ch">4</span><span class="dec">52</span></td>
|
||||
<td class="upper"><span class="hex">44</span><span class="ch">D</span><span class="dec">68</span></td>
|
||||
<td class="upper"><span class="hex">54</span><span class="ch">T</span><span class="dec">84</span></td>
|
||||
<td class="lower"><span class="hex">64</span><span class="ch">d</span><span class="dec">100</span></td>
|
||||
<td class="lower"><span class="hex">74</span><span class="ch">t</span><span class="dec">116</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th class="row">5<span class="b">0101</span></th>
|
||||
<td class="ctrl"><span class="hex">05</span><span class="ch">ENQ<small>enquiry</small></span><span class="dec">5</span></td>
|
||||
<td class="ctrl"><span class="hex">15</span><span class="ch">NAK</span><span class="dec">21</span></td>
|
||||
<td class="punct"><span class="hex">25</span><span class="ch">%</span><span class="dec">37</span></td>
|
||||
<td class="digit"><span class="hex">35</span><span class="ch">5</span><span class="dec">53</span></td>
|
||||
<td class="upper"><span class="hex">45</span><span class="ch">E</span><span class="dec">69</span></td>
|
||||
<td class="upper"><span class="hex">55</span><span class="ch">U</span><span class="dec">85</span></td>
|
||||
<td class="lower"><span class="hex">65</span><span class="ch">e</span><span class="dec">101</span></td>
|
||||
<td class="lower"><span class="hex">75</span><span class="ch">u</span><span class="dec">117</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th class="row">6<span class="b">0110</span></th>
|
||||
<td class="ctrl"><span class="hex">06</span><span class="ch">ACK<small>ack</small></span><span class="dec">6</span></td>
|
||||
<td class="ctrl"><span class="hex">16</span><span class="ch">SYN</span><span class="dec">22</span></td>
|
||||
<td class="punct"><span class="hex">26</span><span class="ch">&</span><span class="dec">38</span></td>
|
||||
<td class="digit"><span class="hex">36</span><span class="ch">6</span><span class="dec">54</span></td>
|
||||
<td class="upper"><span class="hex">46</span><span class="ch">F</span><span class="dec">70</span></td>
|
||||
<td class="upper"><span class="hex">56</span><span class="ch">V</span><span class="dec">86</span></td>
|
||||
<td class="lower"><span class="hex">66</span><span class="ch">f</span><span class="dec">102</span></td>
|
||||
<td class="lower"><span class="hex">76</span><span class="ch">v</span><span class="dec">118</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th class="row">7<span class="b">0111</span></th>
|
||||
<td class="ctrl"><span class="hex">07</span><span class="ch">BEL<small>bell 🔔</small></span><span class="dec">7</span></td>
|
||||
<td class="ctrl"><span class="hex">17</span><span class="ch">ETB</span><span class="dec">23</span></td>
|
||||
<td class="punct"><span class="hex">27</span><span class="ch">'</span><span class="dec">39</span></td>
|
||||
<td class="digit"><span class="hex">37</span><span class="ch">7</span><span class="dec">55</span></td>
|
||||
<td class="upper"><span class="hex">47</span><span class="ch">G</span><span class="dec">71</span></td>
|
||||
<td class="upper"><span class="hex">57</span><span class="ch">W</span><span class="dec">87</span></td>
|
||||
<td class="lower"><span class="hex">67</span><span class="ch">g</span><span class="dec">103</span></td>
|
||||
<td class="lower"><span class="hex">77</span><span class="ch">w</span><span class="dec">119</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th class="row">8<span class="b">1000</span></th>
|
||||
<td class="ctrl"><span class="hex">08</span><span class="ch">BS<small>backspace</small></span><span class="dec">8</span></td>
|
||||
<td class="ctrl"><span class="hex">18</span><span class="ch">CAN</span><span class="dec">24</span></td>
|
||||
<td class="punct"><span class="hex">28</span><span class="ch">(</span><span class="dec">40</span></td>
|
||||
<td class="digit"><span class="hex">38</span><span class="ch">8</span><span class="dec">56</span></td>
|
||||
<td class="upper"><span class="hex">48</span><span class="ch">H</span><span class="dec">72</span></td>
|
||||
<td class="upper"><span class="hex">58</span><span class="ch">X</span><span class="dec">88</span></td>
|
||||
<td class="lower"><span class="hex">68</span><span class="ch">h</span><span class="dec">104</span></td>
|
||||
<td class="lower"><span class="hex">78</span><span class="ch">x</span><span class="dec">120</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th class="row">9<span class="b">1001</span></th>
|
||||
<td class="ctrl"><span class="hex">09</span><span class="ch">HT<small>tab ⇥</small></span><span class="dec">9</span></td>
|
||||
<td class="ctrl"><span class="hex">19</span><span class="ch">EM</span><span class="dec">25</span></td>
|
||||
<td class="punct"><span class="hex">29</span><span class="ch">)</span><span class="dec">41</span></td>
|
||||
<td class="digit"><span class="hex">39</span><span class="ch">9</span><span class="dec">57</span></td>
|
||||
<td class="upper"><span class="hex">49</span><span class="ch">I</span><span class="dec">73</span></td>
|
||||
<td class="upper"><span class="hex">59</span><span class="ch">Y</span><span class="dec">89</span></td>
|
||||
<td class="lower"><span class="hex">69</span><span class="ch">i</span><span class="dec">105</span></td>
|
||||
<td class="lower"><span class="hex">79</span><span class="ch">y</span><span class="dec">121</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th class="row">A<span class="b">1010</span></th>
|
||||
<td class="ctrl"><span class="hex">0A</span><span class="ch">LF<small>↵ newline</small></span><span class="dec">10</span></td>
|
||||
<td class="ctrl"><span class="hex">1A</span><span class="ch">SUB<small>EOF DOS</small></span><span class="dec">26</span></td>
|
||||
<td class="punct"><span class="hex">2A</span><span class="ch">*</span><span class="dec">42</span></td>
|
||||
<td class="punct"><span class="hex">3A</span><span class="ch">:</span><span class="dec">58</span></td>
|
||||
<td class="upper"><span class="hex">4A</span><span class="ch">J</span><span class="dec">74</span></td>
|
||||
<td class="upper"><span class="hex">5A</span><span class="ch">Z</span><span class="dec">90</span></td>
|
||||
<td class="lower"><span class="hex">6A</span><span class="ch">j</span><span class="dec">106</span></td>
|
||||
<td class="lower"><span class="hex">7A</span><span class="ch">z</span><span class="dec">122</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th class="row">B<span class="b">1011</span></th>
|
||||
<td class="ctrl"><span class="hex">0B</span><span class="ch">VT</span><span class="dec">11</span></td>
|
||||
<td class="ctrl"><span class="hex">1B</span><span class="ch">ESC<small>escape</small></span><span class="dec">27</span></td>
|
||||
<td class="punct"><span class="hex">2B</span><span class="ch">+</span><span class="dec">43</span></td>
|
||||
<td class="punct"><span class="hex">3B</span><span class="ch">;</span><span class="dec">59</span></td>
|
||||
<td class="upper"><span class="hex">4B</span><span class="ch">K</span><span class="dec">75</span></td>
|
||||
<td class="punct"><span class="hex">5B</span><span class="ch">[</span><span class="dec">91</span></td>
|
||||
<td class="lower"><span class="hex">6B</span><span class="ch">k</span><span class="dec">107</span></td>
|
||||
<td class="punct"><span class="hex">7B</span><span class="ch">{</span><span class="dec">123</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th class="row">C<span class="b">1100</span></th>
|
||||
<td class="ctrl"><span class="hex">0C</span><span class="ch">FF<small>form feed</small></span><span class="dec">12</span></td>
|
||||
<td class="ctrl"><span class="hex">1C</span><span class="ch">FS</span><span class="dec">28</span></td>
|
||||
<td class="punct"><span class="hex">2C</span><span class="ch">,</span><span class="dec">44</span></td>
|
||||
<td class="punct"><span class="hex">3C</span><span class="ch"><</span><span class="dec">60</span></td>
|
||||
<td class="upper"><span class="hex">4C</span><span class="ch">L</span><span class="dec">76</span></td>
|
||||
<td class="punct"><span class="hex">5C</span><span class="ch">\</span><span class="dec">92</span></td>
|
||||
<td class="lower"><span class="hex">6C</span><span class="ch">l</span><span class="dec">108</span></td>
|
||||
<td class="punct"><span class="hex">7C</span><span class="ch">|</span><span class="dec">124</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th class="row">D<span class="b">1101</span></th>
|
||||
<td class="ctrl"><span class="hex">0D</span><span class="ch">CR<small>carriage</small></span><span class="dec">13</span></td>
|
||||
<td class="ctrl"><span class="hex">1D</span><span class="ch">GS</span><span class="dec">29</span></td>
|
||||
<td class="punct"><span class="hex">2D</span><span class="ch">-</span><span class="dec">45</span></td>
|
||||
<td class="punct"><span class="hex">3D</span><span class="ch">=</span><span class="dec">61</span></td>
|
||||
<td class="upper"><span class="hex">4D</span><span class="ch">M</span><span class="dec">77</span></td>
|
||||
<td class="punct"><span class="hex">5D</span><span class="ch">]</span><span class="dec">93</span></td>
|
||||
<td class="lower"><span class="hex">6D</span><span class="ch">m</span><span class="dec">109</span></td>
|
||||
<td class="punct"><span class="hex">7D</span><span class="ch">}</span><span class="dec">125</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th class="row">E<span class="b">1110</span></th>
|
||||
<td class="ctrl"><span class="hex">0E</span><span class="ch">SO</span><span class="dec">14</span></td>
|
||||
<td class="ctrl"><span class="hex">1E</span><span class="ch">RS</span><span class="dec">30</span></td>
|
||||
<td class="punct"><span class="hex">2E</span><span class="ch">.</span><span class="dec">46</span></td>
|
||||
<td class="punct"><span class="hex">3E</span><span class="ch">></span><span class="dec">62</span></td>
|
||||
<td class="upper"><span class="hex">4E</span><span class="ch">N</span><span class="dec">78</span></td>
|
||||
<td class="punct"><span class="hex">5E</span><span class="ch">^</span><span class="dec">94</span></td>
|
||||
<td class="lower"><span class="hex">6E</span><span class="ch">n</span><span class="dec">110</span></td>
|
||||
<td class="punct"><span class="hex">7E</span><span class="ch">~</span><span class="dec">126</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th class="row">F<span class="b">1111</span></th>
|
||||
<td class="ctrl"><span class="hex">0F</span><span class="ch">SI</span><span class="dec">15</span></td>
|
||||
<td class="ctrl"><span class="hex">1F</span><span class="ch">US</span><span class="dec">31</span></td>
|
||||
<td class="punct"><span class="hex">2F</span><span class="ch">/</span><span class="dec">47</span></td>
|
||||
<td class="punct"><span class="hex">3F</span><span class="ch">?</span><span class="dec">63</span></td>
|
||||
<td class="upper"><span class="hex">4F</span><span class="ch">O</span><span class="dec">79</span></td>
|
||||
<td class="punct"><span class="hex">5F</span><span class="ch">_</span><span class="dec">95</span></td>
|
||||
<td class="lower"><span class="hex">6F</span><span class="ch">o</span><span class="dec">111</span></td>
|
||||
<td class="del"><span class="hex">7F</span><span class="ch">DEL</span><span class="dec">127</span></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="legend">
|
||||
<div class="item"><span class="swatch ctrl"></span>Steuerzeichen (0–31)</div>
|
||||
<div class="item"><span class="swatch space"></span>Leerzeichen (32)</div>
|
||||
<div class="item"><span class="swatch punct"></span>Satzzeichen</div>
|
||||
<div class="item"><span class="swatch digit"></span>Ziffern (48–57)</div>
|
||||
<div class="item"><span class="swatch upper"></span>Großbuchstaben (65–90)</div>
|
||||
<div class="item"><span class="swatch lower"></span>Kleinbuchstaben (97–122)</div>
|
||||
<div class="item"><span class="swatch del"></span>DEL (127)</div>
|
||||
</div>
|
||||
|
||||
<div class="meta-row">
|
||||
<span><strong>Beispiel:</strong> <code>A</code> = Hex <code>41</code> = Dez <code>65</code> = Bin <code>0100 0001</code></span>
|
||||
<span><strong>Trick:</strong> Ziffern <code>0–9</code> liegen bei <code>30–39</code> · <code>'A'+1='B'</code> · Groß ↔ Klein: Bit 5 togglen</span>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,180 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Byte-Fluss: Bit → Hex → ASCII</title>
|
||||
<style>
|
||||
:root {
|
||||
--hl: #d63384;
|
||||
--dark: #1a1a2e;
|
||||
--muted: #6b7280;
|
||||
--border: #cbd5e1;
|
||||
--bg-soft: #f8fafc;
|
||||
--byte-border: #94a3b8;
|
||||
}
|
||||
html, body { margin: 0; padding: 0; background: #fff; font-family: system-ui, -apple-system, sans-serif; color: var(--dark); }
|
||||
body { padding: 22px 28px; }
|
||||
h1 { text-align: center; margin: 0 0 4px; font-size: 1.55rem; }
|
||||
.sub { text-align: center; color: var(--muted); margin-bottom: 18px; font-size: 0.95rem; }
|
||||
|
||||
.stage { display: flex; flex-direction: column; align-items: center; gap: 8px; max-width: 920px; margin: 0 auto; }
|
||||
|
||||
.file {
|
||||
width: 100%; box-sizing: border-box;
|
||||
border: 2px solid var(--dark);
|
||||
border-radius: 10px;
|
||||
background: var(--bg-soft);
|
||||
overflow: hidden;
|
||||
box-shadow: 0 6px 20px rgba(0,0,0,0.08);
|
||||
}
|
||||
.file .head {
|
||||
background: var(--dark); color: #fff; padding: 8px 14px;
|
||||
font-size: 0.82rem; text-transform: uppercase; letter-spacing: 0.08em; font-weight: 700;
|
||||
display: flex; justify-content: space-between; align-items: center;
|
||||
}
|
||||
.file .head .name { font-family: ui-monospace, monospace; }
|
||||
.file .head .meta { font-weight: 400; opacity: 0.7; text-transform: none; letter-spacing: 0; font-size: 0.85em; }
|
||||
.file .body { padding: 12px 14px; }
|
||||
|
||||
.row-bytes { display: flex; gap: 6px; margin-bottom: 6px; flex-wrap: nowrap; }
|
||||
.row-bytes:last-child { margin-bottom: 0; }
|
||||
|
||||
.byte-bin {
|
||||
border: 1px solid var(--byte-border);
|
||||
border-radius: 4px;
|
||||
padding: 4px 7px;
|
||||
font-family: ui-monospace, "SF Mono", Menlo, monospace;
|
||||
font-size: 0.92rem;
|
||||
font-weight: 700;
|
||||
background: #fff;
|
||||
letter-spacing: 0.04em;
|
||||
}
|
||||
.byte-hex {
|
||||
border: 1px solid var(--byte-border);
|
||||
border-radius: 4px;
|
||||
padding: 6px 0;
|
||||
font-family: ui-monospace, monospace;
|
||||
font-size: 1.1rem;
|
||||
font-weight: 700;
|
||||
background: #fff;
|
||||
min-width: 88px;
|
||||
text-align: center;
|
||||
}
|
||||
.byte-ascii {
|
||||
border: 1px solid var(--byte-border);
|
||||
border-radius: 4px;
|
||||
padding: 6px 0;
|
||||
font-family: ui-monospace, monospace;
|
||||
font-size: 1.2rem;
|
||||
font-weight: 700;
|
||||
background: #fff;
|
||||
min-width: 88px;
|
||||
text-align: center;
|
||||
}
|
||||
.byte-ascii.np { color: var(--muted); font-style: italic; }
|
||||
|
||||
.truncate { color: var(--muted); font-family: ui-monospace, monospace; padding: 4px 6px; font-weight: 700; align-self: center; }
|
||||
|
||||
.arrow-stack { display: flex; flex-direction: column; align-items: center; gap: 2px; padding: 4px 0; }
|
||||
.arrow {
|
||||
width: 0; height: 0;
|
||||
border-left: 11px solid transparent;
|
||||
border-right: 11px solid transparent;
|
||||
border-top: 14px solid var(--hl);
|
||||
}
|
||||
.arrow-label {
|
||||
font-size: 0.78rem; color: var(--hl); font-weight: 700;
|
||||
text-transform: uppercase; letter-spacing: 0.05em;
|
||||
}
|
||||
|
||||
.legend {
|
||||
margin-top: 12px;
|
||||
display: flex; gap: 14px; flex-wrap: wrap; justify-content: center;
|
||||
font-size: 0.85rem; color: var(--muted);
|
||||
}
|
||||
.legend strong { color: var(--dark); }
|
||||
.legend code { background: var(--bg-soft); border: 1px solid var(--border); padding: 1px 6px; border-radius: 3px; font-family: ui-monospace, monospace; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>1 Byte = 8 Bit = 2 Hex = 1 ASCII-Zeichen</h1>
|
||||
<div class="sub">Dieselbe Datei — dieselben Byte, drei Schreibweisen. Jeder Rahmen = ein Byte.</div>
|
||||
|
||||
<div class="stage">
|
||||
|
||||
<!-- Stage 1: Bitstream -->
|
||||
<div class="file">
|
||||
<div class="head"><span class="name">datei.bin</span><span class="meta">Roh-Bit · 8 Bit pro Rahmen</span></div>
|
||||
<div class="body">
|
||||
<div class="row-bytes">
|
||||
<span class="byte-bin">01001000</span><span class="byte-bin">01100101</span><span class="byte-bin">01101100</span><span class="byte-bin">01101100</span><span class="byte-bin">01101111</span><span class="byte-bin">00101100</span><span class="byte-bin">00100000</span><span class="byte-bin">01010111</span>
|
||||
</div>
|
||||
<div class="row-bytes">
|
||||
<span class="byte-bin">01101111</span><span class="byte-bin">01110010</span><span class="byte-bin">01101100</span><span class="byte-bin">01100100</span><span class="byte-bin">00100001</span><span class="byte-bin">00100000</span><span class="byte-bin">01001000</span><span class="byte-bin">01101111</span>
|
||||
</div>
|
||||
<div class="row-bytes">
|
||||
<span class="byte-bin">01110111</span><span class="byte-bin">00100000</span><span class="byte-bin">01100001</span><span class="byte-bin">01110010</span><span class="byte-bin">01100101</span><span class="byte-bin">00100000</span><span class="byte-bin">01111001</span><span class="byte-bin">01101111</span>
|
||||
</div>
|
||||
<div class="row-bytes">
|
||||
<span class="byte-bin">01110101</span><span class="byte-bin">00111111</span><span class="byte-bin">00001010</span><span class="truncate">… (weitere Byte)</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="arrow-stack">
|
||||
<div class="arrow-label">je 8 Bit → 2 Hex-Ziffern</div>
|
||||
<div class="arrow"></div>
|
||||
</div>
|
||||
|
||||
<!-- Stage 2: Hex -->
|
||||
<div class="file">
|
||||
<div class="head"><span class="name">datei.hex</span><span class="meta">Hex-Sicht · 2 Hex-Ziffern pro Rahmen</span></div>
|
||||
<div class="body">
|
||||
<div class="row-bytes">
|
||||
<span class="byte-hex">48</span><span class="byte-hex">65</span><span class="byte-hex">6C</span><span class="byte-hex">6C</span><span class="byte-hex">6F</span><span class="byte-hex">2C</span><span class="byte-hex">20</span><span class="byte-hex">57</span>
|
||||
</div>
|
||||
<div class="row-bytes">
|
||||
<span class="byte-hex">6F</span><span class="byte-hex">72</span><span class="byte-hex">6C</span><span class="byte-hex">64</span><span class="byte-hex">21</span><span class="byte-hex">20</span><span class="byte-hex">48</span><span class="byte-hex">6F</span>
|
||||
</div>
|
||||
<div class="row-bytes">
|
||||
<span class="byte-hex">77</span><span class="byte-hex">20</span><span class="byte-hex">61</span><span class="byte-hex">72</span><span class="byte-hex">65</span><span class="byte-hex">20</span><span class="byte-hex">79</span><span class="byte-hex">6F</span>
|
||||
</div>
|
||||
<div class="row-bytes">
|
||||
<span class="byte-hex">75</span><span class="byte-hex">3F</span><span class="byte-hex">0A</span><span class="truncate">…</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="arrow-stack">
|
||||
<div class="arrow-label">je 1 Byte → 1 Zeichen</div>
|
||||
<div class="arrow"></div>
|
||||
</div>
|
||||
|
||||
<!-- Stage 3: ASCII -->
|
||||
<div class="file">
|
||||
<div class="head"><span class="name">datei.txt</span><span class="meta">Text-Sicht · 1 ASCII-Zeichen pro Rahmen</span></div>
|
||||
<div class="body">
|
||||
<div class="row-bytes">
|
||||
<span class="byte-ascii">H</span><span class="byte-ascii">e</span><span class="byte-ascii">l</span><span class="byte-ascii">l</span><span class="byte-ascii">o</span><span class="byte-ascii">,</span><span class="byte-ascii np">␣</span><span class="byte-ascii">W</span>
|
||||
</div>
|
||||
<div class="row-bytes">
|
||||
<span class="byte-ascii">o</span><span class="byte-ascii">r</span><span class="byte-ascii">l</span><span class="byte-ascii">d</span><span class="byte-ascii">!</span><span class="byte-ascii np">␣</span><span class="byte-ascii">H</span><span class="byte-ascii">o</span>
|
||||
</div>
|
||||
<div class="row-bytes">
|
||||
<span class="byte-ascii">w</span><span class="byte-ascii np">␣</span><span class="byte-ascii">a</span><span class="byte-ascii">r</span><span class="byte-ascii">e</span><span class="byte-ascii np">␣</span><span class="byte-ascii">y</span><span class="byte-ascii">o</span>
|
||||
</div>
|
||||
<div class="row-bytes">
|
||||
<span class="byte-ascii">u</span><span class="byte-ascii">?</span><span class="byte-ascii np">↵</span><span class="truncate">…</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="legend">
|
||||
<span><code>␣</code> = Leerzeichen (0x20)</span>
|
||||
<span><code>↵</code> = Zeilenumbruch (0x0A, nicht druckbar)</span>
|
||||
<span><strong>Byte ändern sich nicht.</strong> Nur die Anzeige.</span>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
After Width: | Height: | Size: 77 KiB |
@@ -0,0 +1,117 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Byte für Byte — drei Brillen</title>
|
||||
<style>
|
||||
:root {
|
||||
--hl: #d63384;
|
||||
--dark: #1a1a2e;
|
||||
--muted: #6b7280;
|
||||
--border: #cbd5e1;
|
||||
--bg-soft: #f8fafc;
|
||||
--bin-bg: #0f0f23;
|
||||
--bin-fg: #e5e7eb;
|
||||
--binary-mark: #ef4444;
|
||||
--ascii-ok: #16a34a;
|
||||
--ctrl: #9ca3af;
|
||||
}
|
||||
html, body { margin: 0; padding: 0; background: #fff; font-family: system-ui, -apple-system, sans-serif; color: var(--dark); }
|
||||
body { padding: 28px 32px; }
|
||||
h1 { text-align: center; margin: 0 0 4px; font-size: 1.75rem; }
|
||||
.sub { text-align: center; color: var(--muted); margin-bottom: 22px; font-size: 1rem; }
|
||||
.sub code { font-family: ui-monospace, "SF Mono", Menlo, monospace; }
|
||||
|
||||
.windows { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 18px; max-width: 1180px; margin: 0 auto; }
|
||||
|
||||
.window { border: 2px solid var(--border); border-radius: 10px; overflow: hidden; display: flex; flex-direction: column; }
|
||||
.window-header { background: var(--bg-soft); padding: 10px 14px; border-bottom: 2px solid var(--border); display: flex; flex-direction: column; gap: 2px; }
|
||||
.window-title { font-size: 0.78rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.1em; color: var(--muted); }
|
||||
.window-name { font-size: 1.15rem; font-weight: 700; color: var(--dark); }
|
||||
|
||||
.window-body { padding: 14px 16px; flex: 1; display: flex; flex-direction: column; gap: 6px; font-family: ui-monospace, "SF Mono", Menlo, monospace; }
|
||||
|
||||
.window.bin .window-body { background: var(--bin-bg); }
|
||||
.window.bin .row { color: var(--bin-fg); font-size: 1.05rem; letter-spacing: 0.04em; }
|
||||
|
||||
.window.hex .row { color: var(--dark); font-size: 1.4rem; font-weight: 700; letter-spacing: 0.06em; }
|
||||
|
||||
.window.text .row { font-size: 1.4rem; font-weight: 700; display: flex; align-items: center; gap: 10px; }
|
||||
.window.text .glyph.printable { color: var(--ascii-ok); }
|
||||
.window.text .glyph.ctrl { color: var(--ctrl); font-size: 1.1rem; }
|
||||
.window.text .glyph.binary { color: var(--binary-mark); }
|
||||
.window.text .note { font-size: 0.78rem; font-weight: 400; color: var(--muted); margin-left: auto; }
|
||||
|
||||
.footnote { margin-top: 24px; max-width: 1100px; margin-left: auto; margin-right: auto; display: flex; gap: 32px; justify-content: center; font-size: 0.95rem; }
|
||||
.legend { display: flex; align-items: center; gap: 8px; }
|
||||
.swatch { display: inline-block; width: 16px; height: 16px; border-radius: 3px; }
|
||||
.swatch.binary { background: #fee2e2; border: 2px solid var(--binary-mark); }
|
||||
.swatch.ascii { background: #dcfce7; border: 2px solid var(--ascii-ok); }
|
||||
.verdict { margin-top: 14px; text-align: center; font-size: 1.05rem; color: var(--dark); }
|
||||
.verdict strong { color: var(--binary-mark); }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Byte für Byte</h1>
|
||||
<div class="sub">Eine Datei — drei Brillen. Beispiel: erste 8 Byte einer PNG-Datei.</div>
|
||||
|
||||
<div class="windows">
|
||||
|
||||
<div class="window bin">
|
||||
<div class="window-header">
|
||||
<div class="window-title">Fenster 1</div>
|
||||
<div class="window-name">Bin · rohe 0 und 1</div>
|
||||
</div>
|
||||
<div class="window-body">
|
||||
<div class="row">10001001</div>
|
||||
<div class="row">01010000</div>
|
||||
<div class="row">01001110</div>
|
||||
<div class="row">01000111</div>
|
||||
<div class="row">00001101</div>
|
||||
<div class="row">00001010</div>
|
||||
<div class="row">00011010</div>
|
||||
<div class="row">00001010</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="window hex">
|
||||
<div class="window-header">
|
||||
<div class="window-title">Fenster 2</div>
|
||||
<div class="window-name">Hex · 2 Ziffern pro Byte</div>
|
||||
</div>
|
||||
<div class="window-body">
|
||||
<div class="row">89</div>
|
||||
<div class="row">50</div>
|
||||
<div class="row">4E</div>
|
||||
<div class="row">47</div>
|
||||
<div class="row">0D</div>
|
||||
<div class="row">0A</div>
|
||||
<div class="row">1A</div>
|
||||
<div class="row">0A</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="window text">
|
||||
<div class="window-header">
|
||||
<div class="window-title">Fenster 3</div>
|
||||
<div class="window-name">Text · ASCII oder ✗ (> 126)</div>
|
||||
</div>
|
||||
<div class="window-body">
|
||||
<div class="row"><span class="glyph binary">✗</span><span class="note">137 > 126</span></div>
|
||||
<div class="row"><span class="glyph printable">P</span><span class="note">80</span></div>
|
||||
<div class="row"><span class="glyph printable">N</span><span class="note">78</span></div>
|
||||
<div class="row"><span class="glyph printable">G</span><span class="note">71</span></div>
|
||||
<div class="row"><span class="glyph ctrl">CR</span><span class="note">13 · Steuerz.</span></div>
|
||||
<div class="row"><span class="glyph ctrl">LF</span><span class="note">10 · Steuerz.</span></div>
|
||||
<div class="row"><span class="glyph ctrl">SUB</span><span class="note">26 · Steuerz.</span></div>
|
||||
<div class="row"><span class="glyph ctrl">LF</span><span class="note">10 · Steuerz.</span></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="verdict">
|
||||
Mindestens ein Byte mit Wert > 126 → <strong>Binärdatei</strong>. Sonst: reine Textdatei.
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
After Width: | Height: | Size: 56 KiB |
@@ -0,0 +1,185 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Byte → Nibble → Hex</title>
|
||||
<style>
|
||||
:root {
|
||||
--hl: #d63384;
|
||||
--dark: #1a1a2e;
|
||||
--muted: #6b7280;
|
||||
--border: #cbd5e1;
|
||||
--bg-soft: #f8fafc;
|
||||
}
|
||||
html, body { margin: 0; padding: 0; background: #fff; font-family: system-ui, -apple-system, sans-serif; color: var(--dark); }
|
||||
body { padding: 28px 32px; }
|
||||
h1 { text-align: center; margin: 0 0 4px; font-size: 1.55rem; }
|
||||
.sub { text-align: center; color: var(--muted); margin-bottom: 22px; font-size: 0.95rem; }
|
||||
|
||||
.stage { display: flex; flex-direction: column; align-items: center; gap: 6px; }
|
||||
|
||||
.level { display: flex; flex-direction: column; align-items: center; }
|
||||
.label { font-size: 0.78rem; color: var(--muted); text-transform: uppercase; letter-spacing: 0.08em; margin-bottom: 6px; font-weight: 600; }
|
||||
|
||||
/* Level 1: whole byte */
|
||||
.byte {
|
||||
display: flex;
|
||||
gap: 4px;
|
||||
padding: 8px 14px;
|
||||
border: 2px solid var(--dark);
|
||||
border-radius: 8px;
|
||||
background: var(--bg-soft);
|
||||
}
|
||||
.byte .bit { font-family: ui-monospace, "SF Mono", Menlo, monospace; font-size: 1.3rem; font-weight: 700; padding: 4px 8px; min-width: 22px; text-align: center; }
|
||||
.byte .sep { width: 2px; background: var(--hl); margin: 2px 6px; border-radius: 2px; }
|
||||
|
||||
/* Split arrows */
|
||||
.split { display: flex; justify-content: space-between; width: 360px; margin: 2px 0; }
|
||||
.split .arrow {
|
||||
width: 0; height: 0;
|
||||
border-left: 9px solid transparent;
|
||||
border-right: 9px solid transparent;
|
||||
border-top: 12px solid var(--hl);
|
||||
}
|
||||
|
||||
/* Level 2: two nibbles */
|
||||
.nibbles { display: flex; gap: 80px; }
|
||||
.nibble {
|
||||
display: flex; flex-direction: column; align-items: center; gap: 6px;
|
||||
padding: 10px 14px;
|
||||
border: 2px solid var(--hl);
|
||||
border-radius: 8px;
|
||||
background: #fff;
|
||||
}
|
||||
.nibble .bits { display: flex; gap: 4px; font-family: ui-monospace, monospace; font-size: 1.15rem; font-weight: 700; }
|
||||
.nibble .bits span { padding: 2px 6px; min-width: 20px; text-align: center; }
|
||||
.nibble .meta { font-size: 0.78rem; color: var(--muted); }
|
||||
|
||||
.single-arrow {
|
||||
width: 0; height: 0;
|
||||
border-left: 9px solid transparent;
|
||||
border-right: 9px solid transparent;
|
||||
border-top: 12px solid var(--hl);
|
||||
margin: 2px 0;
|
||||
}
|
||||
|
||||
/* Level 3: hex digits */
|
||||
.hex-digits { display: flex; gap: 80px; }
|
||||
.hex-digit {
|
||||
display: flex; flex-direction: column; align-items: center; gap: 4px;
|
||||
padding: 8px 22px;
|
||||
border: 2px solid var(--dark);
|
||||
border-radius: 8px;
|
||||
background: var(--dark);
|
||||
color: var(--hl);
|
||||
}
|
||||
.hex-digit .digit { font-family: ui-monospace, monospace; font-size: 2rem; font-weight: 800; line-height: 1; }
|
||||
.hex-digit .meta { font-size: 0.72rem; color: #f3f4f6; opacity: 0.7; }
|
||||
|
||||
/* Merge down to byte */
|
||||
.merge {
|
||||
display: flex; justify-content: center; margin-top: 2px;
|
||||
}
|
||||
.merge-v {
|
||||
display: grid;
|
||||
grid-template-columns: 60px 60px;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
.merge-v .line {
|
||||
height: 20px;
|
||||
border-right: 2px solid var(--hl);
|
||||
}
|
||||
.merge-v .line.l { border-right: none; border-left: 2px solid var(--hl); }
|
||||
.bottom-bar { height: 2px; background: var(--hl); width: 120px; }
|
||||
|
||||
/* Final result */
|
||||
.result {
|
||||
margin-top: 14px;
|
||||
padding: 14px 22px;
|
||||
background: #fef3f8;
|
||||
border-left: 4px solid var(--hl);
|
||||
border-radius: 4px;
|
||||
font-size: 1.05rem;
|
||||
text-align: center;
|
||||
max-width: 640px;
|
||||
}
|
||||
.result code { background: var(--dark); color: var(--hl); padding: 2px 8px; border-radius: 4px; font-family: ui-monospace, monospace; font-weight: 700; }
|
||||
.result strong { color: var(--hl); }
|
||||
|
||||
.math {
|
||||
margin-top: 10px;
|
||||
font-size: 0.95rem;
|
||||
color: var(--dark);
|
||||
text-align: center;
|
||||
}
|
||||
.math .eq { font-family: ui-monospace, monospace; font-weight: 700; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>1 Byte → 2 Nibble → 2 Hex-Ziffern</h1>
|
||||
<div class="sub">Jedes Byte lässt sich sauber halbieren – und 4 Bit passen exakt auf eine Hex-Ziffer.</div>
|
||||
|
||||
<div class="stage">
|
||||
<!-- Level 1 -->
|
||||
<div class="level">
|
||||
<div class="label">1 Byte · 8 Bit · 2⁸ = 256 Werte</div>
|
||||
<div class="byte">
|
||||
<span class="bit">0</span><span class="bit">1</span><span class="bit">0</span><span class="bit">0</span>
|
||||
<span class="sep"></span>
|
||||
<span class="bit">1</span><span class="bit">1</span><span class="bit">0</span><span class="bit">1</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="split">
|
||||
<div class="arrow"></div>
|
||||
<div class="arrow"></div>
|
||||
</div>
|
||||
|
||||
<!-- Level 2 -->
|
||||
<div class="level">
|
||||
<div class="label">2 Nibble · je 4 Bit · 2⁴ = 16 Werte</div>
|
||||
<div class="nibbles">
|
||||
<div class="nibble">
|
||||
<div class="bits"><span>0</span><span>1</span><span>0</span><span>0</span></div>
|
||||
<div class="meta">= 4 (dez)</div>
|
||||
</div>
|
||||
<div class="nibble">
|
||||
<div class="bits"><span>1</span><span>1</span><span>0</span><span>1</span></div>
|
||||
<div class="meta">= 13 (dez)</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="split">
|
||||
<div class="arrow"></div>
|
||||
<div class="arrow"></div>
|
||||
</div>
|
||||
|
||||
<!-- Level 3 -->
|
||||
<div class="level">
|
||||
<div class="label">2 Hex-Ziffern · Symbole 0–F</div>
|
||||
<div class="hex-digits">
|
||||
<div class="hex-digit">
|
||||
<div class="digit">4</div>
|
||||
<div class="meta">Nibble → 1 Ziffer</div>
|
||||
</div>
|
||||
<div class="hex-digit">
|
||||
<div class="digit">D</div>
|
||||
<div class="meta">13 → D</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="result">
|
||||
<code>01001101</code> (bin) = <code>4D</code> (hex) = <strong>77</strong> (dez) = <strong>"M"</strong> (ASCII)
|
||||
</div>
|
||||
|
||||
<div class="math">
|
||||
<span class="eq">16 × 16 = 256</span> · <span class="eq">2⁴ × 2⁴ = 2⁸</span> · Darum passt Hex so gut zu Bytes.
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
</content>
|
||||
</invoke>
|
||||
|
After Width: | Height: | Size: 97 KiB |
@@ -0,0 +1,172 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Container ≠ Codec</title>
|
||||
<style>
|
||||
:root {
|
||||
--dark: #1a1a2e;
|
||||
--muted: #6b7280;
|
||||
--soft: #f8fafc;
|
||||
--border: #cbd5e1;
|
||||
--hl: #d63384;
|
||||
--container: #2563eb;
|
||||
--video: #7c3aed;
|
||||
--audio: #ea580c;
|
||||
--subs: #16a34a;
|
||||
--meta: #94a3b8;
|
||||
}
|
||||
html, body { margin: 0; padding: 0; background: #fff; font-family: system-ui, -apple-system, sans-serif; color: var(--dark); }
|
||||
body { padding: 28px 40px; }
|
||||
h1 { text-align: center; margin: 0 0 6px; font-size: 1.75rem; }
|
||||
.sub { text-align: center; color: var(--muted); margin-bottom: 22px; font-size: 1.05rem; }
|
||||
.sub strong { color: var(--dark); }
|
||||
|
||||
.scene {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 22px;
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.container-box {
|
||||
border: 3px dashed var(--container);
|
||||
border-radius: 14px;
|
||||
padding: 14px 16px 18px;
|
||||
background: #fff;
|
||||
position: relative;
|
||||
}
|
||||
.container-tag {
|
||||
position: absolute;
|
||||
top: -12px;
|
||||
left: 18px;
|
||||
background: #fff;
|
||||
padding: 0 10px;
|
||||
font-family: ui-monospace, monospace;
|
||||
font-size: 0.78rem;
|
||||
font-weight: 700;
|
||||
color: var(--container);
|
||||
}
|
||||
.container-label {
|
||||
text-align: center;
|
||||
font-size: 0.7rem;
|
||||
font-weight: 700;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.12em;
|
||||
color: var(--muted);
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.track {
|
||||
display: grid;
|
||||
grid-template-columns: 90px 1fr;
|
||||
gap: 12px;
|
||||
align-items: center;
|
||||
background: var(--soft);
|
||||
border-left: 4px solid;
|
||||
border-radius: 6px;
|
||||
padding: 9px 14px;
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
.track.video { border-left-color: var(--video); }
|
||||
.track.audio { border-left-color: var(--audio); }
|
||||
.track.subs { border-left-color: var(--subs); }
|
||||
.track.meta { border-left-color: var(--meta); }
|
||||
|
||||
.track-label {
|
||||
font-size: 0.78rem;
|
||||
font-weight: 700;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.08em;
|
||||
}
|
||||
.track.video .track-label { color: var(--video); }
|
||||
.track.audio .track-label { color: var(--audio); }
|
||||
.track.subs .track-label { color: var(--subs); }
|
||||
.track.meta .track-label { color: var(--meta); }
|
||||
|
||||
.codec-pill {
|
||||
display: inline-block;
|
||||
font-family: ui-monospace, monospace;
|
||||
font-size: 0.82rem;
|
||||
background: #fff;
|
||||
border: 1px solid var(--border);
|
||||
padding: 2px 9px;
|
||||
border-radius: 4px;
|
||||
color: var(--dark);
|
||||
}
|
||||
|
||||
.verdict {
|
||||
margin-top: 22px;
|
||||
max-width: 1200px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
text-align: center;
|
||||
border: 2px solid var(--hl);
|
||||
border-radius: 12px;
|
||||
padding: 14px 22px;
|
||||
}
|
||||
.verdict-q { font-size: 1.1rem; font-weight: 700; color: var(--hl); }
|
||||
.verdict-a { font-size: 0.93rem; color: var(--dark); margin-top: 4px; }
|
||||
.verdict-a strong { color: var(--hl); }
|
||||
.verdict-a code { font-family: ui-monospace, monospace; background: var(--soft); padding: 1px 5px; border-radius: 4px; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Container ≠ Codec</h1>
|
||||
<div class="sub">Die <strong>Hülle</strong> sagt nichts darüber, <strong>wie</strong> der Inhalt komprimiert wurde.</div>
|
||||
|
||||
<div class="scene">
|
||||
|
||||
<div class="container-box">
|
||||
<span class="container-tag">.mp4</span>
|
||||
<div class="container-label">Datei A — älterer Stand</div>
|
||||
|
||||
<div class="track video">
|
||||
<span class="track-label">Video</span>
|
||||
<span><span class="codec-pill">H.264 / AVC</span> · 1080p · 8 Mbit/s</span>
|
||||
</div>
|
||||
<div class="track audio">
|
||||
<span class="track-label">Audio</span>
|
||||
<span><span class="codec-pill">AAC</span> · 192 kbit/s · Stereo</span>
|
||||
</div>
|
||||
<div class="track subs">
|
||||
<span class="track-label">Untertitel</span>
|
||||
<span><span class="codec-pill">TTML</span> · de + en</span>
|
||||
</div>
|
||||
<div class="track meta">
|
||||
<span class="track-label">Metadaten</span>
|
||||
<span>Titel · Dauer · Datum · Bitrate</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="container-box">
|
||||
<span class="container-tag">.mp4</span>
|
||||
<div class="container-label">Datei B — modern</div>
|
||||
|
||||
<div class="track video">
|
||||
<span class="track-label">Video</span>
|
||||
<span><span class="codec-pill">AV1</span> · 4K · 25 Mbit/s</span>
|
||||
</div>
|
||||
<div class="track audio">
|
||||
<span class="track-label">Audio</span>
|
||||
<span><span class="codec-pill">Opus</span> · 128 kbit/s · 5.1 Surround</span>
|
||||
</div>
|
||||
<div class="track subs">
|
||||
<span class="track-label">Untertitel</span>
|
||||
<span><span class="codec-pill">WebVTT</span> · de + en + ja</span>
|
||||
</div>
|
||||
<div class="track meta">
|
||||
<span class="track-label">Metadaten</span>
|
||||
<span>Titel · Dauer · Datum · HDR-Info</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="verdict">
|
||||
<div class="verdict-q">Gleiche Endung. Anderes Innenleben.</div>
|
||||
<div class="verdict-a"><strong>Container</strong> = Verpackung (<code>.mp4</code>, <code>.mkv</code>, <code>.webm</code>). <strong>Codec</strong> = Komprimierer (H.264 / AV1 / AAC / Opus). <strong>Tool:</strong> <code>mediainfo <datei></code> zeigt beides.</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
After Width: | Height: | Size: 62 KiB |
@@ -0,0 +1,200 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Drei Dateien — dasselbe Innenleben</title>
|
||||
<style>
|
||||
:root {
|
||||
--dark: #1a1a2e;
|
||||
--muted: #6b7280;
|
||||
--soft: #f8fafc;
|
||||
--border: #cbd5e1;
|
||||
--hl: #d63384;
|
||||
--foto: #2563eb;
|
||||
--audio: #ea580c;
|
||||
--pdf: #7c3aed;
|
||||
}
|
||||
html, body { margin: 0; padding: 0; background: #fff; font-family: system-ui, -apple-system, sans-serif; color: var(--dark); }
|
||||
body { padding: 32px 40px; }
|
||||
h1 { text-align: center; margin: 0 0 6px; font-size: 1.85rem; }
|
||||
.sub { text-align: center; color: var(--muted); margin-bottom: 28px; font-size: 1.05rem; }
|
||||
.sub strong { color: var(--dark); }
|
||||
|
||||
.files {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr 1fr;
|
||||
gap: 22px;
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.file {
|
||||
border: 2px solid;
|
||||
border-radius: 12px;
|
||||
padding: 16px 18px;
|
||||
background: #fff;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 12px;
|
||||
}
|
||||
.file.foto { border-color: var(--foto); }
|
||||
.file.audio { border-color: var(--audio); }
|
||||
.file.pdf { border-color: var(--pdf); }
|
||||
|
||||
.file-head { display: flex; justify-content: space-between; align-items: baseline; }
|
||||
.file-name { font-size: 1.2rem; font-weight: 700; }
|
||||
.file.foto .file-name { color: var(--foto); }
|
||||
.file.audio .file-name { color: var(--audio); }
|
||||
.file.pdf .file-name { color: var(--pdf); }
|
||||
.file-ext { font-family: ui-monospace, monospace; font-size: 0.78rem; color: var(--muted); }
|
||||
|
||||
.preview {
|
||||
border-radius: 8px;
|
||||
border: 1px solid var(--border);
|
||||
overflow: hidden;
|
||||
display: block;
|
||||
height: 130px;
|
||||
background: var(--soft);
|
||||
}
|
||||
|
||||
.hex-strip {
|
||||
background: #0f0f23;
|
||||
border-radius: 6px;
|
||||
padding: 8px 10px;
|
||||
font-family: ui-monospace, monospace;
|
||||
font-size: 0.78rem;
|
||||
line-height: 1.6;
|
||||
color: #cbd5e1;
|
||||
overflow: hidden;
|
||||
}
|
||||
.hex-strip .magic { color: #fff; font-weight: 700; padding: 0 2px; border-radius: 2px; }
|
||||
.hex-strip.foto-magic .magic { background: var(--foto); }
|
||||
.hex-strip.audio-magic .magic { background: var(--audio); }
|
||||
.hex-strip.pdf-magic .magic { background: var(--pdf); }
|
||||
.hex-label {
|
||||
font-size: 0.68rem;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.1em;
|
||||
color: var(--muted);
|
||||
font-weight: 700;
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
.magic-caption {
|
||||
font-size: 0.78rem;
|
||||
color: var(--muted);
|
||||
text-align: center;
|
||||
font-family: ui-monospace, monospace;
|
||||
}
|
||||
.magic-caption .magic-word {
|
||||
color: var(--dark);
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.verdict {
|
||||
margin-top: 26px;
|
||||
max-width: 1200px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
text-align: center;
|
||||
border: 2px solid var(--hl);
|
||||
border-radius: 12px;
|
||||
padding: 14px 22px;
|
||||
}
|
||||
.verdict-q { font-size: 1.15rem; font-weight: 700; color: var(--hl); }
|
||||
.verdict-a { font-size: 0.95rem; color: var(--dark); margin-top: 4px; }
|
||||
.verdict-a strong { color: var(--hl); }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Drei Dateien — dasselbe Innenleben</h1>
|
||||
<div class="sub">Außen <strong>völlig verschieden</strong>. Innen reden alle dieselbe Sprache: <strong>Byte für Byte</strong>.</div>
|
||||
|
||||
<div class="files">
|
||||
|
||||
<div class="file foto">
|
||||
<div class="file-head">
|
||||
<span class="file-name">Foto</span>
|
||||
<span class="file-ext">.png</span>
|
||||
</div>
|
||||
<svg class="preview" viewBox="0 0 220 130" preserveAspectRatio="xMidYMid slice">
|
||||
<defs>
|
||||
<linearGradient id="sky-f" x1="0" y1="0" x2="0" y2="1">
|
||||
<stop offset="0%" stop-color="#fde68a"/>
|
||||
<stop offset="60%" stop-color="#fb923c"/>
|
||||
<stop offset="100%" stop-color="#7c3aed"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<rect x="0" y="0" width="220" height="130" fill="url(#sky-f)"/>
|
||||
<circle cx="160" cy="50" r="18" fill="#fef3c7" opacity="0.95"/>
|
||||
<path d="M0,95 L40,80 L80,90 L120,72 L160,86 L220,75 L220,130 L0,130 Z" fill="#1e1b4b"/>
|
||||
<path d="M0,110 L60,100 L120,108 L180,98 L220,105 L220,130 L0,130 Z" fill="#0f172a" opacity="0.7"/>
|
||||
</svg>
|
||||
<div>
|
||||
<div class="hex-label">Erste Bytes der Datei</div>
|
||||
<div class="hex-strip foto-magic">
|
||||
<span class="magic">89 50 4E 47</span> 0D 0A 1A 0A 00 00 00 0D 49 48 44 52
|
||||
</div>
|
||||
</div>
|
||||
<div class="magic-caption"><span class="magic-word">50 4E 47</span> = <span class="magic-word">"PNG"</span></div>
|
||||
</div>
|
||||
|
||||
<div class="file audio">
|
||||
<div class="file-head">
|
||||
<span class="file-name">Sprachnachricht</span>
|
||||
<span class="file-ext">.mp3</span>
|
||||
</div>
|
||||
<svg class="preview" viewBox="0 0 220 130" preserveAspectRatio="none">
|
||||
<rect x="0" y="0" width="220" height="130" fill="#0f0f23"/>
|
||||
<line x1="0" y1="65" x2="220" y2="65" stroke="#374151" stroke-width="1"/>
|
||||
<path d="M0,65 L8,65 L12,55 L16,75 L20,40 L24,90 L28,30 L32,95 L36,35 L40,90
|
||||
L48,45 L56,82 L64,50 L72,78 L80,52 L88,75 L96,55 L104,72
|
||||
L116,58 L128,72 L140,60 L152,70 L168,62 L184,68 L200,64 L220,65
|
||||
L220,130 L0,130 Z" fill="#fb923c" stroke="#ea580c" stroke-width="1"/>
|
||||
</svg>
|
||||
<div>
|
||||
<div class="hex-label">Erste Bytes der Datei</div>
|
||||
<div class="hex-strip audio-magic">
|
||||
<span class="magic">49 44 33</span> 03 00 00 00 00 03 76 54 49 54 32 00 00
|
||||
</div>
|
||||
</div>
|
||||
<div class="magic-caption"><span class="magic-word">49 44 33</span> = <span class="magic-word">"ID3"</span></div>
|
||||
</div>
|
||||
|
||||
<div class="file pdf">
|
||||
<div class="file-head">
|
||||
<span class="file-name">PDF-Dokument</span>
|
||||
<span class="file-ext">.pdf</span>
|
||||
</div>
|
||||
<svg class="preview" viewBox="0 0 220 130" preserveAspectRatio="xMidYMid meet">
|
||||
<rect x="0" y="0" width="220" height="130" fill="#f8fafc"/>
|
||||
<rect x="50" y="14" width="120" height="102" rx="4" fill="#fff" stroke="#cbd5e1" stroke-width="1"/>
|
||||
<rect x="58" y="24" width="80" height="4" rx="1" fill="#7c3aed"/>
|
||||
<rect x="58" y="34" width="104" height="2" fill="#cbd5e1"/>
|
||||
<rect x="58" y="40" width="98" height="2" fill="#cbd5e1"/>
|
||||
<rect x="58" y="46" width="92" height="2" fill="#cbd5e1"/>
|
||||
<rect x="58" y="52" width="100" height="2" fill="#cbd5e1"/>
|
||||
<rect x="58" y="62" width="80" height="2" fill="#cbd5e1"/>
|
||||
<rect x="58" y="68" width="96" height="2" fill="#cbd5e1"/>
|
||||
<rect x="58" y="74" width="88" height="2" fill="#cbd5e1"/>
|
||||
<rect x="58" y="84" width="40" height="3" rx="1" fill="#7c3aed" opacity="0.7"/>
|
||||
<rect x="58" y="92" width="92" height="2" fill="#cbd5e1"/>
|
||||
<rect x="58" y="98" width="86" height="2" fill="#cbd5e1"/>
|
||||
<rect x="58" y="104" width="78" height="2" fill="#cbd5e1"/>
|
||||
</svg>
|
||||
<div>
|
||||
<div class="hex-label">Erste Bytes der Datei</div>
|
||||
<div class="hex-strip pdf-magic">
|
||||
<span class="magic">25 50 44 46</span> 2D 31 2E 37 0A 25 E2 E3 CF D3 0A 0A
|
||||
</div>
|
||||
</div>
|
||||
<div class="magic-caption"><span class="magic-word">25 50 44 46</span> = <span class="magic-word">"%PDF"</span></div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="verdict">
|
||||
<div class="verdict-q">Drei verschiedene Dinge — eine Sprache.</div>
|
||||
<div class="verdict-a">Jede Datei beginnt mit ihrer <strong>Visitenkarte</strong> (Magic Number) und besteht ab da aus nichts als Byte. Foto, Audio, PDF — alle dieselben Bauteile, nur anders zusammengesetzt.</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
After Width: | Height: | Size: 77 KiB |
@@ -0,0 +1,67 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Hex → Dezimal</title>
|
||||
<style>
|
||||
html, body { margin: 0; padding: 0; background: #fff; font-family: system-ui, -apple-system, sans-serif; }
|
||||
body { padding: 28px; }
|
||||
h1 { text-align: center; margin: 0 0 4px; font-size: 1.6rem; color: #1a1a2e; }
|
||||
.sub { text-align: center; color: #6b7280; margin-bottom: 18px; font-size: 0.95rem; }
|
||||
table { border-collapse: collapse; margin: 0 auto; font-variant-numeric: tabular-nums; }
|
||||
th, td { border: 1px solid #cbd5e1; padding: 7px 10px; text-align: center; font-size: 0.95rem; }
|
||||
thead th { background: #1a1a2e; color: #fff; }
|
||||
tbody th { background: #334155; color: #fff; font-weight: 600; }
|
||||
tbody td.ascii { background: #f3f4f6; }
|
||||
tbody td.nonascii { background: #fff; color: #6b7280; }
|
||||
.corner { background: #0f0f23; color: #d63384; }
|
||||
.legend { display: flex; justify-content: center; gap: 24px; margin-top: 16px; font-size: 0.9rem; color: #374151; }
|
||||
.sw { display: inline-block; width: 14px; height: 14px; border: 1px solid #cbd5e1; vertical-align: middle; margin-right: 6px; }
|
||||
.example { margin: 20px auto 0; max-width: 720px; padding: 14px 18px; background: #fef3f8; border-left: 4px solid #d63384; border-radius: 4px; font-size: 1rem; color: #1a1a2e; }
|
||||
code { background: #1a1a2e; color: #d63384; padding: 2px 6px; border-radius: 3px; font-family: ui-monospace, monospace; font-weight: 700; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Hex → Dezimal</h1>
|
||||
<div class="sub">Dezimalwert = (Zeile × 16) + Spalte</div>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="corner">×16 / +</th>
|
||||
<th>0</th><th>1</th><th>2</th><th>3</th><th>4</th><th>5</th><th>6</th><th>7</th>
|
||||
<th>8</th><th>9</th><th>A <small style="opacity:.7;font-weight:400">(10)</small></th><th>B <small style="opacity:.7;font-weight:400">(11)</small></th><th>C <small style="opacity:.7;font-weight:400">(12)</small></th><th>D <small style="opacity:.7;font-weight:400">(13)</small></th><th>E <small style="opacity:.7;font-weight:400">(14)</small></th><th>F <small style="opacity:.7;font-weight:400">(15)</small></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<div class="legend">
|
||||
<span><span class="sw" style="background:#f3f4f6"></span>ASCII (0–127)</span>
|
||||
<span><span class="sw" style="background:#fff"></span>Non-ASCII (128–255)</span>
|
||||
</div>
|
||||
|
||||
<div class="example">
|
||||
<strong>Beispiel:</strong> <code>4D</code> → Zeile <code>4</code> × 16 + Spalte <code>D</code> = 64 + 13 = <strong>77</strong> (= "M" in ASCII)
|
||||
</div>
|
||||
|
||||
<script>
|
||||
const rows = '0123456789ABCDEF';
|
||||
const tb = document.querySelector('tbody');
|
||||
for (let r = 0; r < 16; r++) {
|
||||
const tr = document.createElement('tr');
|
||||
const th = document.createElement('th');
|
||||
th.innerHTML = r >= 10 ? rows[r] + ' <small style="opacity:.7;font-weight:400">('+r+')</small>' : rows[r];
|
||||
tr.appendChild(th);
|
||||
for (let c = 0; c < 16; c++) {
|
||||
const td = document.createElement('td');
|
||||
const v = r*16 + c;
|
||||
td.textContent = v;
|
||||
td.className = v <= 127 ? 'ascii' : 'nonascii';
|
||||
tr.appendChild(td);
|
||||
}
|
||||
tb.appendChild(tr);
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
After Width: | Height: | Size: 275 KiB |
@@ -0,0 +1,206 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>JPEG-Pipeline — 6 Schritte vom Foto zur Datei</title>
|
||||
<style>
|
||||
:root {
|
||||
--dark: #1a1a2e;
|
||||
--muted: #6b7280;
|
||||
--soft: #f8fafc;
|
||||
--border: #cbd5e1;
|
||||
--hl: #d63384;
|
||||
--lossless-step: #2563eb;
|
||||
--lossy-step: #ea580c;
|
||||
}
|
||||
html, body { margin: 0; padding: 0; background: #fff; font-family: system-ui, -apple-system, sans-serif; color: var(--dark); }
|
||||
body { padding: 28px 40px; }
|
||||
h1 { text-align: center; margin: 0 0 6px; font-size: 1.75rem; }
|
||||
.sub { text-align: center; color: var(--muted); margin-bottom: 26px; font-size: 1.05rem; }
|
||||
.sub strong { color: var(--dark); }
|
||||
|
||||
.pipeline {
|
||||
display: grid;
|
||||
grid-template-columns: 110px repeat(6, 1fr) 110px;
|
||||
gap: 4px;
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
align-items: stretch;
|
||||
}
|
||||
|
||||
.endpoint {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 6px;
|
||||
text-align: center;
|
||||
}
|
||||
.endpoint-art { width: 88px; height: 60px; display: block; }
|
||||
.endpoint-label {
|
||||
font-size: 0.92rem;
|
||||
font-weight: 700;
|
||||
color: var(--dark);
|
||||
}
|
||||
.endpoint-size {
|
||||
font-family: ui-monospace, monospace;
|
||||
font-size: 0.82rem;
|
||||
color: var(--muted);
|
||||
}
|
||||
|
||||
.step {
|
||||
border: 2px solid;
|
||||
border-radius: 8px;
|
||||
padding: 8px 6px;
|
||||
background: #fff;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
text-align: center;
|
||||
}
|
||||
.step.lossless { border-color: var(--lossless-step); }
|
||||
.step.lossy { border-color: var(--lossy-step); }
|
||||
.step-num {
|
||||
font-family: ui-monospace, monospace;
|
||||
font-size: 0.72rem;
|
||||
font-weight: 700;
|
||||
color: var(--muted);
|
||||
}
|
||||
.step-name {
|
||||
font-size: 0.78rem;
|
||||
font-weight: 700;
|
||||
line-height: 1.2;
|
||||
}
|
||||
.step.lossless .step-name { color: var(--lossless-step); }
|
||||
.step.lossy .step-name { color: var(--lossy-step); }
|
||||
.step-desc {
|
||||
font-size: 0.66rem;
|
||||
color: var(--muted);
|
||||
line-height: 1.3;
|
||||
}
|
||||
|
||||
.arrow {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: var(--muted);
|
||||
font-family: ui-monospace, monospace;
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
.legend {
|
||||
margin-top: 16px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
gap: 24px;
|
||||
font-size: 0.84rem;
|
||||
color: var(--dark);
|
||||
}
|
||||
.legend-item { display: flex; align-items: center; gap: 6px; }
|
||||
.legend-swatch {
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
border-radius: 3px;
|
||||
display: inline-block;
|
||||
}
|
||||
.legend-swatch.lossless { background: var(--lossless-step); }
|
||||
.legend-swatch.lossy { background: var(--lossy-step); }
|
||||
|
||||
.verdict {
|
||||
margin-top: 22px;
|
||||
max-width: 1200px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
text-align: center;
|
||||
border: 2px solid var(--hl);
|
||||
border-radius: 12px;
|
||||
padding: 14px 22px;
|
||||
}
|
||||
.verdict-q { font-size: 1.1rem; font-weight: 700; color: var(--hl); }
|
||||
.verdict-a { font-size: 0.93rem; color: var(--dark); margin-top: 4px; }
|
||||
.verdict-a strong { color: var(--hl); }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>JPEG-Pipeline — 6 Schritte vom Foto zur Datei</h1>
|
||||
<div class="sub">Nur <strong>einer</strong> dieser Schritte verliert Information. Die anderen fünf sind verlustfrei.</div>
|
||||
|
||||
<div class="pipeline">
|
||||
|
||||
<div class="endpoint">
|
||||
<svg class="endpoint-art" viewBox="0 0 88 60">
|
||||
<defs>
|
||||
<linearGradient id="photo-grad" x1="0" y1="0" x2="0" y2="1">
|
||||
<stop offset="0%" stop-color="#fde68a"/>
|
||||
<stop offset="55%" stop-color="#fb923c"/>
|
||||
<stop offset="100%" stop-color="#7c3aed"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<rect x="0" y="0" width="88" height="60" rx="3" fill="url(#photo-grad)"/>
|
||||
<circle cx="66" cy="22" r="9" fill="#fef3c7"/>
|
||||
<path d="M0,42 L18,34 L40,40 L60,30 L80,38 L88,33 L88,60 L0,60 Z" fill="#1e1b4b"/>
|
||||
</svg>
|
||||
<div class="endpoint-label">Foto (Roh)</div>
|
||||
<div class="endpoint-size">~36 MB</div>
|
||||
</div>
|
||||
|
||||
<div class="step lossless">
|
||||
<div class="step-num">1</div>
|
||||
<div class="step-name">Farbraum</div>
|
||||
<div class="step-desc">RGB → Y'CbCr<br>Helligkeit von Farbe trennen</div>
|
||||
</div>
|
||||
|
||||
<div class="step lossy">
|
||||
<div class="step-num">2</div>
|
||||
<div class="step-name">Chroma-Subsampling</div>
|
||||
<div class="step-desc">Cb & Cr auf <strong>¼</strong><br>Auge sieht Farbe grob</div>
|
||||
</div>
|
||||
|
||||
<div class="step lossless">
|
||||
<div class="step-num">3</div>
|
||||
<div class="step-name">8×8 Blöcke</div>
|
||||
<div class="step-desc">Bild in Kacheln<br>jeder Block einzeln</div>
|
||||
</div>
|
||||
|
||||
<div class="step lossless">
|
||||
<div class="step-num">4</div>
|
||||
<div class="step-name">DCT</div>
|
||||
<div class="step-desc">Frequenz-Zerlegung<br>häufige Muster</div>
|
||||
</div>
|
||||
|
||||
<div class="step lossy">
|
||||
<div class="step-num">5</div>
|
||||
<div class="step-name">Quantisierung</div>
|
||||
<div class="step-desc"><strong>Hier</strong> wird weggeworfen<br>hohe Frequenzen raus</div>
|
||||
</div>
|
||||
|
||||
<div class="step lossless">
|
||||
<div class="step-num">6</div>
|
||||
<div class="step-name">Huffman</div>
|
||||
<div class="step-desc">Verlustfrei kürzen<br>häufig → kurz</div>
|
||||
</div>
|
||||
|
||||
<div class="endpoint">
|
||||
<svg class="endpoint-art" viewBox="0 0 88 60">
|
||||
<rect x="0" y="0" width="88" height="60" rx="3" fill="url(#photo-grad)"/>
|
||||
<circle cx="66" cy="22" r="9" fill="#fef3c7"/>
|
||||
<path d="M0,42 L18,34 L40,40 L60,30 L80,38 L88,33 L88,60 L0,60 Z" fill="#1e1b4b"/>
|
||||
</svg>
|
||||
<div class="endpoint-label">JPEG</div>
|
||||
<div class="endpoint-size">~3,5 MB</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="legend">
|
||||
<span class="legend-item"><span class="legend-swatch lossless"></span>verlustfrei (umkehrbar)</span>
|
||||
<span class="legend-item"><span class="legend-swatch lossy"></span>verlustbehaftet (Information weg)</span>
|
||||
</div>
|
||||
|
||||
<div class="verdict">
|
||||
<div class="verdict-q">Der <strong>Quanten-Schritt</strong> ist das ganze Geheimnis von JPEG.</div>
|
||||
<div class="verdict-a">Schritte 1, 3, 4, 6 verlieren nichts. Schritt 2 wirft Farb-Detail weg (Auge merkt nicht). Schritt 5 entscheidet — je nach Qualitäts-Stufe — wie viel <strong>Frequenz-Detail</strong> verloren geht. Niedrige Quality = aggressivere Schritt-5-Quantisierung.</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
After Width: | Height: | Size: 71 KiB |
@@ -0,0 +1,158 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Dieselbe Aufnahme, zwei Formate</title>
|
||||
<style>
|
||||
:root {
|
||||
--dark: #1a1a2e;
|
||||
--muted: #6b7280;
|
||||
--soft: #f8fafc;
|
||||
--border: #cbd5e1;
|
||||
--hl: #d63384;
|
||||
--lossless: #16a34a;
|
||||
--lossy: #ef4444;
|
||||
}
|
||||
html, body { margin: 0; padding: 0; background: #fff; font-family: system-ui, -apple-system, sans-serif; color: var(--dark); }
|
||||
body { padding: 36px 48px; }
|
||||
h1 { text-align: center; margin: 0 0 6px; font-size: 1.85rem; }
|
||||
.sub { text-align: center; color: var(--muted); margin-bottom: 28px; font-size: 1.05rem; }
|
||||
|
||||
.grid { display: grid; grid-template-columns: 1fr 1fr; gap: 26px; max-width: 1200px; margin: 0 auto; }
|
||||
.panel { border: 2px solid var(--border); border-radius: 12px; padding: 22px 24px; display: flex; flex-direction: column; gap: 14px; background: #fff; }
|
||||
.panel.left { border-color: var(--lossless); }
|
||||
.panel.right { border-color: var(--lossy); }
|
||||
|
||||
.panel-head { display: flex; justify-content: space-between; align-items: baseline; }
|
||||
.panel-tag {
|
||||
font-size: 0.74rem;
|
||||
font-weight: 700;
|
||||
letter-spacing: 0.12em;
|
||||
text-transform: uppercase;
|
||||
color: var(--muted);
|
||||
}
|
||||
.panel-name { font-size: 1.5rem; font-weight: 700; }
|
||||
.panel.left .panel-name { color: var(--lossless); }
|
||||
.panel.right .panel-name { color: var(--lossy); }
|
||||
.panel-format {
|
||||
font-family: ui-monospace, "SF Mono", Menlo, monospace;
|
||||
font-size: 0.85rem;
|
||||
color: var(--muted);
|
||||
}
|
||||
|
||||
.waveform {
|
||||
background: #0f0f23;
|
||||
border-radius: 8px;
|
||||
padding: 6px;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.stats { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
|
||||
.stat { background: var(--soft); border: 1px solid var(--border); border-radius: 7px; padding: 8px 12px; }
|
||||
.stat .label { font-size: 0.7rem; text-transform: uppercase; letter-spacing: 0.08em; color: var(--muted); font-weight: 700; }
|
||||
.stat .value { font-family: ui-monospace, "SF Mono", Menlo, monospace; font-size: 1rem; font-weight: 700; color: var(--dark); margin-top: 2px; }
|
||||
|
||||
.verdict {
|
||||
margin-top: 26px;
|
||||
border: 2px solid var(--hl);
|
||||
background: #fff;
|
||||
border-radius: 12px;
|
||||
padding: 16px 22px;
|
||||
text-align: center;
|
||||
max-width: 1200px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
.verdict-q { font-size: 1.2rem; font-weight: 700; color: var(--hl); }
|
||||
.verdict-a { font-size: 1rem; color: var(--dark); margin-top: 6px; }
|
||||
.verdict-a strong { color: var(--hl); }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Dieselbe Aufnahme, zwei Formate</h1>
|
||||
<div class="sub">3 Sekunden Snare-Hit mit Cymbal-Tail · 44,1 kHz Sample-Rate · Stereo</div>
|
||||
|
||||
<div class="grid">
|
||||
|
||||
<div class="panel left">
|
||||
<div class="panel-head">
|
||||
<span class="panel-name">Lossless</span>
|
||||
<span class="panel-tag">FLAC</span>
|
||||
</div>
|
||||
<div class="panel-format">verlustfrei · alle Frequenzen 0–22 kHz erhalten</div>
|
||||
|
||||
<svg class="waveform" viewBox="0 0 800 160" preserveAspectRatio="none">
|
||||
<defs>
|
||||
<linearGradient id="green-grad" x1="0" y1="0" x2="0" y2="1">
|
||||
<stop offset="0%" stop-color="#34d399"/>
|
||||
<stop offset="100%" stop-color="#16a34a"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<line x1="0" y1="80" x2="800" y2="80" stroke="#374151" stroke-width="1"/>
|
||||
<!-- detailed waveform: transient peak + cymbal decay with high-freq noise -->
|
||||
<path d="M0,80
|
||||
L40,80 L42,78 L44,82 L46,74 L48,88
|
||||
L60,30 L62,135 L64,18 L66,142 L68,28 L70,128 L72,38 L74,118 L76,48 L78,108
|
||||
L90,55 L92,108 L94,52 L96,112 L98,58 L100,105 L102,62 L104,98 L106,68 L108,92
|
||||
L130,72 L132,92 L134,68 L136,94 L138,72 L140,90 L142,74 L144,88
|
||||
L170,76 L172,86 L174,74 L176,87 L178,76 L180,85
|
||||
L220,77 L222,84 L224,76 L226,85 L228,77 L230,83
|
||||
L280,78 L282,83 L284,77 L286,84 L288,78 L290,82
|
||||
L340,79 L342,82 L344,78 L346,82 L348,79 L350,81
|
||||
L400,79 L402,81 L404,79 L406,81 L408,79 L410,81
|
||||
L460,80 L462,81 L464,79 L466,81 L468,80 L470,80
|
||||
L520,80 L522,81 L524,79 L526,80
|
||||
L580,80 L582,80 L584,80
|
||||
L640,80 L700,80 L800,80 Z"
|
||||
fill="url(#green-grad)" stroke="#16a34a" stroke-width="1" opacity="0.95"/>
|
||||
</svg>
|
||||
|
||||
<div class="stats">
|
||||
<div class="stat"><div class="label">Dateigröße</div><div class="value">5,3 MB</div></div>
|
||||
<div class="stat"><div class="label">Bitrate</div><div class="value">1.411 kbit/s</div></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="panel right">
|
||||
<div class="panel-head">
|
||||
<span class="panel-name">Lossy</span>
|
||||
<span class="panel-tag">MP3 128 kbit/s</span>
|
||||
</div>
|
||||
<div class="panel-format">verlustbehaftet · hohe Frequenzen weggeworfen, Transienten geglättet</div>
|
||||
|
||||
<svg class="waveform" viewBox="0 0 800 160" preserveAspectRatio="none">
|
||||
<defs>
|
||||
<linearGradient id="red-grad" x1="0" y1="0" x2="0" y2="1">
|
||||
<stop offset="0%" stop-color="#fca5a5"/>
|
||||
<stop offset="100%" stop-color="#ef4444"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<line x1="0" y1="80" x2="800" y2="80" stroke="#374151" stroke-width="1"/>
|
||||
<!-- smoothed waveform: same overall shape, no fine detail in transient peak -->
|
||||
<path d="M0,80
|
||||
L40,80 L48,80
|
||||
L60,48 L65,120 L70,52 L75,115 L80,58 L85,108
|
||||
L100,68 L108,92 L114,70 L120,90
|
||||
L150,75 L160,86 L168,76 L174,85
|
||||
L200,77 L210,84 L220,77 L230,83
|
||||
L260,78 L280,82 L300,78 L320,82
|
||||
L360,79 L380,81 L400,79 L420,81
|
||||
L460,80 L480,80 L520,80
|
||||
L580,80 L640,80 L700,80 L800,80 Z"
|
||||
fill="url(#red-grad)" stroke="#ef4444" stroke-width="1" opacity="0.95"/>
|
||||
</svg>
|
||||
|
||||
<div class="stats">
|
||||
<div class="stat"><div class="label">Dateigröße</div><div class="value">0,48 MB</div></div>
|
||||
<div class="stat"><div class="label">Bitrate</div><div class="value">128 kbit/s</div></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="verdict">
|
||||
<div class="verdict-q">Hört man den Unterschied?</div>
|
||||
<div class="verdict-a">Auf dem Smartphone-Lautsprecher: meist nicht. Im Studio-Monitor mit Kopfhörer: oft schon. — MP3 wirft <strong>91 % der Daten weg</strong>, die der Mensch im Alltag nicht vermisst.</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
After Width: | Height: | Size: 72 KiB |
@@ -0,0 +1,119 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Drei Modalitäten, ein Hebel</title>
|
||||
<style>
|
||||
:root {
|
||||
--dark: #1a1a2e;
|
||||
--muted: #6b7280;
|
||||
--soft: #f8fafc;
|
||||
--border: #cbd5e1;
|
||||
--hl: #d63384;
|
||||
--bild: #2563eb;
|
||||
--audio: #ea580c;
|
||||
--video: #7c3aed;
|
||||
}
|
||||
html, body { margin: 0; padding: 0; background: #fff; font-family: system-ui, -apple-system, sans-serif; color: var(--dark); }
|
||||
body { padding: 32px 48px; }
|
||||
h1 { text-align: center; margin: 0 0 6px; font-size: 1.85rem; }
|
||||
.sub { text-align: center; color: var(--muted); margin-bottom: 26px; font-size: 1.05rem; }
|
||||
|
||||
.table { display: grid; grid-template-columns: 140px 1fr 1fr 1fr; gap: 12px; max-width: 1180px; margin: 0 auto; align-items: stretch; }
|
||||
.col-head { font-size: 0.7rem; text-transform: uppercase; letter-spacing: 0.1em; font-weight: 700; color: var(--muted); padding: 0 8px 4px; }
|
||||
|
||||
.row-label { font-size: 1.15rem; font-weight: 700; padding: 16px 12px; display: flex; flex-direction: column; gap: 4px; justify-content: center; border-radius: 10px; }
|
||||
.row-label.bild { background: #dbeafe; color: var(--bild); }
|
||||
.row-label.audio { background: #ffedd5; color: var(--audio); }
|
||||
.row-label.video { background: #ede9fe; color: var(--video); }
|
||||
.row-label small { font-size: 0.78rem; font-weight: 400; color: var(--muted); text-transform: none; letter-spacing: 0; }
|
||||
|
||||
.cell { border: 1.5px solid var(--border); border-radius: 10px; padding: 12px 14px; background: #fff; display: flex; flex-direction: column; gap: 8px; }
|
||||
.cell-format { font-family: ui-monospace, monospace; font-size: 0.85rem; color: var(--muted); }
|
||||
.cell-size { font-size: 1.7rem; font-weight: 700; color: var(--dark); font-family: ui-monospace, monospace; }
|
||||
.cell-bar { height: 8px; border-radius: 4px; background: var(--soft); position: relative; overflow: hidden; }
|
||||
.cell-bar .fill { position: absolute; left: 0; top: 0; bottom: 0; border-radius: 4px; }
|
||||
|
||||
.verdict {
|
||||
margin-top: 22px;
|
||||
max-width: 1180px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
border: 2px solid var(--hl);
|
||||
border-radius: 12px;
|
||||
padding: 14px 22px;
|
||||
text-align: center;
|
||||
}
|
||||
.verdict-q { font-size: 1.05rem; font-weight: 700; color: var(--hl); }
|
||||
.verdict-a { font-size: 0.95rem; color: var(--dark); margin-top: 4px; }
|
||||
.verdict-a strong { color: var(--hl); }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Drei Modalitäten — derselbe Hebel</h1>
|
||||
<div class="sub">Bild, Audio, Video schrumpfen alle dramatisch. Warum? Weil Wahrnehmung Lücken hat.</div>
|
||||
|
||||
<div class="table">
|
||||
<div></div>
|
||||
<div class="col-head">Roh</div>
|
||||
<div class="col-head">Lossy (modern)</div>
|
||||
<div class="col-head">Lossy (aggressiv)</div>
|
||||
|
||||
<div class="row-label bild">Bild<small>12-MP-Foto</small></div>
|
||||
<div class="cell">
|
||||
<div class="cell-format">RAW</div>
|
||||
<div class="cell-size">36 MB</div>
|
||||
<div class="cell-bar"><div class="fill" style="width:100%;background:#2563eb"></div></div>
|
||||
</div>
|
||||
<div class="cell">
|
||||
<div class="cell-format">JPEG · Q 90</div>
|
||||
<div class="cell-size">4 MB</div>
|
||||
<div class="cell-bar"><div class="fill" style="width:11%;background:#2563eb"></div></div>
|
||||
</div>
|
||||
<div class="cell">
|
||||
<div class="cell-format">JPEG · Q 50</div>
|
||||
<div class="cell-size">800 KB</div>
|
||||
<div class="cell-bar"><div class="fill" style="width:2.2%;background:#2563eb"></div></div>
|
||||
</div>
|
||||
|
||||
<div class="row-label audio">Audio<small>30 s Stereo</small></div>
|
||||
<div class="cell">
|
||||
<div class="cell-format">WAV · 44,1 kHz · 16 bit</div>
|
||||
<div class="cell-size">5,3 MB</div>
|
||||
<div class="cell-bar"><div class="fill" style="width:100%;background:#ea580c"></div></div>
|
||||
</div>
|
||||
<div class="cell">
|
||||
<div class="cell-format">MP3 · 192 kbit/s</div>
|
||||
<div class="cell-size">720 KB</div>
|
||||
<div class="cell-bar"><div class="fill" style="width:14%;background:#ea580c"></div></div>
|
||||
</div>
|
||||
<div class="cell">
|
||||
<div class="cell-format">MP3 · 64 kbit/s</div>
|
||||
<div class="cell-size">240 KB</div>
|
||||
<div class="cell-bar"><div class="fill" style="width:4.5%;background:#ea580c"></div></div>
|
||||
</div>
|
||||
|
||||
<div class="row-label video">Video<small>30 s · 4K · 30 fps</small></div>
|
||||
<div class="cell">
|
||||
<div class="cell-format">Roh · 8 bit</div>
|
||||
<div class="cell-size">12 GB</div>
|
||||
<div class="cell-bar"><div class="fill" style="width:100%;background:#7c3aed"></div></div>
|
||||
</div>
|
||||
<div class="cell">
|
||||
<div class="cell-format">H.264 · 25 Mbit/s</div>
|
||||
<div class="cell-size">94 MB</div>
|
||||
<div class="cell-bar"><div class="fill" style="width:0.8%;background:#7c3aed"></div></div>
|
||||
</div>
|
||||
<div class="cell">
|
||||
<div class="cell-format">H.265 · 12 Mbit/s</div>
|
||||
<div class="cell-size">45 MB</div>
|
||||
<div class="cell-bar"><div class="fill" style="width:0.4%;background:#7c3aed"></div></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="verdict">
|
||||
<div class="verdict-q">Bilder schrumpfen ×45. Audio ×22. Video ×270.</div>
|
||||
<div class="verdict-a">Jede Reduktion nutzt eine andere Wahrnehmungs-Lücke: <strong>Bild</strong> die geringere Farbschärfe, <strong>Audio</strong> die Maskierung, <strong>Video</strong> die Frame-zu-Frame-Ähnlichkeit.</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
After Width: | Height: | Size: 75 KiB |
@@ -0,0 +1,182 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Die Reise einer Datei</title>
|
||||
<style>
|
||||
:root {
|
||||
--dark: #1a1a2e;
|
||||
--muted: #6b7280;
|
||||
--soft: #f8fafc;
|
||||
--border: #cbd5e1;
|
||||
--hl: #d63384;
|
||||
--slot1: #0891b2;
|
||||
--slot2: #2563eb;
|
||||
--slot3: #7c3aed;
|
||||
--slot4: #be185d;
|
||||
--slot5: #ea580c;
|
||||
}
|
||||
html, body { margin: 0; padding: 0; background: #fff; font-family: system-ui, -apple-system, sans-serif; color: var(--dark); }
|
||||
body { padding: 32px 40px; }
|
||||
h1 { text-align: center; margin: 0 0 6px; font-size: 1.85rem; }
|
||||
.sub { text-align: center; color: var(--muted); margin-bottom: 30px; font-size: 1.05rem; }
|
||||
.sub strong { color: var(--dark); }
|
||||
|
||||
.journey {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr auto 1fr auto 1fr auto 1fr auto 1fr;
|
||||
gap: 6px;
|
||||
align-items: stretch;
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.station {
|
||||
border: 2px solid;
|
||||
border-radius: 10px;
|
||||
padding: 14px 12px 12px;
|
||||
background: #fff;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
}
|
||||
.station.s1 { border-color: var(--slot1); }
|
||||
.station.s2 { border-color: var(--slot2); }
|
||||
.station.s3 { border-color: var(--slot3); }
|
||||
.station.s4 { border-color: var(--slot4); }
|
||||
.station.s5 { border-color: var(--slot5); }
|
||||
|
||||
.station-tag { font-size: 0.68rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.12em; color: var(--muted); }
|
||||
.station-name { font-size: 1.05rem; font-weight: 700; text-align: center; line-height: 1.2; }
|
||||
.station.s1 .station-name { color: var(--slot1); }
|
||||
.station.s2 .station-name { color: var(--slot2); }
|
||||
.station.s3 .station-name { color: var(--slot3); }
|
||||
.station.s4 .station-name { color: var(--slot4); }
|
||||
.station.s5 .station-name { color: var(--slot5); }
|
||||
.station-detail { font-size: 0.78rem; color: var(--muted); text-align: center; }
|
||||
|
||||
.link {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
padding: 0 4px;
|
||||
justify-content: center;
|
||||
}
|
||||
.link-rate {
|
||||
font-family: ui-monospace, monospace;
|
||||
font-size: 0.88rem;
|
||||
font-weight: 700;
|
||||
color: var(--dark);
|
||||
white-space: nowrap;
|
||||
}
|
||||
.link-protocol {
|
||||
font-size: 0.7rem;
|
||||
color: var(--muted);
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.06em;
|
||||
}
|
||||
.link-arrow svg { width: 32px; height: 14px; }
|
||||
|
||||
.scenario {
|
||||
margin-top: 28px;
|
||||
max-width: 1200px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
background: var(--soft);
|
||||
border: 1.5px solid var(--border);
|
||||
border-radius: 10px;
|
||||
padding: 16px 22px;
|
||||
}
|
||||
.scenario-head { font-size: 0.78rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.1em; color: var(--muted); margin-bottom: 6px; }
|
||||
.scenario-body { font-size: 0.98rem; line-height: 1.55; }
|
||||
.scenario-body code { font-family: ui-monospace, monospace; background: #fff; padding: 1px 6px; border-radius: 4px; border: 1px solid var(--border); }
|
||||
|
||||
.verdict {
|
||||
margin-top: 18px;
|
||||
max-width: 1200px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
text-align: center;
|
||||
border: 2px solid var(--hl);
|
||||
border-radius: 12px;
|
||||
padding: 14px 22px;
|
||||
}
|
||||
.verdict-q { font-size: 1.1rem; font-weight: 700; color: var(--hl); }
|
||||
.verdict-a { font-size: 0.92rem; color: var(--dark); margin-top: 4px; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Die Reise einer Datei</h1>
|
||||
<div class="sub">Ein 4K-Trailer (<strong>1,2 GB</strong>) reist von der externen SSD auf den Monitor — jede Etappe ist ein eigener Engpass.</div>
|
||||
|
||||
<div class="journey">
|
||||
<div class="station s1">
|
||||
<div class="station-tag">Quelle</div>
|
||||
<div class="station-name">SSD<br>extern</div>
|
||||
<div class="station-detail">NVMe-Stick</div>
|
||||
</div>
|
||||
|
||||
<div class="link">
|
||||
<div class="link-rate">3 200 MB/s</div>
|
||||
<svg class="link-arrow" viewBox="0 0 32 14"><path d="M2,7 L26,7 M22,2 L28,7 L22,12" stroke="#d63384" stroke-width="2" fill="none"/></svg>
|
||||
<div class="link-protocol">USB 4 / TB4</div>
|
||||
</div>
|
||||
|
||||
<div class="station s2">
|
||||
<div class="station-tag">Aufnahme</div>
|
||||
<div class="station-name">Laptop</div>
|
||||
<div class="station-detail">RAM & CPU</div>
|
||||
</div>
|
||||
|
||||
<div class="link">
|
||||
<div class="link-rate">~7 000 MB/s</div>
|
||||
<svg class="link-arrow" viewBox="0 0 32 14"><path d="M2,7 L26,7 M22,2 L28,7 L22,12" stroke="#d63384" stroke-width="2" fill="none"/></svg>
|
||||
<div class="link-protocol">PCIe 4.0</div>
|
||||
</div>
|
||||
|
||||
<div class="station s3">
|
||||
<div class="station-tag">Decoder</div>
|
||||
<div class="station-name">GPU</div>
|
||||
<div class="station-detail">H.264-Hardware</div>
|
||||
</div>
|
||||
|
||||
<div class="link">
|
||||
<div class="link-rate">2 200 MB/s</div>
|
||||
<svg class="link-arrow" viewBox="0 0 32 14"><path d="M2,7 L26,7 M22,2 L28,7 L22,12" stroke="#d63384" stroke-width="2" fill="none"/></svg>
|
||||
<div class="link-protocol">HDMI 2.1</div>
|
||||
</div>
|
||||
|
||||
<div class="station s4">
|
||||
<div class="station-tag">Display</div>
|
||||
<div class="station-name">4K-Monitor</div>
|
||||
<div class="station-detail">3840 × 2160</div>
|
||||
</div>
|
||||
|
||||
<div class="link">
|
||||
<div class="link-rate">visuell</div>
|
||||
<svg class="link-arrow" viewBox="0 0 32 14"><path d="M2,7 L26,7 M22,2 L28,7 L22,12" stroke="#d63384" stroke-width="2" fill="none"/></svg>
|
||||
<div class="link-protocol">Licht</div>
|
||||
</div>
|
||||
|
||||
<div class="station s5">
|
||||
<div class="station-tag">Ziel</div>
|
||||
<div class="station-name">Auge</div>
|
||||
<div class="station-detail">Bewusstsein</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="scenario">
|
||||
<div class="scenario-head">Was hier passiert</div>
|
||||
<div class="scenario-body">
|
||||
Die <code>1,2 GB</code> liegen verschlüsselt komprimiert auf dem Stick. Sie reisen über <strong>USB-C</strong> in den RAM, werden vom GPU <strong>dekodiert</strong> (H.264 → roher RGB-Strom), und über <strong>HDMI</strong> als unkomprimiertes Bild an den Monitor geschickt. Dort entstehen pro Sekunde 60 Bilder mit je rund <code>24 MB</code> — also <strong>1,4 GB/s an rohem Pixelstrom</strong>, der niemals als Datei vorliegt.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="verdict">
|
||||
<div class="verdict-q">Speicher und Schnittstelle sind keine zwei Themen — sie sind die zwei Seiten desselben Engpasses.</div>
|
||||
<div class="verdict-a">Wo Bytes wohnen entscheidet, wie schnell sie reisen können. Wo sie reisen entscheidet, wo sie wohnen müssen.</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
After Width: | Height: | Size: 89 KiB |
@@ -0,0 +1,254 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Eine Datei reist — und erzählt</title>
|
||||
<style>
|
||||
:root {
|
||||
--dark: #1a1a2e;
|
||||
--muted: #6b7280;
|
||||
--soft: #f8fafc;
|
||||
--border: #cbd5e1;
|
||||
--hl: #d63384;
|
||||
--visible: #2563eb;
|
||||
--hidden: #7c3aed;
|
||||
--transit: #ea580c;
|
||||
}
|
||||
html, body { margin: 0; padding: 0; background: #fff; font-family: system-ui, -apple-system, sans-serif; color: var(--dark); }
|
||||
body { padding: 28px 40px; }
|
||||
h1 { text-align: center; margin: 0 0 6px; font-size: 1.85rem; }
|
||||
.sub { text-align: center; color: var(--muted); margin-bottom: 22px; font-size: 1.05rem; }
|
||||
.sub strong { color: var(--dark); }
|
||||
|
||||
.scene {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1.2fr;
|
||||
gap: 22px;
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.panel {
|
||||
border: 2px solid;
|
||||
border-radius: 12px;
|
||||
padding: 16px 18px;
|
||||
background: #fff;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 10px;
|
||||
}
|
||||
.panel.visible { border-color: var(--visible); }
|
||||
.panel.hidden { border-color: var(--hidden); }
|
||||
|
||||
.panel-head { display: flex; justify-content: space-between; align-items: baseline; }
|
||||
.panel-tag {
|
||||
font-size: 0.7rem;
|
||||
font-weight: 700;
|
||||
letter-spacing: 0.12em;
|
||||
text-transform: uppercase;
|
||||
color: var(--muted);
|
||||
}
|
||||
.panel-name { font-size: 1.25rem; font-weight: 700; }
|
||||
.panel.visible .panel-name { color: var(--visible); }
|
||||
.panel.hidden .panel-name { color: var(--hidden); }
|
||||
|
||||
.photo {
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
border: 1px solid var(--border);
|
||||
display: block;
|
||||
}
|
||||
|
||||
.photo-meta {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
font-family: ui-monospace, monospace;
|
||||
font-size: 0.78rem;
|
||||
color: var(--muted);
|
||||
padding: 0 2px;
|
||||
}
|
||||
|
||||
.exif-list {
|
||||
display: grid;
|
||||
grid-template-columns: 130px 1fr;
|
||||
gap: 4px 12px;
|
||||
font-size: 0.86rem;
|
||||
line-height: 1.4;
|
||||
}
|
||||
.exif-key {
|
||||
font-size: 0.7rem;
|
||||
font-weight: 700;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.08em;
|
||||
color: var(--muted);
|
||||
padding-top: 3px;
|
||||
}
|
||||
.exif-val { font-family: ui-monospace, monospace; color: var(--dark); }
|
||||
.exif-val.gps { color: var(--hl); font-weight: 700; }
|
||||
|
||||
.transit-strip {
|
||||
max-width: 1200px;
|
||||
margin: 18px auto 0;
|
||||
border: 2px solid var(--transit);
|
||||
border-radius: 12px;
|
||||
padding: 14px 18px;
|
||||
background: #fff;
|
||||
display: grid;
|
||||
grid-template-columns: auto 1fr;
|
||||
gap: 16px;
|
||||
align-items: center;
|
||||
}
|
||||
.transit-tag {
|
||||
font-size: 0.7rem;
|
||||
font-weight: 700;
|
||||
letter-spacing: 0.12em;
|
||||
text-transform: uppercase;
|
||||
color: var(--transit);
|
||||
writing-mode: vertical-rl;
|
||||
transform: rotate(180deg);
|
||||
text-align: center;
|
||||
}
|
||||
.transit-body { display: flex; flex-direction: column; gap: 8px; }
|
||||
.transit-route {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
font-size: 0.92rem;
|
||||
font-weight: 700;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
.hop {
|
||||
background: var(--soft);
|
||||
border: 1.5px solid var(--border);
|
||||
padding: 4px 10px;
|
||||
border-radius: 6px;
|
||||
font-family: ui-monospace, monospace;
|
||||
font-size: 0.82rem;
|
||||
color: var(--dark);
|
||||
}
|
||||
.hop.origin { border-color: var(--visible); color: var(--visible); }
|
||||
.hop.dest { border-color: var(--visible); color: var(--visible); }
|
||||
.hop.edge { border-color: var(--transit); color: var(--transit); }
|
||||
.arrow { color: var(--muted); font-family: ui-monospace, monospace; }
|
||||
.transit-headers {
|
||||
font-family: ui-monospace, monospace;
|
||||
font-size: 0.78rem;
|
||||
color: var(--muted);
|
||||
line-height: 1.5;
|
||||
}
|
||||
.transit-headers strong { color: var(--dark); }
|
||||
|
||||
.verdict {
|
||||
margin-top: 18px;
|
||||
max-width: 1200px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
text-align: center;
|
||||
border: 2px solid var(--hl);
|
||||
border-radius: 12px;
|
||||
padding: 14px 22px;
|
||||
}
|
||||
.verdict-q { font-size: 1.1rem; font-weight: 700; color: var(--hl); }
|
||||
.verdict-a { font-size: 0.93rem; color: var(--dark); margin-top: 4px; }
|
||||
.verdict-a strong { color: var(--hl); }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Eine Datei reist — und erzählt</h1>
|
||||
<div class="sub">Ein Smartphone-Foto geht von <strong>Stuttgart</strong> nach <strong>Tokyo</strong>. Was sieht der Empfänger — und was bekommt er noch dazu?</div>
|
||||
|
||||
<div class="scene">
|
||||
|
||||
<div class="panel visible">
|
||||
<div class="panel-head">
|
||||
<span class="panel-name">Inhalt</span>
|
||||
<span class="panel-tag">Was du siehst</span>
|
||||
</div>
|
||||
|
||||
<svg class="photo" viewBox="0 0 420 280" preserveAspectRatio="xMidYMid slice">
|
||||
<defs>
|
||||
<linearGradient id="sky" x1="0" y1="0" x2="0" y2="1">
|
||||
<stop offset="0%" stop-color="#fde68a"/>
|
||||
<stop offset="55%" stop-color="#fda4af"/>
|
||||
<stop offset="100%" stop-color="#9333ea"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="hills" x1="0" y1="0" x2="0" y2="1">
|
||||
<stop offset="0%" stop-color="#312e81"/>
|
||||
<stop offset="100%" stop-color="#0f172a"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<rect x="0" y="0" width="420" height="280" fill="url(#sky)"/>
|
||||
<circle cx="320" cy="105" r="32" fill="#fff7ed" opacity="0.95"/>
|
||||
<path d="M0,200 L60,170 L110,185 L160,160 L210,178 L260,150 L310,172 L360,148 L420,168 L420,280 L0,280 Z" fill="url(#hills)"/>
|
||||
<path d="M0,225 L50,210 L100,222 L150,205 L200,220 L250,202 L300,218 L350,200 L420,215 L420,280 L0,280 Z" fill="#1e1b4b" opacity="0.7"/>
|
||||
<rect x="80" y="225" width="14" height="42" fill="#0f172a"/>
|
||||
<rect x="180" y="232" width="10" height="35" fill="#0f172a"/>
|
||||
<rect x="240" y="220" width="18" height="48" fill="#0f172a"/>
|
||||
<rect x="300" y="234" width="11" height="34" fill="#0f172a"/>
|
||||
<rect x="86" y="232" width="3" height="3" fill="#fbbf24"/>
|
||||
<rect x="188" y="240" width="2" height="2" fill="#fbbf24"/>
|
||||
<rect x="248" y="228" width="3" height="3" fill="#fbbf24"/>
|
||||
<rect x="307" y="240" width="2" height="2" fill="#fbbf24"/>
|
||||
</svg>
|
||||
|
||||
<div class="photo-meta">
|
||||
<span>HEIC · 4032 × 3024</span>
|
||||
<span>3,2 MB</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="panel hidden">
|
||||
<div class="panel-head">
|
||||
<span class="panel-name">Gepäck</span>
|
||||
<span class="panel-tag">Was die Datei über sich weiß</span>
|
||||
</div>
|
||||
|
||||
<div class="exif-list">
|
||||
<div class="exif-key">Kamera</div>
|
||||
<div class="exif-val">Apple iPhone 15 Pro · 24 mm · ƒ/1.78</div>
|
||||
|
||||
<div class="exif-key">Belichtung</div>
|
||||
<div class="exif-val">1/250 s · ISO 100 · EV 0</div>
|
||||
|
||||
<div class="exif-key">Aufgenommen</div>
|
||||
<div class="exif-val">2026-04-12 · 18:47:12 · +02:00</div>
|
||||
|
||||
<div class="exif-key">GPS</div>
|
||||
<div class="exif-val gps">48.7847° N · 9.1825° E · 248 m<br><span style="font-weight:400">(Stuttgart, Königstraße 28)</span></div>
|
||||
|
||||
<div class="exif-key">Software</div>
|
||||
<div class="exif-val">iOS 18.4.1 · HDR · Live Photo</div>
|
||||
|
||||
<div class="exif-key">Farbprofil</div>
|
||||
<div class="exif-val">Display P3</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="transit-strip">
|
||||
<div class="transit-tag">Weg</div>
|
||||
<div class="transit-body">
|
||||
<div class="transit-route">
|
||||
<span class="hop origin">Stuttgart</span>
|
||||
<span class="arrow">→</span>
|
||||
<span class="hop">DNS</span>
|
||||
<span class="arrow">→</span>
|
||||
<span class="hop">TLS 1.3</span>
|
||||
<span class="arrow">→</span>
|
||||
<span class="hop edge">CDN-Edge Tokyo</span>
|
||||
<span class="arrow">→</span>
|
||||
<span class="hop dest">Tokyo</span>
|
||||
</div>
|
||||
<div class="transit-headers">
|
||||
<strong>HTTP/3 200 OK</strong> · content-type: image/heic · content-length: 3 220 480 · <strong>RTT 47 ms</strong> · cache: HIT (Edge tok-7) · age: 312 s
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="verdict">
|
||||
<div class="verdict-q">Eine Datei = Inhalt + Gepäck + Weg.</div>
|
||||
<div class="verdict-a"><strong>Inhalt</strong> sieht der Empfänger. <strong>Gepäck</strong> verrät, wer sie gemacht hat — und wo. <strong>Weg</strong> entscheidet, wie schnell sie ankommt. Drei Schichten, eine Datei.</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
After Width: | Height: | Size: 96 KiB |
@@ -0,0 +1,194 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>1 TB verkauft, 931 GB angezeigt — wo gehen die 69 GB hin?</title>
|
||||
<style>
|
||||
:root {
|
||||
--dark: #1a1a2e;
|
||||
--muted: #6b7280;
|
||||
--soft: #f8fafc;
|
||||
--border: #cbd5e1;
|
||||
--hl: #d63384;
|
||||
--marketing: #2563eb;
|
||||
--os: #ea580c;
|
||||
}
|
||||
html, body { margin: 0; padding: 0; background: #fff; font-family: system-ui, -apple-system, sans-serif; color: var(--dark); }
|
||||
body { padding: 32px 40px; }
|
||||
h1 { text-align: center; margin: 0 0 6px; font-size: 1.75rem; }
|
||||
.sub { text-align: center; color: var(--muted); margin-bottom: 24px; font-size: 1.05rem; }
|
||||
.sub strong { color: var(--dark); }
|
||||
|
||||
.compare {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 80px 1fr;
|
||||
gap: 18px;
|
||||
max-width: 1100px;
|
||||
margin: 0 auto;
|
||||
align-items: stretch;
|
||||
}
|
||||
|
||||
.side {
|
||||
border: 2px solid;
|
||||
border-radius: 12px;
|
||||
padding: 18px 22px;
|
||||
background: #fff;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
}
|
||||
.side.marketing { border-color: var(--marketing); }
|
||||
.side.os { border-color: var(--os); }
|
||||
|
||||
.side-tag {
|
||||
font-size: 0.72rem;
|
||||
font-weight: 700;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.12em;
|
||||
color: var(--muted);
|
||||
}
|
||||
.side.marketing .side-name { color: var(--marketing); }
|
||||
.side.os .side-name { color: var(--os); }
|
||||
.side-name { font-size: 1.15rem; font-weight: 700; }
|
||||
|
||||
.label-mock {
|
||||
background: var(--soft);
|
||||
border: 1.5px solid var(--border);
|
||||
border-radius: 8px;
|
||||
padding: 14px 22px;
|
||||
min-width: 240px;
|
||||
text-align: center;
|
||||
font-family: ui-monospace, monospace;
|
||||
font-size: 0.85rem;
|
||||
color: var(--muted);
|
||||
line-height: 1.5;
|
||||
}
|
||||
.label-mock .big {
|
||||
font-family: system-ui, sans-serif;
|
||||
font-size: 2.2rem;
|
||||
font-weight: 900;
|
||||
display: block;
|
||||
color: var(--dark);
|
||||
line-height: 1.05;
|
||||
}
|
||||
.side.marketing .label-mock .big { color: var(--marketing); }
|
||||
.side.os .label-mock .big { color: var(--os); }
|
||||
.label-mock .small-line { font-size: 0.78rem; }
|
||||
|
||||
.formel {
|
||||
font-family: ui-monospace, monospace;
|
||||
font-size: 0.85rem;
|
||||
color: var(--muted);
|
||||
text-align: center;
|
||||
line-height: 1.6;
|
||||
}
|
||||
.formel strong { color: var(--dark); }
|
||||
|
||||
.arrow-col {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 4px;
|
||||
color: var(--muted);
|
||||
}
|
||||
.arrow-col svg { display: block; }
|
||||
.arrow-col .why {
|
||||
font-size: 0.78rem;
|
||||
font-weight: 700;
|
||||
color: var(--hl);
|
||||
text-align: center;
|
||||
line-height: 1.25;
|
||||
}
|
||||
|
||||
.math-box {
|
||||
margin-top: 22px;
|
||||
max-width: 1100px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
background: var(--soft);
|
||||
border: 1.5px solid var(--border);
|
||||
border-radius: 10px;
|
||||
padding: 16px 22px;
|
||||
}
|
||||
.math-box-head { font-size: 0.78rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.1em; color: var(--muted); margin-bottom: 8px; }
|
||||
.math-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 10px 22px; font-family: ui-monospace, monospace; font-size: 0.9rem; line-height: 1.6; }
|
||||
.math-grid .key { color: var(--muted); }
|
||||
.math-grid .val { color: var(--dark); font-weight: 700; }
|
||||
.math-grid .val.hl { color: var(--hl); }
|
||||
|
||||
.verdict {
|
||||
margin-top: 18px;
|
||||
max-width: 1100px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
text-align: center;
|
||||
border: 2px solid var(--hl);
|
||||
border-radius: 12px;
|
||||
padding: 14px 22px;
|
||||
}
|
||||
.verdict-q { font-size: 1.05rem; font-weight: 700; color: var(--hl); }
|
||||
.verdict-a { font-size: 0.93rem; color: var(--dark); margin-top: 4px; }
|
||||
.verdict-a code { font-family: ui-monospace, monospace; background: #fff; padding: 1px 5px; border-radius: 4px; border: 1px solid var(--border); }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>„1 TB" gekauft — 931 GB im Finder. Wo sind die 69 GB hin?</h1>
|
||||
<div class="sub">Nirgendwo. Es sind <strong>dieselben Byte</strong>. Nur zwei Welten zählen anders.</div>
|
||||
|
||||
<div class="compare">
|
||||
|
||||
<div class="side marketing">
|
||||
<div class="side-tag">Auf der Verpackung</div>
|
||||
<div class="side-name">Marketing</div>
|
||||
<div class="label-mock">
|
||||
<span class="big">1 TB</span>
|
||||
<span class="small-line">externe SSD</span>
|
||||
</div>
|
||||
<div class="formel">
|
||||
1 TB = <strong>10<sup>12</sup></strong> Byte<br>
|
||||
= 1 000 000 000 000
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="arrow-col">
|
||||
<svg viewBox="0 0 60 30" width="56" height="30"><path d="M5,15 L48,15 M42,7 L52,15 L42,23" stroke="#d63384" stroke-width="2.5" fill="none"/></svg>
|
||||
<div class="why">geteilt durch<br>2<sup>30</sup></div>
|
||||
</div>
|
||||
|
||||
<div class="side os">
|
||||
<div class="side-tag">Im Finder · Explorer</div>
|
||||
<div class="side-name">Betriebssystem</div>
|
||||
<div class="label-mock">
|
||||
<span class="big">931 GB</span>
|
||||
<span class="small-line">eigentlich: 931 GiB</span>
|
||||
</div>
|
||||
<div class="formel">
|
||||
1 GiB = <strong>2<sup>30</sup></strong> Byte<br>
|
||||
= 1 073 741 824
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="math-box">
|
||||
<div class="math-box-head">Die Rechnung</div>
|
||||
<div class="math-grid">
|
||||
<span class="key">Marketing schreibt</span>
|
||||
<span class="val">1 TB = 1 000 000 000 000 Byte (Basis 10)</span>
|
||||
<span class="key">Betriebssystem rechnet</span>
|
||||
<span class="val">1 TiB = 1 099 511 627 776 Byte (Basis 2)</span>
|
||||
<span class="key">1 TB in GiB umrechnen</span>
|
||||
<span class="val hl">10<sup>12</sup> ÷ 2<sup>30</sup> ≈ 931,3 GiB — der Finder zeigt also „931 GB"</span>
|
||||
<span class="key">Was die Studis sehen</span>
|
||||
<span class="val">Etikett: GB · Anzeige: GB · Bedeutung: zwei verschiedene Dinge</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="verdict">
|
||||
<div class="verdict-q">Es fehlt nichts. Es wird nur in zwei Sprachen gezählt.</div>
|
||||
<div class="verdict-a">Korrekt wären <code>GiB</code> (binär, 1024) und <code>GB</code> (dezimal, 1000). In der Realität verwenden beide Welten <code>GB</code> und meinen verschiedene Zahlen.</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
After Width: | Height: | Size: 91 KiB |
@@ -0,0 +1,232 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Nyquist-Shannon — wie oft muss man messen?</title>
|
||||
<style>
|
||||
:root {
|
||||
--dark: #1a1a2e;
|
||||
--muted: #6b7280;
|
||||
--soft: #f8fafc;
|
||||
--border: #cbd5e1;
|
||||
--hl: #d63384;
|
||||
--bad: #ef4444;
|
||||
--warn: #f59e0b;
|
||||
--good: #16a34a;
|
||||
}
|
||||
html, body { margin: 0; padding: 0; background: #fff; font-family: system-ui, -apple-system, sans-serif; color: var(--dark); }
|
||||
body { padding: 28px 40px; }
|
||||
h1 { text-align: center; margin: 0 0 6px; font-size: 1.75rem; }
|
||||
.sub { text-align: center; color: var(--muted); margin-bottom: 22px; font-size: 1.05rem; }
|
||||
.sub strong { color: var(--dark); }
|
||||
|
||||
.cases {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 12px;
|
||||
max-width: 1180px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.case {
|
||||
display: grid;
|
||||
grid-template-columns: 200px 1fr;
|
||||
gap: 18px;
|
||||
align-items: center;
|
||||
border: 2px solid;
|
||||
border-radius: 10px;
|
||||
padding: 10px 14px;
|
||||
background: #fff;
|
||||
}
|
||||
.case.bad { border-color: var(--bad); }
|
||||
.case.warn { border-color: var(--warn); }
|
||||
.case.good { border-color: var(--good); }
|
||||
|
||||
.case-meta { display: flex; flex-direction: column; gap: 4px; }
|
||||
.case-tag {
|
||||
font-size: 0.7rem;
|
||||
font-weight: 700;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.12em;
|
||||
color: var(--muted);
|
||||
}
|
||||
.case-name { font-size: 1.05rem; font-weight: 700; }
|
||||
.case.bad .case-name { color: var(--bad); }
|
||||
.case.warn .case-name { color: var(--warn); }
|
||||
.case.good .case-name { color: var(--good); }
|
||||
.case-rate { font-family: ui-monospace, monospace; font-size: 0.82rem; color: var(--dark); }
|
||||
.case-note { font-size: 0.78rem; color: var(--muted); line-height: 1.35; }
|
||||
|
||||
.plot { background: var(--soft); border-radius: 8px; }
|
||||
.plot svg { display: block; }
|
||||
|
||||
.verdict {
|
||||
margin-top: 20px;
|
||||
max-width: 1180px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
text-align: center;
|
||||
border: 2px solid var(--hl);
|
||||
border-radius: 12px;
|
||||
padding: 14px 22px;
|
||||
}
|
||||
.verdict-q { font-size: 1.05rem; font-weight: 700; color: var(--hl); }
|
||||
.verdict-a { font-size: 0.92rem; color: var(--dark); margin-top: 4px; }
|
||||
.verdict-a strong { color: var(--hl); }
|
||||
.verdict-a code { font-family: ui-monospace, monospace; background: var(--soft); padding: 1px 5px; border-radius: 4px; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Nyquist-Shannon — wie oft müssen wir messen?</h1>
|
||||
<div class="sub">Dieselbe Welle, drei Sample-Raten. Eine fällt durch, eine reicht knapp, eine ist sicher.</div>
|
||||
|
||||
<div class="cases">
|
||||
|
||||
<div class="case bad">
|
||||
<div class="case-meta">
|
||||
<div class="case-tag">Zu wenig</div>
|
||||
<div class="case-name">Aliasing</div>
|
||||
<div class="case-rate">f<sub>s</sub> = 0,9 · f</div>
|
||||
<div class="case-note">Die Sample-Punkte sitzen auf der Welle — aber verbunden sehen sie aus wie eine <strong>ganz andere, langsamere</strong> Welle.</div>
|
||||
</div>
|
||||
<div class="plot">
|
||||
<svg viewBox="0 0 880 140" width="100%" height="140" preserveAspectRatio="none">
|
||||
<line x1="20" y1="70" x2="860" y2="70" stroke="#cbd5e1" stroke-width="1" stroke-dasharray="3,4"/>
|
||||
<path d="M 20,70 Q 46.25,-20 72.5,70 T 125,70 T 177.5,70 T 230,70 T 282.5,70 T 335,70 T 387.5,70 T 440,70 T 492.5,70 T 545,70 T 597.5,70 T 650,70 T 702.5,70 T 755,70 T 807.5,70 T 860,70"
|
||||
stroke="#cbd5e1" stroke-width="1.5" fill="none"/>
|
||||
<polyline points="20,70 136.7,41 253.4,25.7 370.1,31.2 486.8,54.9 603.5,85.8 720.2,109.2 836.9,114.2"
|
||||
stroke="#ef4444" stroke-width="2.5" fill="none"/>
|
||||
<circle cx="20" cy="70" r="5" fill="#ef4444"/>
|
||||
<circle cx="136.7" cy="41" r="5" fill="#ef4444"/>
|
||||
<circle cx="253.4" cy="25.7" r="5" fill="#ef4444"/>
|
||||
<circle cx="370.1" cy="31.2" r="5" fill="#ef4444"/>
|
||||
<circle cx="486.8" cy="54.9" r="5" fill="#ef4444"/>
|
||||
<circle cx="603.5" cy="85.8" r="5" fill="#ef4444"/>
|
||||
<circle cx="720.2" cy="109.2" r="5" fill="#ef4444"/>
|
||||
<circle cx="836.9" cy="114.2" r="5" fill="#ef4444"/>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="case warn">
|
||||
<div class="case-meta">
|
||||
<div class="case-tag">Genau</div>
|
||||
<div class="case-name">Nyquist-Grenze</div>
|
||||
<div class="case-rate">f<sub>s</sub> = 2 · f</div>
|
||||
<div class="case-note">Sample exakt auf <strong>Peak und Tal</strong>. Mathematisch reicht das — visuell sieht es kaputt aus.</div>
|
||||
</div>
|
||||
<div class="plot">
|
||||
<svg viewBox="0 0 880 140" width="100%" height="140" preserveAspectRatio="none">
|
||||
<line x1="20" y1="70" x2="860" y2="70" stroke="#cbd5e1" stroke-width="1" stroke-dasharray="3,4"/>
|
||||
<path d="M 20,70 Q 46.25,-20 72.5,70 T 125,70 T 177.5,70 T 230,70 T 282.5,70 T 335,70 T 387.5,70 T 440,70 T 492.5,70 T 545,70 T 597.5,70 T 650,70 T 702.5,70 T 755,70 T 807.5,70 T 860,70"
|
||||
stroke="#cbd5e1" stroke-width="1.5" fill="none"/>
|
||||
<polyline points="46.25,25 98.75,115 151.25,25 203.75,115 256.25,25 308.75,115 361.25,25 413.75,115 466.25,25 518.75,115 571.25,25 623.75,115 676.25,25 728.75,115 781.25,25 833.75,115"
|
||||
stroke="#f59e0b" stroke-width="2" fill="none" opacity="0.5"/>
|
||||
<circle cx="46.25" cy="25" r="5" fill="#f59e0b"/>
|
||||
<circle cx="98.75" cy="115" r="5" fill="#f59e0b"/>
|
||||
<circle cx="151.25" cy="25" r="5" fill="#f59e0b"/>
|
||||
<circle cx="203.75" cy="115" r="5" fill="#f59e0b"/>
|
||||
<circle cx="256.25" cy="25" r="5" fill="#f59e0b"/>
|
||||
<circle cx="308.75" cy="115" r="5" fill="#f59e0b"/>
|
||||
<circle cx="361.25" cy="25" r="5" fill="#f59e0b"/>
|
||||
<circle cx="413.75" cy="115" r="5" fill="#f59e0b"/>
|
||||
<circle cx="466.25" cy="25" r="5" fill="#f59e0b"/>
|
||||
<circle cx="518.75" cy="115" r="5" fill="#f59e0b"/>
|
||||
<circle cx="571.25" cy="25" r="5" fill="#f59e0b"/>
|
||||
<circle cx="623.75" cy="115" r="5" fill="#f59e0b"/>
|
||||
<circle cx="676.25" cy="25" r="5" fill="#f59e0b"/>
|
||||
<circle cx="728.75" cy="115" r="5" fill="#f59e0b"/>
|
||||
<circle cx="781.25" cy="25" r="5" fill="#f59e0b"/>
|
||||
<circle cx="833.75" cy="115" r="5" fill="#f59e0b"/>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="case good">
|
||||
<div class="case-meta">
|
||||
<div class="case-tag">Sicher</div>
|
||||
<div class="case-name">Überabtastung</div>
|
||||
<div class="case-rate">f<sub>s</sub> = 8 · f</div>
|
||||
<div class="case-note">Genug Punkte — die Welle wird Punkt für Punkt nachgezeichnet. So macht es eine CD.</div>
|
||||
</div>
|
||||
<div class="plot">
|
||||
<svg viewBox="0 0 880 140" width="100%" height="140" preserveAspectRatio="none">
|
||||
<line x1="20" y1="70" x2="860" y2="70" stroke="#cbd5e1" stroke-width="1" stroke-dasharray="3,4"/>
|
||||
<path d="M 20,70 Q 46.25,-20 72.5,70 T 125,70 T 177.5,70 T 230,70 T 282.5,70 T 335,70 T 387.5,70 T 440,70 T 492.5,70 T 545,70 T 597.5,70 T 650,70 T 702.5,70 T 755,70 T 807.5,70 T 860,70"
|
||||
stroke="#16a34a" stroke-width="2.5" fill="none" opacity="0.9"/>
|
||||
<circle cx="20" cy="70" r="2.5" fill="#16a34a"/>
|
||||
<circle cx="33.1" cy="38.2" r="2.5" fill="#16a34a"/>
|
||||
<circle cx="46.2" cy="25" r="2.5" fill="#16a34a"/>
|
||||
<circle cx="59.4" cy="38.2" r="2.5" fill="#16a34a"/>
|
||||
<circle cx="72.5" cy="70" r="2.5" fill="#16a34a"/>
|
||||
<circle cx="85.6" cy="101.8" r="2.5" fill="#16a34a"/>
|
||||
<circle cx="98.8" cy="115" r="2.5" fill="#16a34a"/>
|
||||
<circle cx="111.9" cy="101.8" r="2.5" fill="#16a34a"/>
|
||||
<circle cx="125" cy="70" r="2.5" fill="#16a34a"/>
|
||||
<circle cx="138.1" cy="38.2" r="2.5" fill="#16a34a"/>
|
||||
<circle cx="151.2" cy="25" r="2.5" fill="#16a34a"/>
|
||||
<circle cx="164.4" cy="38.2" r="2.5" fill="#16a34a"/>
|
||||
<circle cx="177.5" cy="70" r="2.5" fill="#16a34a"/>
|
||||
<circle cx="190.6" cy="101.8" r="2.5" fill="#16a34a"/>
|
||||
<circle cx="203.8" cy="115" r="2.5" fill="#16a34a"/>
|
||||
<circle cx="216.9" cy="101.8" r="2.5" fill="#16a34a"/>
|
||||
<circle cx="230" cy="70" r="2.5" fill="#16a34a"/>
|
||||
<circle cx="243.1" cy="38.2" r="2.5" fill="#16a34a"/>
|
||||
<circle cx="256.2" cy="25" r="2.5" fill="#16a34a"/>
|
||||
<circle cx="269.4" cy="38.2" r="2.5" fill="#16a34a"/>
|
||||
<circle cx="282.5" cy="70" r="2.5" fill="#16a34a"/>
|
||||
<circle cx="295.6" cy="101.8" r="2.5" fill="#16a34a"/>
|
||||
<circle cx="308.8" cy="115" r="2.5" fill="#16a34a"/>
|
||||
<circle cx="321.9" cy="101.8" r="2.5" fill="#16a34a"/>
|
||||
<circle cx="335" cy="70" r="2.5" fill="#16a34a"/>
|
||||
<circle cx="348.1" cy="38.2" r="2.5" fill="#16a34a"/>
|
||||
<circle cx="361.2" cy="25" r="2.5" fill="#16a34a"/>
|
||||
<circle cx="374.4" cy="38.2" r="2.5" fill="#16a34a"/>
|
||||
<circle cx="387.5" cy="70" r="2.5" fill="#16a34a"/>
|
||||
<circle cx="400.6" cy="101.8" r="2.5" fill="#16a34a"/>
|
||||
<circle cx="413.8" cy="115" r="2.5" fill="#16a34a"/>
|
||||
<circle cx="426.9" cy="101.8" r="2.5" fill="#16a34a"/>
|
||||
<circle cx="440" cy="70" r="2.5" fill="#16a34a"/>
|
||||
<circle cx="453.1" cy="38.2" r="2.5" fill="#16a34a"/>
|
||||
<circle cx="466.2" cy="25" r="2.5" fill="#16a34a"/>
|
||||
<circle cx="479.4" cy="38.2" r="2.5" fill="#16a34a"/>
|
||||
<circle cx="492.5" cy="70" r="2.5" fill="#16a34a"/>
|
||||
<circle cx="505.6" cy="101.8" r="2.5" fill="#16a34a"/>
|
||||
<circle cx="518.8" cy="115" r="2.5" fill="#16a34a"/>
|
||||
<circle cx="531.9" cy="101.8" r="2.5" fill="#16a34a"/>
|
||||
<circle cx="545" cy="70" r="2.5" fill="#16a34a"/>
|
||||
<circle cx="558.1" cy="38.2" r="2.5" fill="#16a34a"/>
|
||||
<circle cx="571.2" cy="25" r="2.5" fill="#16a34a"/>
|
||||
<circle cx="584.4" cy="38.2" r="2.5" fill="#16a34a"/>
|
||||
<circle cx="597.5" cy="70" r="2.5" fill="#16a34a"/>
|
||||
<circle cx="610.6" cy="101.8" r="2.5" fill="#16a34a"/>
|
||||
<circle cx="623.8" cy="115" r="2.5" fill="#16a34a"/>
|
||||
<circle cx="636.9" cy="101.8" r="2.5" fill="#16a34a"/>
|
||||
<circle cx="650" cy="70" r="2.5" fill="#16a34a"/>
|
||||
<circle cx="663.1" cy="38.2" r="2.5" fill="#16a34a"/>
|
||||
<circle cx="676.2" cy="25" r="2.5" fill="#16a34a"/>
|
||||
<circle cx="689.4" cy="38.2" r="2.5" fill="#16a34a"/>
|
||||
<circle cx="702.5" cy="70" r="2.5" fill="#16a34a"/>
|
||||
<circle cx="715.6" cy="101.8" r="2.5" fill="#16a34a"/>
|
||||
<circle cx="728.8" cy="115" r="2.5" fill="#16a34a"/>
|
||||
<circle cx="741.9" cy="101.8" r="2.5" fill="#16a34a"/>
|
||||
<circle cx="755" cy="70" r="2.5" fill="#16a34a"/>
|
||||
<circle cx="768.1" cy="38.2" r="2.5" fill="#16a34a"/>
|
||||
<circle cx="781.2" cy="25" r="2.5" fill="#16a34a"/>
|
||||
<circle cx="794.4" cy="38.2" r="2.5" fill="#16a34a"/>
|
||||
<circle cx="807.5" cy="70" r="2.5" fill="#16a34a"/>
|
||||
<circle cx="820.6" cy="101.8" r="2.5" fill="#16a34a"/>
|
||||
<circle cx="833.8" cy="115" r="2.5" fill="#16a34a"/>
|
||||
<circle cx="846.9" cy="101.8" r="2.5" fill="#16a34a"/>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="verdict">
|
||||
<div class="verdict-q">f<sub>s</sub> ≥ 2 · f<sub>max</sub>. So einfach. So endgültig.</div>
|
||||
<div class="verdict-a">Das Ohr hört bis <strong>20 kHz</strong>. 2 × 20 = 40 kHz. Die CD nimmt <code>44,1 kHz</code> — die 4,1 sind Sicherheits-Marge.</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
After Width: | Height: | Size: 140 KiB |
@@ -0,0 +1,173 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Wir haben gelernt zu lesen — jetzt: wie kommt es rein?</title>
|
||||
<style>
|
||||
:root {
|
||||
--dark: #1a1a2e;
|
||||
--muted: #6b7280;
|
||||
--soft: #f8fafc;
|
||||
--border: #cbd5e1;
|
||||
--hl: #d63384;
|
||||
--done: #94a3b8;
|
||||
--next: #d63384;
|
||||
--bytes: #0891b2;
|
||||
}
|
||||
html, body { margin: 0; padding: 0; background: #fff; font-family: system-ui, -apple-system, sans-serif; color: var(--dark); }
|
||||
body { padding: 32px 40px; }
|
||||
h1 { text-align: center; margin: 0 0 6px; font-size: 1.7rem; }
|
||||
.sub { text-align: center; color: var(--muted); margin-bottom: 36px; font-size: 1.05rem; }
|
||||
.sub strong { color: var(--dark); }
|
||||
|
||||
.pivot {
|
||||
display: grid;
|
||||
grid-template-columns: 200px 1fr 240px 1fr 200px;
|
||||
gap: 8px;
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.station {
|
||||
border: 2px solid var(--border);
|
||||
border-radius: 12px;
|
||||
padding: 18px 14px;
|
||||
background: #fff;
|
||||
text-align: center;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
}
|
||||
.station.bytes { border-color: var(--bytes); background: #0f0f23; color: #fff; }
|
||||
.station-tag {
|
||||
font-size: 0.7rem;
|
||||
font-weight: 700;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.12em;
|
||||
color: var(--muted);
|
||||
}
|
||||
.station.bytes .station-tag { color: #94a3b8; }
|
||||
.station-name { font-size: 1.3rem; font-weight: 700; }
|
||||
.station.bytes .station-name { color: #67e8f9; }
|
||||
.station-detail { font-size: 0.85rem; color: var(--muted); }
|
||||
.station.bytes .station-detail { color: #94a3b8; font-family: ui-monospace, monospace; font-size: 0.78rem; line-height: 1.4; }
|
||||
|
||||
.station-art { display: flex; align-items: center; justify-content: center; height: 70px; }
|
||||
.station-art svg { width: 80%; height: 100%; }
|
||||
|
||||
.strang {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
padding: 0 6px;
|
||||
}
|
||||
.strang-arrow svg { display: block; width: 100%; height: 28px; }
|
||||
.strang-label {
|
||||
font-size: 0.95rem;
|
||||
font-weight: 700;
|
||||
text-align: center;
|
||||
line-height: 1.3;
|
||||
}
|
||||
.strang.next .strang-label { color: var(--next); }
|
||||
.strang.done .strang-label { color: var(--done); text-decoration: line-through; text-decoration-color: var(--done); text-decoration-thickness: 1.5px; }
|
||||
.strang-tag {
|
||||
font-size: 0.72rem;
|
||||
font-weight: 700;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.12em;
|
||||
text-align: center;
|
||||
}
|
||||
.strang.next .strang-tag { color: var(--next); }
|
||||
.strang.done .strang-tag { color: var(--done); }
|
||||
|
||||
.verdict {
|
||||
margin-top: 28px;
|
||||
max-width: 1100px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
text-align: center;
|
||||
border: 2px solid var(--hl);
|
||||
border-radius: 12px;
|
||||
padding: 14px 22px;
|
||||
}
|
||||
.verdict-q { font-size: 1.1rem; font-weight: 700; color: var(--hl); }
|
||||
.verdict-a { font-size: 0.95rem; color: var(--dark); margin-top: 4px; }
|
||||
.verdict-a strong { color: var(--hl); }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Wir haben gelernt zu <strong>lesen</strong>. Jetzt: wie kommt es <strong>rein</strong>?</h1>
|
||||
<div class="sub">Die rechte Seite haben wir abgearbeitet. Die linke ist die nächste Stunde.</div>
|
||||
|
||||
<div class="pivot">
|
||||
|
||||
<div class="station">
|
||||
<div class="station-tag">Quelle</div>
|
||||
<div class="station-name">Welt</div>
|
||||
<div class="station-art">
|
||||
<svg viewBox="0 0 120 70" preserveAspectRatio="xMidYMid meet">
|
||||
<path d="M5,35 Q15,10 25,35 T45,35 T65,35 T85,35 T105,35 T115,35"
|
||||
stroke="#d63384" stroke-width="2.5" fill="none"/>
|
||||
<circle cx="115" cy="35" r="3" fill="#d63384"/>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="station-detail">Schallwelle · Lichtwelle<br>kontinuierlich · analog</div>
|
||||
</div>
|
||||
|
||||
<div class="strang next">
|
||||
<div class="strang-tag">jetzt dran</div>
|
||||
<div class="strang-arrow">
|
||||
<svg viewBox="0 0 220 28" preserveAspectRatio="none">
|
||||
<line x1="6" y1="14" x2="200" y2="14" stroke="#d63384" stroke-width="2.5"/>
|
||||
<path d="M195,7 L208,14 L195,21" stroke="#d63384" stroke-width="2.5" fill="none"/>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="strang-label">Sampling + Quantisierung</div>
|
||||
</div>
|
||||
|
||||
<div class="station bytes">
|
||||
<div class="station-tag">Mitte</div>
|
||||
<div class="station-name">Datei</div>
|
||||
<div class="station-detail">
|
||||
89 50 4E 47<br>
|
||||
0D 0A 1A 0A<br>
|
||||
00 00 00 0D
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="strang done">
|
||||
<div class="strang-tag">schon durch</div>
|
||||
<div class="strang-arrow">
|
||||
<svg viewBox="0 0 220 28" preserveAspectRatio="none">
|
||||
<line x1="6" y1="14" x2="200" y2="14" stroke="#94a3b8" stroke-width="2"/>
|
||||
<path d="M195,7 L208,14 L195,21" stroke="#94a3b8" stroke-width="2" fill="none"/>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="strang-label">Notation · Encoding · Format</div>
|
||||
</div>
|
||||
|
||||
<div class="station">
|
||||
<div class="station-tag">Ziel</div>
|
||||
<div class="station-name">Mensch</div>
|
||||
<div class="station-art">
|
||||
<svg viewBox="0 0 120 70" preserveAspectRatio="xMidYMid meet">
|
||||
<rect x="14" y="14" width="92" height="14" rx="2" fill="#1a1a2e"/>
|
||||
<rect x="14" y="34" width="68" height="6" rx="1" fill="#cbd5e1"/>
|
||||
<rect x="14" y="44" width="78" height="6" rx="1" fill="#cbd5e1"/>
|
||||
<rect x="14" y="54" width="56" height="6" rx="1" fill="#cbd5e1"/>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="station-detail">Text · Bild · Klang<br>Bedeutung</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="verdict">
|
||||
<div class="verdict-q">Die Datei ist die Mitte. Beide Wege führen durch sie hindurch.</div>
|
||||
<div class="verdict-a"><strong>Rechts:</strong> aus Byte wird Bedeutung — gerade gelernt. <strong>Links:</strong> aus Welt wird Byte — jetzt.</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
After Width: | Height: | Size: 61 KiB |
@@ -0,0 +1,159 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Psychoakustik — was MP3 weglässt</title>
|
||||
<style>
|
||||
:root {
|
||||
--dark: #1a1a2e;
|
||||
--muted: #6b7280;
|
||||
--soft: #f8fafc;
|
||||
--border: #cbd5e1;
|
||||
--hl: #d63384;
|
||||
--kept: #16a34a;
|
||||
--tossed: #94a3b8;
|
||||
--masker: #2563eb;
|
||||
--threshold: #ea580c;
|
||||
}
|
||||
html, body { margin: 0; padding: 0; background: #fff; font-family: system-ui, -apple-system, sans-serif; color: var(--dark); }
|
||||
body { padding: 30px 40px; }
|
||||
h1 { text-align: center; margin: 0 0 6px; font-size: 1.75rem; }
|
||||
.sub { text-align: center; color: var(--muted); margin-bottom: 22px; font-size: 1.05rem; }
|
||||
.sub strong { color: var(--dark); }
|
||||
|
||||
.chart-wrap {
|
||||
max-width: 1180px;
|
||||
margin: 0 auto;
|
||||
background: #fff;
|
||||
border: 1.5px solid var(--border);
|
||||
border-radius: 12px;
|
||||
padding: 16px 20px;
|
||||
}
|
||||
.chart-head {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: baseline;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
.chart-title { font-size: 1rem; font-weight: 700; }
|
||||
.legend {
|
||||
display: flex;
|
||||
gap: 16px;
|
||||
font-size: 0.78rem;
|
||||
color: var(--muted);
|
||||
}
|
||||
.legend-item { display: flex; align-items: center; gap: 4px; }
|
||||
.legend-swatch {
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
border-radius: 3px;
|
||||
display: inline-block;
|
||||
}
|
||||
.legend-swatch.kept { background: var(--kept); }
|
||||
.legend-swatch.tossed { background: var(--tossed); }
|
||||
.legend-swatch.masker { background: var(--masker); }
|
||||
.legend-swatch.threshold {
|
||||
background: transparent;
|
||||
border-top: 2px dashed var(--threshold);
|
||||
height: 8px;
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
.verdict {
|
||||
margin-top: 22px;
|
||||
max-width: 1180px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
text-align: center;
|
||||
border: 2px solid var(--hl);
|
||||
border-radius: 12px;
|
||||
padding: 14px 22px;
|
||||
}
|
||||
.verdict-q { font-size: 1.1rem; font-weight: 700; color: var(--hl); }
|
||||
.verdict-a { font-size: 0.93rem; color: var(--dark); margin-top: 4px; }
|
||||
.verdict-a strong { color: var(--hl); }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Psychoakustik — was MP3 wegwirft</h1>
|
||||
<div class="sub">Ein lauter Ton macht leise Nachbarn <strong>unhörbar</strong>. Was nicht hörbar ist, muss man nicht speichern.</div>
|
||||
|
||||
<div class="chart-wrap">
|
||||
<div class="chart-head">
|
||||
<div class="chart-title">Lautstärke (dB SPL) über Frequenz (Hz, logarithmisch)</div>
|
||||
<div class="legend">
|
||||
<span class="legend-item"><span class="legend-swatch masker"></span>lauter Ton (Masker)</span>
|
||||
<span class="legend-item"><span class="legend-swatch kept"></span>hörbar · bleibt</span>
|
||||
<span class="legend-item"><span class="legend-swatch tossed"></span>maskiert · raus</span>
|
||||
<span class="legend-item"><span class="legend-swatch threshold"></span>Hörschwelle</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<svg viewBox="0 0 1100 380" width="100%" height="380">
|
||||
<line x1="80" y1="340" x2="1060" y2="340" stroke="#1a1a2e" stroke-width="1.5"/>
|
||||
<line x1="80" y1="20" x2="80" y2="340" stroke="#1a1a2e" stroke-width="1.5"/>
|
||||
|
||||
<text x="20" y="30" font-size="11" fill="#6b7280">dB</text>
|
||||
<text x="40" y="50" font-size="10" fill="#6b7280" text-anchor="end">100</text>
|
||||
<text x="40" y="125" font-size="10" fill="#6b7280" text-anchor="end">75</text>
|
||||
<text x="40" y="200" font-size="10" fill="#6b7280" text-anchor="end">50</text>
|
||||
<text x="40" y="275" font-size="10" fill="#6b7280" text-anchor="end">25</text>
|
||||
<text x="40" y="345" font-size="10" fill="#6b7280" text-anchor="end">0</text>
|
||||
|
||||
<line x1="75" y1="50" x2="80" y2="50" stroke="#1a1a2e"/>
|
||||
<line x1="75" y1="125" x2="80" y2="125" stroke="#1a1a2e"/>
|
||||
<line x1="75" y1="200" x2="80" y2="200" stroke="#1a1a2e"/>
|
||||
<line x1="75" y1="275" x2="80" y2="275" stroke="#1a1a2e"/>
|
||||
|
||||
<text x="100" y="360" font-size="10" fill="#6b7280">20</text>
|
||||
<text x="260" y="360" font-size="10" fill="#6b7280">100</text>
|
||||
<text x="420" y="360" font-size="10" fill="#6b7280">500</text>
|
||||
<text x="580" y="360" font-size="10" fill="#6b7280">1k</text>
|
||||
<text x="740" y="360" font-size="10" fill="#6b7280">5k</text>
|
||||
<text x="900" y="360" font-size="10" fill="#6b7280">10k</text>
|
||||
<text x="1040" y="360" font-size="10" fill="#6b7280">20k</text>
|
||||
<text x="540" y="378" font-size="11" fill="#6b7280" text-anchor="middle">Frequenz [Hz]</text>
|
||||
|
||||
<path d="M100,80 Q170,130 260,200 Q350,290 420,310 Q500,335 580,330 Q670,310 740,295 Q820,280 900,250 Q970,200 1040,80"
|
||||
stroke="#ea580c" stroke-width="2" stroke-dasharray="5,5" fill="none"/>
|
||||
|
||||
<path d="M460,340 L460,210 Q480,165 580,80 Q680,165 700,210 L700,340 Z"
|
||||
fill="#2563eb" opacity="0.15"/>
|
||||
<path d="M460,340 L460,210 Q480,165 580,80 Q680,165 700,210 L700,340"
|
||||
stroke="#2563eb" stroke-width="2" fill="none" stroke-dasharray="2,3"/>
|
||||
|
||||
<rect x="572" y="80" width="16" height="260" fill="#2563eb"/>
|
||||
|
||||
<circle cx="240" cy="270" r="6" fill="#16a34a"/>
|
||||
<text x="240" y="260" font-size="10" fill="#16a34a" text-anchor="middle" font-weight="700">bleibt</text>
|
||||
|
||||
<circle cx="420" cy="240" r="6" fill="#16a34a"/>
|
||||
<text x="420" y="230" font-size="10" fill="#16a34a" text-anchor="middle" font-weight="700">bleibt</text>
|
||||
|
||||
<circle cx="510" cy="180" r="6" fill="#94a3b8"/>
|
||||
<text x="510" y="170" font-size="10" fill="#94a3b8" text-anchor="middle">raus</text>
|
||||
|
||||
<circle cx="660" cy="200" r="6" fill="#94a3b8"/>
|
||||
<text x="660" y="190" font-size="10" fill="#94a3b8" text-anchor="middle">raus</text>
|
||||
|
||||
<circle cx="640" cy="155" r="6" fill="#94a3b8"/>
|
||||
<text x="640" y="145" font-size="10" fill="#94a3b8" text-anchor="middle">raus</text>
|
||||
|
||||
<circle cx="860" cy="220" r="6" fill="#16a34a"/>
|
||||
<text x="860" y="210" font-size="10" fill="#16a34a" text-anchor="middle" font-weight="700">bleibt</text>
|
||||
|
||||
<circle cx="960" cy="170" r="6" fill="#16a34a"/>
|
||||
<text x="960" y="160" font-size="10" fill="#16a34a" text-anchor="middle" font-weight="700">bleibt</text>
|
||||
|
||||
<text x="595" y="76" font-size="11" fill="#2563eb" font-weight="700">1 kHz · 90 dB · "Masker"</text>
|
||||
<text x="780" y="105" font-size="11" fill="#ea580c" font-weight="700">Hörschwelle (in Ruhe)</text>
|
||||
<text x="540" y="160" font-size="11" fill="#2563eb" font-weight="700" text-anchor="middle">Maskierungs-Bereich</text>
|
||||
</svg>
|
||||
</div>
|
||||
|
||||
<div class="verdict">
|
||||
<div class="verdict-q">MP3 kodiert nur, was über der <strong>kombinierten Schwelle</strong> liegt.</div>
|
||||
<div class="verdict-a">Alles unterhalb wird weggeworfen — das Ohr hört es ohnehin nicht. So spart MP3 typischerweise <strong>~90 % der Daten</strong>, ohne dass der Mensch im Alltag etwas vermisst.</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
After Width: | Height: | Size: 77 KiB |
@@ -0,0 +1,222 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Psychovisualität — Luminanz vor Chrominanz</title>
|
||||
<style>
|
||||
:root {
|
||||
--dark: #1a1a2e;
|
||||
--muted: #6b7280;
|
||||
--soft: #f8fafc;
|
||||
--border: #cbd5e1;
|
||||
--hl: #d63384;
|
||||
--full: #2563eb;
|
||||
--reduced: #7c3aed;
|
||||
--y: #1a1a2e;
|
||||
--cb: #2563eb;
|
||||
--cr: #ef4444;
|
||||
--bar-bg: #e2e8f0;
|
||||
}
|
||||
html, body { margin: 0; padding: 0; background: #fff; font-family: system-ui, -apple-system, sans-serif; color: var(--dark); }
|
||||
body { padding: 30px 40px; }
|
||||
h1 { text-align: center; margin: 0 0 6px; font-size: 1.75rem; }
|
||||
.sub { text-align: center; color: var(--muted); margin-bottom: 24px; font-size: 1.05rem; }
|
||||
.sub strong { color: var(--dark); }
|
||||
|
||||
.compare {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 22px;
|
||||
max-width: 1180px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.col {
|
||||
border: 2px solid;
|
||||
border-radius: 12px;
|
||||
padding: 16px 20px;
|
||||
background: #fff;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 12px;
|
||||
}
|
||||
.col.full { border-color: var(--full); }
|
||||
.col.reduced { border-color: var(--reduced); }
|
||||
|
||||
.col-head { display: flex; justify-content: space-between; align-items: baseline; }
|
||||
.col-tag {
|
||||
font-size: 0.72rem;
|
||||
font-weight: 700;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.12em;
|
||||
color: var(--muted);
|
||||
}
|
||||
.col-name { font-size: 1.25rem; font-weight: 700; }
|
||||
.col.full .col-name { color: var(--full); }
|
||||
.col.reduced .col-name { color: var(--reduced); }
|
||||
.col-format {
|
||||
font-family: ui-monospace, monospace;
|
||||
font-size: 0.82rem;
|
||||
color: var(--muted);
|
||||
}
|
||||
|
||||
.preview {
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
border: 1px solid var(--border);
|
||||
}
|
||||
.preview svg { display: block; }
|
||||
|
||||
.channels {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 6px;
|
||||
}
|
||||
.channel { display: grid; grid-template-columns: 90px 1fr 60px; gap: 8px; align-items: center; font-size: 0.85rem; }
|
||||
.channel-label {
|
||||
font-family: ui-monospace, monospace;
|
||||
font-weight: 700;
|
||||
}
|
||||
.channel-bar { height: 14px; background: var(--bar-bg); border-radius: 3px; overflow: hidden; }
|
||||
.channel-bar .fill { height: 100%; border-radius: 3px; }
|
||||
.channel-bar .fill.y { background: var(--y); }
|
||||
.channel-bar .fill.cb { background: var(--cb); }
|
||||
.channel-bar .fill.cr { background: var(--cr); }
|
||||
.channel-pct {
|
||||
font-family: ui-monospace, monospace;
|
||||
font-size: 0.78rem;
|
||||
color: var(--muted);
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.summary-line {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
background: var(--soft);
|
||||
border-radius: 6px;
|
||||
padding: 6px 12px;
|
||||
font-family: ui-monospace, monospace;
|
||||
font-size: 0.85rem;
|
||||
color: var(--dark);
|
||||
}
|
||||
.summary-line strong { color: var(--hl); }
|
||||
|
||||
.verdict {
|
||||
margin-top: 22px;
|
||||
max-width: 1180px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
text-align: center;
|
||||
border: 2px solid var(--hl);
|
||||
border-radius: 12px;
|
||||
padding: 14px 22px;
|
||||
}
|
||||
.verdict-q { font-size: 1.1rem; font-weight: 700; color: var(--hl); }
|
||||
.verdict-a { font-size: 0.93rem; color: var(--dark); margin-top: 4px; }
|
||||
.verdict-a strong { color: var(--hl); }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Psychovisualität — Luminanz vor Chrominanz</h1>
|
||||
<div class="sub">Das Auge sieht <strong>Helligkeit</strong> scharf. <strong>Farbe</strong> darf grob bleiben — und das Bild sieht trotzdem identisch aus.</div>
|
||||
|
||||
<div class="compare">
|
||||
|
||||
<div class="col full">
|
||||
<div class="col-head">
|
||||
<span class="col-name">Ohne Subsampling</span>
|
||||
<span class="col-tag">4:4:4</span>
|
||||
</div>
|
||||
<div class="col-format">jedes Pixel speichert Y · Cb · Cr in voller Auflösung</div>
|
||||
|
||||
<svg class="preview" viewBox="0 0 320 130" preserveAspectRatio="xMidYMid slice">
|
||||
<defs>
|
||||
<linearGradient id="full-sky" x1="0" y1="0" x2="0" y2="1">
|
||||
<stop offset="0%" stop-color="#fde68a"/>
|
||||
<stop offset="55%" stop-color="#fb923c"/>
|
||||
<stop offset="100%" stop-color="#7c3aed"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<rect x="0" y="0" width="320" height="130" fill="url(#full-sky)"/>
|
||||
<circle cx="230" cy="50" r="22" fill="#fef3c7"/>
|
||||
<path d="M0,90 L40,75 L90,87 L140,68 L190,82 L240,66 L290,80 L320,72 L320,130 L0,130 Z" fill="#1e1b4b"/>
|
||||
<path d="M0,108 L60,100 L120,108 L180,98 L240,106 L300,98 L320,103 L320,130 L0,130 Z" fill="#0f172a" opacity="0.7"/>
|
||||
</svg>
|
||||
|
||||
<div class="channels">
|
||||
<div class="channel">
|
||||
<span class="channel-label">Y</span>
|
||||
<div class="channel-bar"><div class="fill y" style="width:100%"></div></div>
|
||||
<span class="channel-pct">100 %</span>
|
||||
</div>
|
||||
<div class="channel">
|
||||
<span class="channel-label">Cb</span>
|
||||
<div class="channel-bar"><div class="fill cb" style="width:100%"></div></div>
|
||||
<span class="channel-pct">100 %</span>
|
||||
</div>
|
||||
<div class="channel">
|
||||
<span class="channel-label">Cr</span>
|
||||
<div class="channel-bar"><div class="fill cr" style="width:100%"></div></div>
|
||||
<span class="channel-pct">100 %</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="summary-line">
|
||||
<span>Datenmenge:</span>
|
||||
<span><strong>100 %</strong></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col reduced">
|
||||
<div class="col-head">
|
||||
<span class="col-name">JPEG · H.264 Standard</span>
|
||||
<span class="col-tag">4:2:0</span>
|
||||
</div>
|
||||
<div class="col-format">Y voll · Cb & Cr nur in 2×2-Pixel-Blöcken</div>
|
||||
|
||||
<svg class="preview" viewBox="0 0 320 130" preserveAspectRatio="xMidYMid slice">
|
||||
<defs>
|
||||
<linearGradient id="red-sky" x1="0" y1="0" x2="0" y2="1">
|
||||
<stop offset="0%" stop-color="#fde68a"/>
|
||||
<stop offset="55%" stop-color="#fb923c"/>
|
||||
<stop offset="100%" stop-color="#7c3aed"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<rect x="0" y="0" width="320" height="130" fill="url(#red-sky)"/>
|
||||
<circle cx="230" cy="50" r="22" fill="#fef3c7"/>
|
||||
<path d="M0,90 L40,75 L90,87 L140,68 L190,82 L240,66 L290,80 L320,72 L320,130 L0,130 Z" fill="#1e1b4b"/>
|
||||
<path d="M0,108 L60,100 L120,108 L180,98 L240,106 L300,98 L320,103 L320,130 L0,130 Z" fill="#0f172a" opacity="0.7"/>
|
||||
</svg>
|
||||
|
||||
<div class="channels">
|
||||
<div class="channel">
|
||||
<span class="channel-label">Y</span>
|
||||
<div class="channel-bar"><div class="fill y" style="width:100%"></div></div>
|
||||
<span class="channel-pct">100 %</span>
|
||||
</div>
|
||||
<div class="channel">
|
||||
<span class="channel-label">Cb</span>
|
||||
<div class="channel-bar"><div class="fill cb" style="width:25%"></div></div>
|
||||
<span class="channel-pct">25 %</span>
|
||||
</div>
|
||||
<div class="channel">
|
||||
<span class="channel-label">Cr</span>
|
||||
<div class="channel-bar"><div class="fill cr" style="width:25%"></div></div>
|
||||
<span class="channel-pct">25 %</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="summary-line">
|
||||
<span>Datenmenge:</span>
|
||||
<span><strong>50 %</strong></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="verdict">
|
||||
<div class="verdict-q">Halbe Datenmenge. Identisches Bild — für dein Auge.</div>
|
||||
<div class="verdict-a">JPEG, H.264, H.265, WebP — alle reduzieren die Farb-Auflösung auf <strong>ein Viertel</strong>. Das ist Psychovisualität: was wir nicht scharf sehen, muss man nicht scharf speichern.</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
After Width: | Height: | Size: 76 KiB |
@@ -0,0 +1,212 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Raster vs. Vektor — Pixel oder Anweisung?</title>
|
||||
<style>
|
||||
:root {
|
||||
--dark: #1a1a2e;
|
||||
--muted: #6b7280;
|
||||
--soft: #f8fafc;
|
||||
--border: #cbd5e1;
|
||||
--hl: #d63384;
|
||||
--raster: #ea580c;
|
||||
--vektor: #2563eb;
|
||||
}
|
||||
html, body { margin: 0; padding: 0; background: #fff; font-family: system-ui, -apple-system, sans-serif; color: var(--dark); }
|
||||
body { padding: 30px 40px; }
|
||||
h1 { text-align: center; margin: 0 0 6px; font-size: 1.75rem; }
|
||||
.sub { text-align: center; color: var(--muted); margin-bottom: 24px; font-size: 1.05rem; }
|
||||
.sub strong { color: var(--dark); }
|
||||
|
||||
.pair {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 22px;
|
||||
max-width: 1180px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.col {
|
||||
border: 2px solid;
|
||||
border-radius: 12px;
|
||||
padding: 16px 18px;
|
||||
background: #fff;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 10px;
|
||||
}
|
||||
.col.raster { border-color: var(--raster); }
|
||||
.col.vektor { border-color: var(--vektor); }
|
||||
|
||||
.col-head { display: flex; justify-content: space-between; align-items: baseline; }
|
||||
.col-name { font-size: 1.3rem; font-weight: 700; }
|
||||
.col.raster .col-name { color: var(--raster); }
|
||||
.col.vektor .col-name { color: var(--vektor); }
|
||||
.col-tag {
|
||||
font-size: 0.72rem;
|
||||
font-weight: 700;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.12em;
|
||||
color: var(--muted);
|
||||
}
|
||||
.col-desc { font-size: 0.85rem; color: var(--muted); line-height: 1.4; }
|
||||
|
||||
.views {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 8px;
|
||||
}
|
||||
.view { display: flex; flex-direction: column; gap: 4px; }
|
||||
.view-label {
|
||||
font-size: 0.68rem;
|
||||
font-weight: 700;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.1em;
|
||||
color: var(--muted);
|
||||
text-align: center;
|
||||
}
|
||||
.view-canvas {
|
||||
background: var(--soft);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 6px;
|
||||
aspect-ratio: 1.4;
|
||||
overflow: hidden;
|
||||
}
|
||||
.view-canvas svg { display: block; width: 100%; height: 100%; }
|
||||
|
||||
.stats {
|
||||
background: var(--soft);
|
||||
border-radius: 6px;
|
||||
padding: 8px 12px;
|
||||
font-family: ui-monospace, monospace;
|
||||
font-size: 0.82rem;
|
||||
color: var(--dark);
|
||||
line-height: 1.5;
|
||||
}
|
||||
.stats .key { color: var(--muted); }
|
||||
.stats .val { font-weight: 700; }
|
||||
|
||||
.verdict {
|
||||
margin-top: 22px;
|
||||
max-width: 1180px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
text-align: center;
|
||||
border: 2px solid var(--hl);
|
||||
border-radius: 12px;
|
||||
padding: 14px 22px;
|
||||
}
|
||||
.verdict-q { font-size: 1.1rem; font-weight: 700; color: var(--hl); }
|
||||
.verdict-a { font-size: 0.93rem; color: var(--dark); margin-top: 4px; }
|
||||
.verdict-a strong { color: var(--hl); }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Raster vs. Vektor — Pixel oder Anweisung?</h1>
|
||||
<div class="sub">Beide zeigen ein Häkchen. Wenn man <strong>reinzoomt</strong>, kommt die Wahrheit raus.</div>
|
||||
|
||||
<div class="pair">
|
||||
|
||||
<div class="col raster">
|
||||
<div class="col-head">
|
||||
<span class="col-name">Raster</span>
|
||||
<span class="col-tag">PNG · JPEG · GIF</span>
|
||||
</div>
|
||||
<div class="col-desc">Ein Gitter aus Pixel-Farbwerten. Jede Position ist festgelegt.</div>
|
||||
|
||||
<div class="views">
|
||||
<div class="view">
|
||||
<div class="view-label">Original (32 × 22 px)</div>
|
||||
<div class="view-canvas">
|
||||
<svg viewBox="0 0 320 220" preserveAspectRatio="xMidYMid meet">
|
||||
<rect x="0" y="0" width="320" height="220" fill="#f8fafc"/>
|
||||
<g shape-rendering="crispEdges">
|
||||
<rect x="20" y="120" width="20" height="20" fill="#ea580c"/>
|
||||
<rect x="40" y="140" width="20" height="20" fill="#ea580c"/>
|
||||
<rect x="60" y="160" width="20" height="20" fill="#ea580c"/>
|
||||
<rect x="80" y="180" width="20" height="20" fill="#ea580c"/>
|
||||
<rect x="100" y="160" width="20" height="20" fill="#ea580c"/>
|
||||
<rect x="120" y="140" width="20" height="20" fill="#ea580c"/>
|
||||
<rect x="140" y="120" width="20" height="20" fill="#ea580c"/>
|
||||
<rect x="160" y="100" width="20" height="20" fill="#ea580c"/>
|
||||
<rect x="180" y="80" width="20" height="20" fill="#ea580c"/>
|
||||
<rect x="200" y="60" width="20" height="20" fill="#ea580c"/>
|
||||
<rect x="220" y="40" width="20" height="20" fill="#ea580c"/>
|
||||
<rect x="240" y="20" width="20" height="20" fill="#ea580c"/>
|
||||
</g>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
<div class="view">
|
||||
<div class="view-label">4× Zoom</div>
|
||||
<div class="view-canvas">
|
||||
<svg viewBox="80 60 160 160" preserveAspectRatio="xMidYMid meet">
|
||||
<rect x="0" y="0" width="320" height="220" fill="#f8fafc"/>
|
||||
<g shape-rendering="crispEdges">
|
||||
<rect x="20" y="120" width="20" height="20" fill="#ea580c"/>
|
||||
<rect x="40" y="140" width="20" height="20" fill="#ea580c"/>
|
||||
<rect x="60" y="160" width="20" height="20" fill="#ea580c"/>
|
||||
<rect x="80" y="180" width="20" height="20" fill="#ea580c"/>
|
||||
<rect x="100" y="160" width="20" height="20" fill="#ea580c"/>
|
||||
<rect x="120" y="140" width="20" height="20" fill="#ea580c"/>
|
||||
<rect x="140" y="120" width="20" height="20" fill="#ea580c"/>
|
||||
<rect x="160" y="100" width="20" height="20" fill="#ea580c"/>
|
||||
<rect x="180" y="80" width="20" height="20" fill="#ea580c"/>
|
||||
<rect x="200" y="60" width="20" height="20" fill="#ea580c"/>
|
||||
<rect x="220" y="40" width="20" height="20" fill="#ea580c"/>
|
||||
<rect x="240" y="20" width="20" height="20" fill="#ea580c"/>
|
||||
</g>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="stats">
|
||||
<div><span class="key">Speicher:</span> <span class="val">32 × 22 × 3 Byte = 2 112 Byte</span></div>
|
||||
<div><span class="key">Beim Zoom:</span> <span class="val">pixelig — Information ist erschöpft</span></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col vektor">
|
||||
<div class="col-head">
|
||||
<span class="col-name">Vektor</span>
|
||||
<span class="col-tag">SVG · PDF · Schriftarten</span>
|
||||
</div>
|
||||
<div class="col-desc">Mathematische Anweisungen: <code style="background:#0f0f23;color:#5fb3e4;padding:0 4px;border-radius:3px;">polyline 30,110 → 90,170 → 250,30</code></div>
|
||||
|
||||
<div class="views">
|
||||
<div class="view">
|
||||
<div class="view-label">Original</div>
|
||||
<div class="view-canvas">
|
||||
<svg viewBox="0 0 320 220" preserveAspectRatio="xMidYMid meet">
|
||||
<rect x="0" y="0" width="320" height="220" fill="#f8fafc"/>
|
||||
<polyline points="30,130 90,190 270,30" stroke="#2563eb" stroke-width="14" fill="none" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
<div class="view">
|
||||
<div class="view-label">4× Zoom</div>
|
||||
<div class="view-canvas">
|
||||
<svg viewBox="80 60 160 160" preserveAspectRatio="xMidYMid meet">
|
||||
<rect x="0" y="0" width="320" height="220" fill="#f8fafc"/>
|
||||
<polyline points="30,130 90,190 270,30" stroke="#2563eb" stroke-width="14" fill="none" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="stats">
|
||||
<div><span class="key">Speicher:</span> <span class="val">3 Punkte + Strichbreite = ~80 Byte</span></div>
|
||||
<div><span class="key">Beim Zoom:</span> <span class="val">scharf — wird neu berechnet</span></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="verdict">
|
||||
<div class="verdict-q">Pixel sind festgenagelt. Vektoren werden bei jedem Zoom <strong>neu berechnet</strong>.</div>
|
||||
<div class="verdict-a">Faustregel: <strong>Foto → Raster</strong> (kann nicht „neu berechnet" werden). <strong>Logo, Icon, Schrift → Vektor</strong> (skalierbar ohne Verlust).</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
After Width: | Height: | Size: 76 KiB |
@@ -0,0 +1,189 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Was wir über Kompression gelernt haben</title>
|
||||
<style>
|
||||
:root {
|
||||
--dark: #1a1a2e;
|
||||
--muted: #6b7280;
|
||||
--soft: #f8fafc;
|
||||
--border: #cbd5e1;
|
||||
--hl: #d63384;
|
||||
--lossless: #16a34a;
|
||||
--lossy: #ef4444;
|
||||
}
|
||||
html, body { margin: 0; padding: 0; background: #fff; font-family: system-ui, -apple-system, sans-serif; color: var(--dark); }
|
||||
body { padding: 30px 40px; }
|
||||
h1 { text-align: center; margin: 0 0 6px; font-size: 1.75rem; }
|
||||
.sub { text-align: center; color: var(--muted); margin-bottom: 26px; font-size: 1.05rem; }
|
||||
.sub strong { color: var(--dark); }
|
||||
|
||||
.compare {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 22px;
|
||||
max-width: 1180px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.col {
|
||||
border: 2px solid;
|
||||
border-radius: 12px;
|
||||
padding: 18px 22px;
|
||||
background: #fff;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 12px;
|
||||
}
|
||||
.col.lossless { border-color: var(--lossless); }
|
||||
.col.lossy { border-color: var(--lossy); }
|
||||
|
||||
.col-head { display: flex; justify-content: space-between; align-items: baseline; }
|
||||
.col-name { font-size: 1.4rem; font-weight: 700; }
|
||||
.col.lossless .col-name { color: var(--lossless); }
|
||||
.col.lossy .col-name { color: var(--lossy); }
|
||||
.col-tag {
|
||||
font-size: 0.72rem;
|
||||
font-weight: 700;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.12em;
|
||||
color: var(--muted);
|
||||
}
|
||||
|
||||
.row { display: grid; grid-template-columns: 120px 1fr; gap: 10px 14px; }
|
||||
.row-key {
|
||||
font-size: 0.72rem;
|
||||
font-weight: 700;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.08em;
|
||||
color: var(--muted);
|
||||
padding-top: 3px;
|
||||
}
|
||||
.row-val { font-size: 0.92rem; line-height: 1.5; color: var(--dark); }
|
||||
.row-val strong {
|
||||
font-family: ui-monospace, monospace;
|
||||
background: var(--soft);
|
||||
padding: 1px 6px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.matrix {
|
||||
margin-top: 22px;
|
||||
max-width: 1180px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
background: var(--soft);
|
||||
border: 1.5px solid var(--border);
|
||||
border-radius: 10px;
|
||||
padding: 14px 22px;
|
||||
}
|
||||
.matrix-head {
|
||||
font-size: 0.78rem;
|
||||
font-weight: 700;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.1em;
|
||||
color: var(--muted);
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
.matrix-grid {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr 1fr 1fr;
|
||||
gap: 8px 16px;
|
||||
font-size: 0.88rem;
|
||||
}
|
||||
.matrix-grid .scenario { font-weight: 700; color: var(--dark); }
|
||||
.matrix-grid .answer {
|
||||
font-family: ui-monospace, monospace;
|
||||
color: var(--dark);
|
||||
}
|
||||
.matrix-grid .answer.lossless { color: var(--lossless); font-weight: 700; }
|
||||
.matrix-grid .answer.lossy { color: var(--lossy); font-weight: 700; }
|
||||
|
||||
.verdict {
|
||||
margin-top: 18px;
|
||||
max-width: 1180px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
text-align: center;
|
||||
border: 2px solid var(--hl);
|
||||
border-radius: 12px;
|
||||
padding: 14px 22px;
|
||||
}
|
||||
.verdict-q { font-size: 1.1rem; font-weight: 700; color: var(--hl); }
|
||||
.verdict-a { font-size: 0.93rem; color: var(--dark); margin-top: 4px; }
|
||||
.verdict-a strong { color: var(--hl); }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Was wir über Kompression gelernt haben</h1>
|
||||
<div class="sub">Zwei fundamental verschiedene Wege, dasselbe Ziel: <strong>Daten kleiner machen.</strong></div>
|
||||
|
||||
<div class="compare">
|
||||
|
||||
<div class="col lossless">
|
||||
<div class="col-head">
|
||||
<span class="col-name">Verlustfrei</span>
|
||||
<span class="col-tag">Lossless</span>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="row-key">Was passiert</div>
|
||||
<div class="row-val">Redundanz raus — Wiederholungen kürzer schreiben</div>
|
||||
<div class="row-key">Umkehrbar</div>
|
||||
<div class="row-val">Ja. Aus der komprimierten Datei wird das <strong>exakte</strong> Original wieder.</div>
|
||||
<div class="row-key">Verfahren</div>
|
||||
<div class="row-val">RLE, Huffman, Deflate, LZ77/LZ78</div>
|
||||
<div class="row-key">Formate</div>
|
||||
<div class="row-val">ZIP · PNG · FLAC · TIFF · RAW</div>
|
||||
<div class="row-key">Faktor</div>
|
||||
<div class="row-val">2× – 5× (typisch)</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col lossy">
|
||||
<div class="col-head">
|
||||
<span class="col-name">Verlustbehaftet</span>
|
||||
<span class="col-tag">Lossy</span>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="row-key">Was passiert</div>
|
||||
<div class="row-val">Irrelevanz raus — was Mensch nicht wahrnimmt, wird weggeworfen</div>
|
||||
<div class="row-key">Umkehrbar</div>
|
||||
<div class="row-val">Nein. Einmal weg, für immer weg.</div>
|
||||
<div class="row-key">Trick</div>
|
||||
<div class="row-val">Psychoakustik (MP3) · Psychovisualität (JPEG)</div>
|
||||
<div class="row-key">Formate</div>
|
||||
<div class="row-val">MP3 · AAC · JPEG · WebP · H.264 · H.265</div>
|
||||
<div class="row-key">Faktor</div>
|
||||
<div class="row-val">10× – 100× (typisch)</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="matrix">
|
||||
<div class="matrix-head">Entscheidungsmatrix — wann nehme ich welches?</div>
|
||||
<div class="matrix-grid">
|
||||
<div class="scenario">Foto-Archiv (RAW)</div>
|
||||
<div class="answer lossless">Lossless</div>
|
||||
<div class="scenario">Spotify-Stream</div>
|
||||
<div class="answer lossy">Lossy</div>
|
||||
|
||||
<div class="scenario">Code-Repository</div>
|
||||
<div class="answer lossless">Lossless (ZIP)</div>
|
||||
<div class="scenario">Instagram-Foto</div>
|
||||
<div class="answer lossy">Lossy (JPEG)</div>
|
||||
|
||||
<div class="scenario">Studio-Master-Track</div>
|
||||
<div class="answer lossless">Lossless (FLAC)</div>
|
||||
<div class="scenario">YouTube-Video</div>
|
||||
<div class="answer lossy">Lossy (H.264)</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="verdict">
|
||||
<div class="verdict-q">Lossless für Archiv und Code. Lossy für Streaming und Anzeige.</div>
|
||||
<div class="verdict-a">Faustregel: <strong>Werkzeug</strong> (du arbeitest noch dran) → Lossless. <strong>Konsum</strong> (du schaust/hörst nur) → Lossy.</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
After Width: | Height: | Size: 108 KiB |
@@ -0,0 +1,188 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Was wir in 90 Minuten gelernt haben</title>
|
||||
<style>
|
||||
:root {
|
||||
--dark: #1a1a2e;
|
||||
--muted: #6b7280;
|
||||
--soft: #f8fafc;
|
||||
--border: #cbd5e1;
|
||||
--hl: #d63384;
|
||||
--left: #d63384;
|
||||
--right: #0891b2;
|
||||
--bytes: #0891b2;
|
||||
}
|
||||
html, body { margin: 0; padding: 0; background: #fff; font-family: system-ui, -apple-system, sans-serif; color: var(--dark); }
|
||||
body { padding: 30px 40px; }
|
||||
h1 { text-align: center; margin: 0 0 6px; font-size: 1.75rem; }
|
||||
.sub { text-align: center; color: var(--muted); margin-bottom: 28px; font-size: 1.05rem; }
|
||||
.sub strong { color: var(--dark); }
|
||||
|
||||
.recap {
|
||||
display: grid;
|
||||
grid-template-columns: 160px 1fr 200px 1fr 160px;
|
||||
gap: 10px;
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.station {
|
||||
border: 2px solid var(--border);
|
||||
border-radius: 10px;
|
||||
padding: 18px 12px;
|
||||
background: #fff;
|
||||
text-align: center;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
}
|
||||
.station.bytes { border-color: var(--bytes); background: #0f0f23; color: #fff; }
|
||||
.station-tag {
|
||||
font-size: 0.7rem;
|
||||
font-weight: 700;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.12em;
|
||||
color: var(--muted);
|
||||
}
|
||||
.station.bytes .station-tag { color: #94a3b8; }
|
||||
.station-name { font-size: 1.3rem; font-weight: 700; }
|
||||
.station.bytes .station-name { color: #67e8f9; }
|
||||
.station-detail { font-size: 0.78rem; color: var(--muted); line-height: 1.35; }
|
||||
.station.bytes .station-detail { color: #94a3b8; font-family: ui-monospace, monospace; font-size: 0.76rem; line-height: 1.35; }
|
||||
|
||||
.strang {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 6px;
|
||||
padding: 0 6px;
|
||||
}
|
||||
.strang-arrow { text-align: center; }
|
||||
.strang-arrow svg { width: 100%; height: 18px; }
|
||||
.strang-title {
|
||||
font-size: 0.92rem;
|
||||
font-weight: 700;
|
||||
text-align: center;
|
||||
line-height: 1.3;
|
||||
}
|
||||
.strang.left .strang-title { color: var(--left); }
|
||||
.strang.right .strang-title { color: var(--right); }
|
||||
.strang-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 3px;
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
background: var(--soft);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 8px;
|
||||
padding: 8px 12px;
|
||||
}
|
||||
.strang-list li {
|
||||
font-size: 0.82rem;
|
||||
color: var(--dark);
|
||||
padding-left: 12px;
|
||||
position: relative;
|
||||
line-height: 1.4;
|
||||
}
|
||||
.strang-list li::before {
|
||||
content: "·";
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
font-weight: 700;
|
||||
}
|
||||
.strang.left .strang-list li::before { color: var(--left); }
|
||||
.strang.right .strang-list li::before { color: var(--right); }
|
||||
|
||||
.verdict {
|
||||
margin-top: 22px;
|
||||
max-width: 1200px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
text-align: center;
|
||||
border: 2px solid var(--hl);
|
||||
border-radius: 12px;
|
||||
padding: 14px 22px;
|
||||
}
|
||||
.verdict-q { font-size: 1.1rem; font-weight: 700; color: var(--hl); }
|
||||
.verdict-a { font-size: 0.95rem; color: var(--dark); margin-top: 4px; }
|
||||
.verdict-a strong { color: var(--hl); }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Was wir in 90 Minuten gelernt haben</h1>
|
||||
<div class="sub">Beide Wege gehen durch <strong>dieselbe Mitte</strong>. Du kennst jetzt alle Stationen.</div>
|
||||
|
||||
<div class="recap">
|
||||
|
||||
<div class="station">
|
||||
<div class="station-tag">Quelle</div>
|
||||
<div class="station-name">Welt</div>
|
||||
<div class="station-detail">Schallwelle<br>Lichtwelle<br>kontinuierlich · analog</div>
|
||||
</div>
|
||||
|
||||
<div class="strang left">
|
||||
<div class="strang-arrow">
|
||||
<svg viewBox="0 0 200 18" preserveAspectRatio="none">
|
||||
<line x1="6" y1="9" x2="180" y2="9" stroke="#d63384" stroke-width="2"/>
|
||||
<path d="M174,3 L188,9 L174,15" stroke="#d63384" stroke-width="2" fill="none"/>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="strang-title">Welt → Byte</div>
|
||||
<ul class="strang-list">
|
||||
<li>Sampling-Rate</li>
|
||||
<li>Bittiefe · Quantisierung</li>
|
||||
<li>Datenrate-Formel</li>
|
||||
<li>Nyquist · 2·f<sub>max</sub></li>
|
||||
<li>Aliasing & Moiré</li>
|
||||
<li>44,1 kHz = 2·20 kHz + Marge</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="station bytes">
|
||||
<div class="station-tag">Mitte</div>
|
||||
<div class="station-name">Datei</div>
|
||||
<div class="station-detail">
|
||||
Byte-Strom<br>
|
||||
89 50 4E 47<br>
|
||||
nichts als Zahlen
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="strang right">
|
||||
<div class="strang-arrow">
|
||||
<svg viewBox="0 0 200 18" preserveAspectRatio="none">
|
||||
<line x1="6" y1="9" x2="180" y2="9" stroke="#0891b2" stroke-width="2"/>
|
||||
<path d="M174,3 L188,9 L174,15" stroke="#0891b2" stroke-width="2" fill="none"/>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="strang-title">Byte → Bedeutung</div>
|
||||
<ul class="strang-list">
|
||||
<li>Bit · Byte · Hex</li>
|
||||
<li>8 Bit = 256 Zustände</li>
|
||||
<li>ASCII · UTF-8</li>
|
||||
<li>Magic Number</li>
|
||||
<li>KB vs KiB</li>
|
||||
<li>Hex im Alltag (CSS, MAC)</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="station">
|
||||
<div class="station-tag">Ziel</div>
|
||||
<div class="station-name">Mensch</div>
|
||||
<div class="station-detail">Text · Bild · Klang<br>Bedeutung<br>verstehen</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="verdict">
|
||||
<div class="verdict-q">Eine Datei ist kein Mysterium. Es ist eine <strong>Reihe von Zahlen</strong> mit zwei Geschichten dran.</div>
|
||||
<div class="verdict-a">Eine Geschichte erzählt, <strong>woher</strong> die Zahlen kommen. Die andere, <strong>was</strong> sie bedeuten. Beide kennst du jetzt.</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
After Width: | Height: | Size: 76 KiB |
@@ -0,0 +1,120 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Dieselben Byte — drei Perspektiven</title>
|
||||
<style>
|
||||
:root {
|
||||
--hl: #d63384;
|
||||
--dark: #1a1a2e;
|
||||
--muted: #6b7280;
|
||||
--border: #cbd5e1;
|
||||
--bg-soft: #f8fafc;
|
||||
--magic: #ef4444;
|
||||
--format: #2563eb;
|
||||
--transport: #16a34a;
|
||||
}
|
||||
html, body { margin: 0; padding: 0; background: #fff; font-family: system-ui, -apple-system, sans-serif; color: var(--dark); }
|
||||
body { padding: 24px 28px; }
|
||||
h1 { text-align: center; margin: 0 0 4px; font-size: 1.55rem; }
|
||||
.sub { text-align: center; color: var(--muted); margin-bottom: 18px; font-size: 0.95rem; }
|
||||
|
||||
.stage { display: flex; flex-direction: column; gap: 14px; align-items: stretch; max-width: 1080px; margin: 0 auto; }
|
||||
|
||||
.row { display: grid; grid-template-columns: 200px 1fr; gap: 14px; align-items: center; }
|
||||
.label { font-size: 0.8rem; color: var(--muted); text-transform: uppercase; letter-spacing: 0.08em; font-weight: 700; text-align: right; white-space: nowrap; }
|
||||
.label small { display: block; font-weight: 400; text-transform: none; letter-spacing: 0; color: var(--muted); margin-top: 2px; font-size: 0.8em; white-space: nowrap; }
|
||||
|
||||
.panel { padding: 14px 16px; border: 2px solid var(--border); border-radius: 8px; background: var(--bg-soft); }
|
||||
.panel.bin { background: #0f0f23; color: #fff; border-color: var(--dark); }
|
||||
.panel.bin code { color: #e5e7eb; }
|
||||
.mono { font-family: ui-monospace, "SF Mono", Menlo, monospace; font-size: 1.1rem; font-weight: 700; letter-spacing: 0.02em; word-break: break-all; line-height: 1.5; }
|
||||
|
||||
.hex-bytes { display: flex; flex-wrap: wrap; gap: 8px; }
|
||||
.hex-byte { background: #fff; border: 1px solid var(--border); border-radius: 4px; padding: 4px 10px; font-family: ui-monospace, monospace; font-size: 1.15rem; font-weight: 700; }
|
||||
|
||||
.semantic { display: flex; gap: 6px; flex-wrap: wrap; align-items: stretch; }
|
||||
.group { display: flex; flex-direction: column; gap: 4px; padding: 8px 10px; border-radius: 6px; min-width: 70px; }
|
||||
.group .bytes { display: flex; gap: 4px; }
|
||||
.group .b { background: #fff; border: 1px solid currentColor; border-radius: 3px; padding: 3px 7px; font-family: ui-monospace, monospace; font-size: 1rem; font-weight: 700; color: var(--dark); }
|
||||
.group .tag { font-size: 0.72rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.05em; }
|
||||
.group .meaning { font-size: 0.78rem; line-height: 1.3; color: var(--dark); }
|
||||
.group.magic { background: #fee2e2; color: var(--magic); }
|
||||
.group.format { background: #dbeafe; color: var(--format); }
|
||||
.group.transport { background: #dcfce7; color: var(--transport); }
|
||||
|
||||
.arrow-row { display: flex; justify-content: center; }
|
||||
.arrow {
|
||||
width: 0; height: 0;
|
||||
border-left: 11px solid transparent;
|
||||
border-right: 11px solid transparent;
|
||||
border-top: 14px solid var(--hl);
|
||||
}
|
||||
|
||||
.footnote { margin-top: 16px; font-size: 0.88rem; color: var(--muted); text-align: center; max-width: 800px; margin-left: auto; margin-right: auto; }
|
||||
.footnote strong { color: var(--dark); }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Dieselben 8 Byte — drei Perspektiven</h1>
|
||||
<div class="sub">PNG-Datei-Anfang: <code style="font-family:ui-monospace,monospace">89 50 4E 47 0D 0A 1A 0A</code></div>
|
||||
|
||||
<div class="stage">
|
||||
|
||||
<div class="row">
|
||||
<div class="label">1 · Bitstream<small>was wirklich gespeichert wird</small></div>
|
||||
<div class="panel bin">
|
||||
<code class="mono">10001001 01010000 01001110 01000111 00001101 00001010 00011010 00001010</code>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="arrow-row"><div class="arrow"></div></div>
|
||||
|
||||
<div class="row">
|
||||
<div class="label">2 · Hex<small>gruppiert in 8-Bit-Häppchen</small></div>
|
||||
<div class="panel">
|
||||
<div class="hex-bytes">
|
||||
<span class="hex-byte">89</span>
|
||||
<span class="hex-byte">50</span>
|
||||
<span class="hex-byte">4E</span>
|
||||
<span class="hex-byte">47</span>
|
||||
<span class="hex-byte">0D</span>
|
||||
<span class="hex-byte">0A</span>
|
||||
<span class="hex-byte">1A</span>
|
||||
<span class="hex-byte">0A</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="arrow-row"><div class="arrow"></div></div>
|
||||
|
||||
<div class="row">
|
||||
<div class="label">3 · Bedeutung<small>was die Byte sagen</small></div>
|
||||
<div class="panel">
|
||||
<div class="semantic">
|
||||
<div class="group magic">
|
||||
<div class="bytes"><span class="b">89</span></div>
|
||||
<div class="tag">Magic Byte</div>
|
||||
<div class="meaning">> 127 → "Ich bin Binär, kein Text"</div>
|
||||
</div>
|
||||
<div class="group format">
|
||||
<div class="bytes"><span class="b">50</span><span class="b">4E</span><span class="b">47</span></div>
|
||||
<div class="tag">Format-Kürzel</div>
|
||||
<div class="meaning">P · N · G (ASCII) → "PNG-Datei"</div>
|
||||
</div>
|
||||
<div class="group transport">
|
||||
<div class="bytes"><span class="b">0D</span><span class="b">0A</span><span class="b">1A</span><span class="b">0A</span></div>
|
||||
<div class="tag">Transport-Schutz</div>
|
||||
<div class="meaning">CR · LF · EOF · LF → erkennt kaputte Übertragung</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="footnote">
|
||||
Byte ändern sich nicht — nur unsere <strong>Brille</strong>. Bitstream zeigt das <em>was</em>, Hex das <em>wie kompakt</em>, Bedeutung das <em>warum</em>.
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
After Width: | Height: | Size: 58 KiB |
@@ -0,0 +1,217 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>USB-C — drei Achsen, eine Verwirrung</title>
|
||||
<style>
|
||||
:root {
|
||||
--dark: #1a1a2e;
|
||||
--muted: #6b7280;
|
||||
--soft: #f8fafc;
|
||||
--border: #cbd5e1;
|
||||
--hl: #d63384;
|
||||
--stecker: #2563eb;
|
||||
--kabel: #ea580c;
|
||||
--protokoll: #7c3aed;
|
||||
}
|
||||
html, body { margin: 0; padding: 0; background: #fff; font-family: system-ui, -apple-system, sans-serif; color: var(--dark); }
|
||||
body { padding: 28px 40px; }
|
||||
h1 { text-align: center; margin: 0 0 6px; font-size: 1.75rem; }
|
||||
.sub { text-align: center; color: var(--muted); margin-bottom: 22px; font-size: 1.05rem; }
|
||||
.sub strong { color: var(--dark); }
|
||||
|
||||
.axes {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr 1fr;
|
||||
gap: 18px;
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.axis {
|
||||
border: 2px solid;
|
||||
border-radius: 12px;
|
||||
padding: 14px 16px;
|
||||
background: #fff;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 10px;
|
||||
}
|
||||
.axis.stecker { border-color: var(--stecker); }
|
||||
.axis.kabel { border-color: var(--kabel); }
|
||||
.axis.protokoll { border-color: var(--protokoll); }
|
||||
|
||||
.axis-head { display: flex; justify-content: space-between; align-items: baseline; }
|
||||
.axis-num {
|
||||
font-family: ui-monospace, monospace;
|
||||
font-size: 0.72rem;
|
||||
font-weight: 700;
|
||||
color: var(--muted);
|
||||
}
|
||||
.axis-name { font-size: 1.15rem; font-weight: 700; }
|
||||
.axis.stecker .axis-name { color: var(--stecker); }
|
||||
.axis.kabel .axis-name { color: var(--kabel); }
|
||||
.axis.protokoll .axis-name { color: var(--protokoll); }
|
||||
.axis-tagline {
|
||||
font-size: 0.82rem;
|
||||
color: var(--muted);
|
||||
line-height: 1.4;
|
||||
}
|
||||
.axis-tagline strong { color: var(--dark); }
|
||||
|
||||
.icon {
|
||||
background: var(--soft);
|
||||
border-radius: 6px;
|
||||
height: 60px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
.icon svg { display: block; }
|
||||
|
||||
.options {
|
||||
font-size: 0.82rem;
|
||||
line-height: 1.6;
|
||||
color: var(--dark);
|
||||
background: var(--soft);
|
||||
border-radius: 6px;
|
||||
padding: 10px 14px;
|
||||
}
|
||||
.options strong {
|
||||
font-family: ui-monospace, monospace;
|
||||
font-size: 0.78rem;
|
||||
padding: 1px 5px;
|
||||
border-radius: 3px;
|
||||
background: #fff;
|
||||
border: 1px solid var(--border);
|
||||
}
|
||||
.axis.stecker .options strong { color: var(--stecker); }
|
||||
.axis.kabel .options strong { color: var(--kabel); }
|
||||
.axis.protokoll .options strong { color: var(--protokoll); }
|
||||
|
||||
.scenario {
|
||||
margin-top: 22px;
|
||||
max-width: 1200px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
background: var(--soft);
|
||||
border: 1.5px solid var(--border);
|
||||
border-radius: 10px;
|
||||
padding: 14px 22px;
|
||||
}
|
||||
.scenario-head {
|
||||
font-size: 0.74rem;
|
||||
font-weight: 700;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.1em;
|
||||
color: var(--muted);
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
.scenario-body {
|
||||
font-size: 0.92rem;
|
||||
line-height: 1.5;
|
||||
}
|
||||
.scenario-body code {
|
||||
font-family: ui-monospace, monospace;
|
||||
background: #fff;
|
||||
padding: 1px 6px;
|
||||
border-radius: 4px;
|
||||
border: 1px solid var(--border);
|
||||
}
|
||||
|
||||
.verdict {
|
||||
margin-top: 16px;
|
||||
max-width: 1200px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
text-align: center;
|
||||
border: 2px solid var(--hl);
|
||||
border-radius: 12px;
|
||||
padding: 14px 22px;
|
||||
}
|
||||
.verdict-q { font-size: 1.05rem; font-weight: 700; color: var(--hl); }
|
||||
.verdict-a { font-size: 0.92rem; color: var(--dark); margin-top: 4px; }
|
||||
.verdict-a strong { color: var(--hl); }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>USB-C — drei Achsen, eine Verwirrung</h1>
|
||||
<div class="sub">Derselbe Stecker. <strong>Aber Kabel ≠ Kabel.</strong> <strong>Protokoll ≠ Protokoll.</strong></div>
|
||||
|
||||
<div class="axes">
|
||||
|
||||
<div class="axis stecker">
|
||||
<div class="axis-head">
|
||||
<span class="axis-name">Stecker</span>
|
||||
<span class="axis-num">1 · MECHANIK</span>
|
||||
</div>
|
||||
<div class="axis-tagline">Die <strong>Form</strong>. Was reinsteckt, oval, beidseitig.</div>
|
||||
<div class="icon">
|
||||
<svg viewBox="0 0 120 30" width="140" height="40">
|
||||
<rect x="6" y="9" width="108" height="12" rx="6" fill="#2563eb" opacity="0.18" stroke="#2563eb" stroke-width="2"/>
|
||||
<rect x="22" y="13" width="76" height="4" rx="2" fill="#2563eb"/>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="options">
|
||||
Nur eine Sorte: <strong>USB-C</strong> (auch USB Type-C). 24 Pins. Beidseitig steckbar. Andere Stecker-Typen: USB-A, USB-B, Micro-USB — nicht mit C kompatibel.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="axis kabel">
|
||||
<div class="axis-head">
|
||||
<span class="axis-name">Kabel</span>
|
||||
<span class="axis-num">2 · WAS DURCH-PASST</span>
|
||||
</div>
|
||||
<div class="axis-tagline">Die <strong>Adern</strong>. Was elektrisch transportiert werden kann.</div>
|
||||
<div class="icon">
|
||||
<svg viewBox="0 0 160 30" width="180" height="40">
|
||||
<path d="M10,15 L150,15" stroke="#ea580c" stroke-width="3"/>
|
||||
<rect x="2" y="8" width="14" height="14" rx="3" fill="#ea580c" opacity="0.4" stroke="#ea580c"/>
|
||||
<rect x="144" y="8" width="14" height="14" rx="3" fill="#ea580c" opacity="0.4" stroke="#ea580c"/>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="options">
|
||||
<strong>Charge-only</strong> · billig, nur Strom · 5 W<br>
|
||||
<strong>USB 2.0</strong> · 480 Mbit/s · 60 W (3 A)<br>
|
||||
<strong>USB 3.2 Gen 2</strong> · 10 Gbit/s · 100 W<br>
|
||||
<strong>Thunderbolt 4</strong> · 40 Gbit/s · 240 W
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="axis protokoll">
|
||||
<div class="axis-head">
|
||||
<span class="axis-name">Protokoll</span>
|
||||
<span class="axis-num">3 · WAS LÄUFT</span>
|
||||
</div>
|
||||
<div class="axis-tagline">Die <strong>Sprache</strong>. Was die zwei Geräte miteinander reden.</div>
|
||||
<div class="icon">
|
||||
<svg viewBox="0 0 160 30" width="180" height="40">
|
||||
<circle cx="20" cy="15" r="6" fill="#7c3aed"/>
|
||||
<path d="M30,15 L130,15" stroke="#7c3aed" stroke-width="2" stroke-dasharray="6,4"/>
|
||||
<circle cx="140" cy="15" r="6" fill="#7c3aed"/>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="options">
|
||||
<strong>USB-PD</strong> · Power Delivery (Laden)<br>
|
||||
<strong>USB 2/3/4</strong> · Datenübertragung<br>
|
||||
<strong>Thunderbolt 3/4</strong> · Daten + Display<br>
|
||||
<strong>DisplayPort Alt</strong> · Monitor anschließen<br>
|
||||
<strong>HDMI Alt</strong> · weiter HDMI rausführen
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="scenario">
|
||||
<div class="scenario-head">Konkret: warum lädt der Laptop nicht?</div>
|
||||
<div class="scenario-body">
|
||||
USB-C-Port am Laptop ist da (<strong>Stecker</strong> stimmt). Aber der Aldi-Kabel ist <code>Charge-only</code> mit <code>5 W</code> (<strong>Kabel</strong> kann nicht genug Strom liefern). Oder der Port am Laptop unterstützt nur <code>USB-PD</code> mit 100 W, das Netzteil meldet aber nur 65 W (<strong>Protokoll</strong>-Handshake scheitert). <em>Eine der drei Achsen passt nicht.</em>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="verdict">
|
||||
<div class="verdict-q">Drei Achsen. Drei unabhängige Fragen. Drei Gründe, warum's nicht funktioniert.</div>
|
||||
<div class="verdict-a">Beim nächsten „USB-C-Kabel funktioniert nicht": <strong>Stecker passt → Kabel-Spec checken → Protokoll-Support prüfen.</strong> In dieser Reihenfolge.</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
After Width: | Height: | Size: 118 KiB |
@@ -0,0 +1,135 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Warum 8 Bit? Adressierung im Speicher</title>
|
||||
<style>
|
||||
:root {
|
||||
--hl: #d63384;
|
||||
--dark: #1a1a2e;
|
||||
--muted: #6b7280;
|
||||
--border: #cbd5e1;
|
||||
--bg-soft: #f8fafc;
|
||||
--bad: #ef4444;
|
||||
--good: #16a34a;
|
||||
}
|
||||
html, body { margin: 0; padding: 0; background: #fff; font-family: system-ui, -apple-system, sans-serif; color: var(--dark); }
|
||||
body { padding: 24px 28px; }
|
||||
h1 { text-align: center; margin: 0 0 4px; font-size: 1.55rem; }
|
||||
.sub { text-align: center; color: var(--muted); margin-bottom: 22px; font-size: 0.95rem; }
|
||||
|
||||
.stage { display: flex; flex-direction: column; align-items: center; gap: 18px; max-width: 1100px; margin: 0 auto; }
|
||||
|
||||
.ram-wrap { display: flex; gap: 18px; align-items: stretch; }
|
||||
|
||||
.ram {
|
||||
display: grid;
|
||||
grid-template-columns: 90px 90px 230px;
|
||||
border: 2px solid var(--dark);
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
background: var(--bg-soft);
|
||||
}
|
||||
.ram .head {
|
||||
background: var(--dark); color: #fff; padding: 8px 10px;
|
||||
font-size: 0.78rem; text-transform: uppercase; letter-spacing: 0.08em; font-weight: 700; text-align: center;
|
||||
}
|
||||
.ram .cell {
|
||||
border-top: 1px solid var(--border); padding: 10px 12px;
|
||||
font-family: ui-monospace, "SF Mono", Menlo, monospace; font-size: 1.05rem; font-weight: 700;
|
||||
text-align: center; background: #fff;
|
||||
}
|
||||
.ram .cell.addr { color: var(--muted); background: var(--bg-soft); }
|
||||
.ram .cell.bin { font-size: 0.95rem; letter-spacing: 0.05em; }
|
||||
.ram .row.cur .cell { background: #fef3f8; color: var(--hl); }
|
||||
|
||||
.pointer-side { display: flex; flex-direction: column; gap: 12px; padding-top: 36px; }
|
||||
.ptr-block { display: flex; align-items: center; gap: 8px; padding: 6px 10px; border-radius: 6px; font-family: ui-monospace, monospace; font-weight: 700; font-size: 0.95rem; }
|
||||
.ptr-block.ok { background: #dcfce7; color: var(--good); border: 2px solid var(--good); }
|
||||
.ptr-block.bad { background: #fee2e2; color: var(--bad); border: 2px dashed var(--bad); }
|
||||
.ptr-block.between {
|
||||
background: #fff; color: var(--bad); border: 2px dashed var(--bad);
|
||||
margin: -12px 0 -12px 0;
|
||||
transform: translateX(-10px);
|
||||
}
|
||||
.ptr-block .ico { font-size: 1.3rem; line-height: 1; }
|
||||
|
||||
.legend {
|
||||
display: flex; gap: 22px; padding: 12px 16px; border-top: 1px solid var(--border);
|
||||
font-size: 0.9rem; color: var(--dark);
|
||||
}
|
||||
.legend .row { display: flex; align-items: center; gap: 6px; }
|
||||
.legend .swatch { width: 14px; height: 14px; border-radius: 3px; }
|
||||
|
||||
.conclusion {
|
||||
margin-top: 6px;
|
||||
padding: 14px 22px;
|
||||
background: #fef3f8;
|
||||
border-left: 4px solid var(--hl);
|
||||
border-radius: 4px;
|
||||
font-size: 1rem;
|
||||
text-align: center;
|
||||
max-width: 760px;
|
||||
}
|
||||
.conclusion strong { color: var(--hl); }
|
||||
.conclusion code { background: var(--dark); color: #f8f8f8; padding: 1px 6px; border-radius: 3px; font-family: ui-monospace, monospace; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Warum 8 Bit? Speicher-Adressierung</h1>
|
||||
<div class="sub">CPU adressiert <strong>byteweise</strong> — halbe Byte existieren nicht.</div>
|
||||
|
||||
<div class="stage">
|
||||
|
||||
<div class="ram-wrap">
|
||||
|
||||
<div class="ram">
|
||||
<div class="head">Adresse</div>
|
||||
<div class="head">Hex</div>
|
||||
<div class="head">Bit (was im Speicher steht)</div>
|
||||
|
||||
<div class="cell addr">0x0000</div>
|
||||
<div class="cell">48</div>
|
||||
<div class="cell bin">01001000</div>
|
||||
|
||||
<div class="cell addr">0x0001</div>
|
||||
<div class="cell">65</div>
|
||||
<div class="cell bin">01100101</div>
|
||||
|
||||
<div class="cell addr">0x0002</div>
|
||||
<div class="cell">6C</div>
|
||||
<div class="cell bin">01101100</div>
|
||||
|
||||
<div class="cell addr">0x0003</div>
|
||||
<div class="cell">6C</div>
|
||||
<div class="cell bin">01101100</div>
|
||||
|
||||
<div class="cell addr">0x0004</div>
|
||||
<div class="cell">6F</div>
|
||||
<div class="cell bin">01101111</div>
|
||||
|
||||
<div class="cell addr">0x0005</div>
|
||||
<div class="cell">21</div>
|
||||
<div class="cell bin">00100001</div>
|
||||
</div>
|
||||
|
||||
<div class="pointer-side">
|
||||
<div class="ptr-block ok"><span class="ico">→</span><span>read 0x0000 ✓</span></div>
|
||||
<div class="ptr-block bad"><span class="ico">✗</span><span>read 0x0000.5 — gibt's nicht</span></div>
|
||||
<div class="ptr-block ok"><span class="ico">→</span><span>read 0x0001 ✓</span></div>
|
||||
<div class="ptr-block bad"><span class="ico">✗</span><span>read 0x0001.5 — gibt's nicht</span></div>
|
||||
<div class="ptr-block ok"><span class="ico">→</span><span>read 0x0002 ✓</span></div>
|
||||
<div class="ptr-block ok" style="opacity:0.4"><span class="ico">→</span><span>...</span></div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="conclusion">
|
||||
<strong>Byte = kleinste adressierbare Einheit.</strong><br>
|
||||
Speichercontroller, Bus und CPU sind alle auf 8-Bit-Häppchen ausgelegt.<br>
|
||||
Einzelne Bit lesen → muss erst <code>byte = mem[addr]</code>, dann mit <code>byte & 0b1000_0000</code> Bit isolieren.
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
After Width: | Height: | Size: 76 KiB |
|
After Width: | Height: | Size: 4.0 MiB |
|
After Width: | Height: | Size: 51 KiB |
|
After Width: | Height: | Size: 318 KiB |
|
After Width: | Height: | Size: 2.7 MiB |
|
After Width: | Height: | Size: 1.8 MiB |
@@ -0,0 +1,258 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 2560 1440" preserveAspectRatio="none" shape-rendering="crispEdges">
|
||||
<rect x="0" y="0" width="10" height="1440" fill="rgb(255,255,255)"/>
|
||||
<rect x="10" y="0" width="10" height="1440" fill="rgb(254,254,254)"/>
|
||||
<rect x="20" y="0" width="10" height="1440" fill="rgb(253,253,253)"/>
|
||||
<rect x="30" y="0" width="10" height="1440" fill="rgb(252,252,252)"/>
|
||||
<rect x="40" y="0" width="10" height="1440" fill="rgb(251,251,251)"/>
|
||||
<rect x="50" y="0" width="10" height="1440" fill="rgb(250,250,250)"/>
|
||||
<rect x="60" y="0" width="10" height="1440" fill="rgb(249,249,249)"/>
|
||||
<rect x="70" y="0" width="10" height="1440" fill="rgb(248,248,248)"/>
|
||||
<rect x="80" y="0" width="10" height="1440" fill="rgb(247,247,247)"/>
|
||||
<rect x="90" y="0" width="10" height="1440" fill="rgb(246,246,246)"/>
|
||||
<rect x="100" y="0" width="10" height="1440" fill="rgb(245,245,245)"/>
|
||||
<rect x="110" y="0" width="10" height="1440" fill="rgb(244,244,244)"/>
|
||||
<rect x="120" y="0" width="10" height="1440" fill="rgb(243,243,243)"/>
|
||||
<rect x="130" y="0" width="10" height="1440" fill="rgb(242,242,242)"/>
|
||||
<rect x="140" y="0" width="10" height="1440" fill="rgb(241,241,241)"/>
|
||||
<rect x="150" y="0" width="10" height="1440" fill="rgb(240,240,240)"/>
|
||||
<rect x="160" y="0" width="10" height="1440" fill="rgb(239,239,239)"/>
|
||||
<rect x="170" y="0" width="10" height="1440" fill="rgb(238,238,238)"/>
|
||||
<rect x="180" y="0" width="10" height="1440" fill="rgb(237,237,237)"/>
|
||||
<rect x="190" y="0" width="10" height="1440" fill="rgb(236,236,236)"/>
|
||||
<rect x="200" y="0" width="10" height="1440" fill="rgb(235,235,235)"/>
|
||||
<rect x="210" y="0" width="10" height="1440" fill="rgb(234,234,234)"/>
|
||||
<rect x="220" y="0" width="10" height="1440" fill="rgb(233,233,233)"/>
|
||||
<rect x="230" y="0" width="10" height="1440" fill="rgb(232,232,232)"/>
|
||||
<rect x="240" y="0" width="10" height="1440" fill="rgb(231,231,231)"/>
|
||||
<rect x="250" y="0" width="10" height="1440" fill="rgb(230,230,230)"/>
|
||||
<rect x="260" y="0" width="10" height="1440" fill="rgb(229,229,229)"/>
|
||||
<rect x="270" y="0" width="10" height="1440" fill="rgb(228,228,228)"/>
|
||||
<rect x="280" y="0" width="10" height="1440" fill="rgb(227,227,227)"/>
|
||||
<rect x="290" y="0" width="10" height="1440" fill="rgb(226,226,226)"/>
|
||||
<rect x="300" y="0" width="10" height="1440" fill="rgb(225,225,225)"/>
|
||||
<rect x="310" y="0" width="10" height="1440" fill="rgb(224,224,224)"/>
|
||||
<rect x="320" y="0" width="10" height="1440" fill="rgb(223,223,223)"/>
|
||||
<rect x="330" y="0" width="10" height="1440" fill="rgb(222,222,222)"/>
|
||||
<rect x="340" y="0" width="10" height="1440" fill="rgb(221,221,221)"/>
|
||||
<rect x="350" y="0" width="10" height="1440" fill="rgb(220,220,220)"/>
|
||||
<rect x="360" y="0" width="10" height="1440" fill="rgb(219,219,219)"/>
|
||||
<rect x="370" y="0" width="10" height="1440" fill="rgb(218,218,218)"/>
|
||||
<rect x="380" y="0" width="10" height="1440" fill="rgb(217,217,217)"/>
|
||||
<rect x="390" y="0" width="10" height="1440" fill="rgb(216,216,216)"/>
|
||||
<rect x="400" y="0" width="10" height="1440" fill="rgb(215,215,215)"/>
|
||||
<rect x="410" y="0" width="10" height="1440" fill="rgb(214,214,214)"/>
|
||||
<rect x="420" y="0" width="10" height="1440" fill="rgb(213,213,213)"/>
|
||||
<rect x="430" y="0" width="10" height="1440" fill="rgb(212,212,212)"/>
|
||||
<rect x="440" y="0" width="10" height="1440" fill="rgb(211,211,211)"/>
|
||||
<rect x="450" y="0" width="10" height="1440" fill="rgb(210,210,210)"/>
|
||||
<rect x="460" y="0" width="10" height="1440" fill="rgb(209,209,209)"/>
|
||||
<rect x="470" y="0" width="10" height="1440" fill="rgb(208,208,208)"/>
|
||||
<rect x="480" y="0" width="10" height="1440" fill="rgb(207,207,207)"/>
|
||||
<rect x="490" y="0" width="10" height="1440" fill="rgb(206,206,206)"/>
|
||||
<rect x="500" y="0" width="10" height="1440" fill="rgb(205,205,205)"/>
|
||||
<rect x="510" y="0" width="10" height="1440" fill="rgb(204,204,204)"/>
|
||||
<rect x="520" y="0" width="10" height="1440" fill="rgb(203,203,203)"/>
|
||||
<rect x="530" y="0" width="10" height="1440" fill="rgb(202,202,202)"/>
|
||||
<rect x="540" y="0" width="10" height="1440" fill="rgb(201,201,201)"/>
|
||||
<rect x="550" y="0" width="10" height="1440" fill="rgb(200,200,200)"/>
|
||||
<rect x="560" y="0" width="10" height="1440" fill="rgb(199,199,199)"/>
|
||||
<rect x="570" y="0" width="10" height="1440" fill="rgb(198,198,198)"/>
|
||||
<rect x="580" y="0" width="10" height="1440" fill="rgb(197,197,197)"/>
|
||||
<rect x="590" y="0" width="10" height="1440" fill="rgb(196,196,196)"/>
|
||||
<rect x="600" y="0" width="10" height="1440" fill="rgb(195,195,195)"/>
|
||||
<rect x="610" y="0" width="10" height="1440" fill="rgb(194,194,194)"/>
|
||||
<rect x="620" y="0" width="10" height="1440" fill="rgb(193,193,193)"/>
|
||||
<rect x="630" y="0" width="10" height="1440" fill="rgb(192,192,192)"/>
|
||||
<rect x="640" y="0" width="10" height="1440" fill="rgb(191,191,191)"/>
|
||||
<rect x="650" y="0" width="10" height="1440" fill="rgb(190,190,190)"/>
|
||||
<rect x="660" y="0" width="10" height="1440" fill="rgb(189,189,189)"/>
|
||||
<rect x="670" y="0" width="10" height="1440" fill="rgb(188,188,188)"/>
|
||||
<rect x="680" y="0" width="10" height="1440" fill="rgb(187,187,187)"/>
|
||||
<rect x="690" y="0" width="10" height="1440" fill="rgb(186,186,186)"/>
|
||||
<rect x="700" y="0" width="10" height="1440" fill="rgb(185,185,185)"/>
|
||||
<rect x="710" y="0" width="10" height="1440" fill="rgb(184,184,184)"/>
|
||||
<rect x="720" y="0" width="10" height="1440" fill="rgb(183,183,183)"/>
|
||||
<rect x="730" y="0" width="10" height="1440" fill="rgb(182,182,182)"/>
|
||||
<rect x="740" y="0" width="10" height="1440" fill="rgb(181,181,181)"/>
|
||||
<rect x="750" y="0" width="10" height="1440" fill="rgb(180,180,180)"/>
|
||||
<rect x="760" y="0" width="10" height="1440" fill="rgb(179,179,179)"/>
|
||||
<rect x="770" y="0" width="10" height="1440" fill="rgb(178,178,178)"/>
|
||||
<rect x="780" y="0" width="10" height="1440" fill="rgb(177,177,177)"/>
|
||||
<rect x="790" y="0" width="10" height="1440" fill="rgb(176,176,176)"/>
|
||||
<rect x="800" y="0" width="10" height="1440" fill="rgb(175,175,175)"/>
|
||||
<rect x="810" y="0" width="10" height="1440" fill="rgb(174,174,174)"/>
|
||||
<rect x="820" y="0" width="10" height="1440" fill="rgb(173,173,173)"/>
|
||||
<rect x="830" y="0" width="10" height="1440" fill="rgb(172,172,172)"/>
|
||||
<rect x="840" y="0" width="10" height="1440" fill="rgb(171,171,171)"/>
|
||||
<rect x="850" y="0" width="10" height="1440" fill="rgb(170,170,170)"/>
|
||||
<rect x="860" y="0" width="10" height="1440" fill="rgb(169,169,169)"/>
|
||||
<rect x="870" y="0" width="10" height="1440" fill="rgb(168,168,168)"/>
|
||||
<rect x="880" y="0" width="10" height="1440" fill="rgb(167,167,167)"/>
|
||||
<rect x="890" y="0" width="10" height="1440" fill="rgb(166,166,166)"/>
|
||||
<rect x="900" y="0" width="10" height="1440" fill="rgb(165,165,165)"/>
|
||||
<rect x="910" y="0" width="10" height="1440" fill="rgb(164,164,164)"/>
|
||||
<rect x="920" y="0" width="10" height="1440" fill="rgb(163,163,163)"/>
|
||||
<rect x="930" y="0" width="10" height="1440" fill="rgb(162,162,162)"/>
|
||||
<rect x="940" y="0" width="10" height="1440" fill="rgb(161,161,161)"/>
|
||||
<rect x="950" y="0" width="10" height="1440" fill="rgb(160,160,160)"/>
|
||||
<rect x="960" y="0" width="10" height="1440" fill="rgb(159,159,159)"/>
|
||||
<rect x="970" y="0" width="10" height="1440" fill="rgb(158,158,158)"/>
|
||||
<rect x="980" y="0" width="10" height="1440" fill="rgb(157,157,157)"/>
|
||||
<rect x="990" y="0" width="10" height="1440" fill="rgb(156,156,156)"/>
|
||||
<rect x="1000" y="0" width="10" height="1440" fill="rgb(155,155,155)"/>
|
||||
<rect x="1010" y="0" width="10" height="1440" fill="rgb(154,154,154)"/>
|
||||
<rect x="1020" y="0" width="10" height="1440" fill="rgb(153,153,153)"/>
|
||||
<rect x="1030" y="0" width="10" height="1440" fill="rgb(152,152,152)"/>
|
||||
<rect x="1040" y="0" width="10" height="1440" fill="rgb(151,151,151)"/>
|
||||
<rect x="1050" y="0" width="10" height="1440" fill="rgb(150,150,150)"/>
|
||||
<rect x="1060" y="0" width="10" height="1440" fill="rgb(149,149,149)"/>
|
||||
<rect x="1070" y="0" width="10" height="1440" fill="rgb(148,148,148)"/>
|
||||
<rect x="1080" y="0" width="10" height="1440" fill="rgb(147,147,147)"/>
|
||||
<rect x="1090" y="0" width="10" height="1440" fill="rgb(146,146,146)"/>
|
||||
<rect x="1100" y="0" width="10" height="1440" fill="rgb(145,145,145)"/>
|
||||
<rect x="1110" y="0" width="10" height="1440" fill="rgb(144,144,144)"/>
|
||||
<rect x="1120" y="0" width="10" height="1440" fill="rgb(143,143,143)"/>
|
||||
<rect x="1130" y="0" width="10" height="1440" fill="rgb(142,142,142)"/>
|
||||
<rect x="1140" y="0" width="10" height="1440" fill="rgb(141,141,141)"/>
|
||||
<rect x="1150" y="0" width="10" height="1440" fill="rgb(140,140,140)"/>
|
||||
<rect x="1160" y="0" width="10" height="1440" fill="rgb(139,139,139)"/>
|
||||
<rect x="1170" y="0" width="10" height="1440" fill="rgb(138,138,138)"/>
|
||||
<rect x="1180" y="0" width="10" height="1440" fill="rgb(137,137,137)"/>
|
||||
<rect x="1190" y="0" width="10" height="1440" fill="rgb(136,136,136)"/>
|
||||
<rect x="1200" y="0" width="10" height="1440" fill="rgb(135,135,135)"/>
|
||||
<rect x="1210" y="0" width="10" height="1440" fill="rgb(134,134,134)"/>
|
||||
<rect x="1220" y="0" width="10" height="1440" fill="rgb(133,133,133)"/>
|
||||
<rect x="1230" y="0" width="10" height="1440" fill="rgb(132,132,132)"/>
|
||||
<rect x="1240" y="0" width="10" height="1440" fill="rgb(131,131,131)"/>
|
||||
<rect x="1250" y="0" width="10" height="1440" fill="rgb(130,130,130)"/>
|
||||
<rect x="1260" y="0" width="10" height="1440" fill="rgb(129,129,129)"/>
|
||||
<rect x="1270" y="0" width="10" height="1440" fill="rgb(128,128,128)"/>
|
||||
<rect x="1280" y="0" width="10" height="1440" fill="rgb(127,127,127)"/>
|
||||
<rect x="1290" y="0" width="10" height="1440" fill="rgb(126,126,126)"/>
|
||||
<rect x="1300" y="0" width="10" height="1440" fill="rgb(125,125,125)"/>
|
||||
<rect x="1310" y="0" width="10" height="1440" fill="rgb(124,124,124)"/>
|
||||
<rect x="1320" y="0" width="10" height="1440" fill="rgb(123,123,123)"/>
|
||||
<rect x="1330" y="0" width="10" height="1440" fill="rgb(122,122,122)"/>
|
||||
<rect x="1340" y="0" width="10" height="1440" fill="rgb(121,121,121)"/>
|
||||
<rect x="1350" y="0" width="10" height="1440" fill="rgb(120,120,120)"/>
|
||||
<rect x="1360" y="0" width="10" height="1440" fill="rgb(119,119,119)"/>
|
||||
<rect x="1370" y="0" width="10" height="1440" fill="rgb(118,118,118)"/>
|
||||
<rect x="1380" y="0" width="10" height="1440" fill="rgb(117,117,117)"/>
|
||||
<rect x="1390" y="0" width="10" height="1440" fill="rgb(116,116,116)"/>
|
||||
<rect x="1400" y="0" width="10" height="1440" fill="rgb(115,115,115)"/>
|
||||
<rect x="1410" y="0" width="10" height="1440" fill="rgb(114,114,114)"/>
|
||||
<rect x="1420" y="0" width="10" height="1440" fill="rgb(113,113,113)"/>
|
||||
<rect x="1430" y="0" width="10" height="1440" fill="rgb(112,112,112)"/>
|
||||
<rect x="1440" y="0" width="10" height="1440" fill="rgb(111,111,111)"/>
|
||||
<rect x="1450" y="0" width="10" height="1440" fill="rgb(110,110,110)"/>
|
||||
<rect x="1460" y="0" width="10" height="1440" fill="rgb(109,109,109)"/>
|
||||
<rect x="1470" y="0" width="10" height="1440" fill="rgb(108,108,108)"/>
|
||||
<rect x="1480" y="0" width="10" height="1440" fill="rgb(107,107,107)"/>
|
||||
<rect x="1490" y="0" width="10" height="1440" fill="rgb(106,106,106)"/>
|
||||
<rect x="1500" y="0" width="10" height="1440" fill="rgb(105,105,105)"/>
|
||||
<rect x="1510" y="0" width="10" height="1440" fill="rgb(104,104,104)"/>
|
||||
<rect x="1520" y="0" width="10" height="1440" fill="rgb(103,103,103)"/>
|
||||
<rect x="1530" y="0" width="10" height="1440" fill="rgb(102,102,102)"/>
|
||||
<rect x="1540" y="0" width="10" height="1440" fill="rgb(101,101,101)"/>
|
||||
<rect x="1550" y="0" width="10" height="1440" fill="rgb(100,100,100)"/>
|
||||
<rect x="1560" y="0" width="10" height="1440" fill="rgb(99,99,99)"/>
|
||||
<rect x="1570" y="0" width="10" height="1440" fill="rgb(98,98,98)"/>
|
||||
<rect x="1580" y="0" width="10" height="1440" fill="rgb(97,97,97)"/>
|
||||
<rect x="1590" y="0" width="10" height="1440" fill="rgb(96,96,96)"/>
|
||||
<rect x="1600" y="0" width="10" height="1440" fill="rgb(95,95,95)"/>
|
||||
<rect x="1610" y="0" width="10" height="1440" fill="rgb(94,94,94)"/>
|
||||
<rect x="1620" y="0" width="10" height="1440" fill="rgb(93,93,93)"/>
|
||||
<rect x="1630" y="0" width="10" height="1440" fill="rgb(92,92,92)"/>
|
||||
<rect x="1640" y="0" width="10" height="1440" fill="rgb(91,91,91)"/>
|
||||
<rect x="1650" y="0" width="10" height="1440" fill="rgb(90,90,90)"/>
|
||||
<rect x="1660" y="0" width="10" height="1440" fill="rgb(89,89,89)"/>
|
||||
<rect x="1670" y="0" width="10" height="1440" fill="rgb(88,88,88)"/>
|
||||
<rect x="1680" y="0" width="10" height="1440" fill="rgb(87,87,87)"/>
|
||||
<rect x="1690" y="0" width="10" height="1440" fill="rgb(86,86,86)"/>
|
||||
<rect x="1700" y="0" width="10" height="1440" fill="rgb(85,85,85)"/>
|
||||
<rect x="1710" y="0" width="10" height="1440" fill="rgb(84,84,84)"/>
|
||||
<rect x="1720" y="0" width="10" height="1440" fill="rgb(83,83,83)"/>
|
||||
<rect x="1730" y="0" width="10" height="1440" fill="rgb(82,82,82)"/>
|
||||
<rect x="1740" y="0" width="10" height="1440" fill="rgb(81,81,81)"/>
|
||||
<rect x="1750" y="0" width="10" height="1440" fill="rgb(80,80,80)"/>
|
||||
<rect x="1760" y="0" width="10" height="1440" fill="rgb(79,79,79)"/>
|
||||
<rect x="1770" y="0" width="10" height="1440" fill="rgb(78,78,78)"/>
|
||||
<rect x="1780" y="0" width="10" height="1440" fill="rgb(77,77,77)"/>
|
||||
<rect x="1790" y="0" width="10" height="1440" fill="rgb(76,76,76)"/>
|
||||
<rect x="1800" y="0" width="10" height="1440" fill="rgb(75,75,75)"/>
|
||||
<rect x="1810" y="0" width="10" height="1440" fill="rgb(74,74,74)"/>
|
||||
<rect x="1820" y="0" width="10" height="1440" fill="rgb(73,73,73)"/>
|
||||
<rect x="1830" y="0" width="10" height="1440" fill="rgb(72,72,72)"/>
|
||||
<rect x="1840" y="0" width="10" height="1440" fill="rgb(71,71,71)"/>
|
||||
<rect x="1850" y="0" width="10" height="1440" fill="rgb(70,70,70)"/>
|
||||
<rect x="1860" y="0" width="10" height="1440" fill="rgb(69,69,69)"/>
|
||||
<rect x="1870" y="0" width="10" height="1440" fill="rgb(68,68,68)"/>
|
||||
<rect x="1880" y="0" width="10" height="1440" fill="rgb(67,67,67)"/>
|
||||
<rect x="1890" y="0" width="10" height="1440" fill="rgb(66,66,66)"/>
|
||||
<rect x="1900" y="0" width="10" height="1440" fill="rgb(65,65,65)"/>
|
||||
<rect x="1910" y="0" width="10" height="1440" fill="rgb(64,64,64)"/>
|
||||
<rect x="1920" y="0" width="10" height="1440" fill="rgb(63,63,63)"/>
|
||||
<rect x="1930" y="0" width="10" height="1440" fill="rgb(62,62,62)"/>
|
||||
<rect x="1940" y="0" width="10" height="1440" fill="rgb(61,61,61)"/>
|
||||
<rect x="1950" y="0" width="10" height="1440" fill="rgb(60,60,60)"/>
|
||||
<rect x="1960" y="0" width="10" height="1440" fill="rgb(59,59,59)"/>
|
||||
<rect x="1970" y="0" width="10" height="1440" fill="rgb(58,58,58)"/>
|
||||
<rect x="1980" y="0" width="10" height="1440" fill="rgb(57,57,57)"/>
|
||||
<rect x="1990" y="0" width="10" height="1440" fill="rgb(56,56,56)"/>
|
||||
<rect x="2000" y="0" width="10" height="1440" fill="rgb(55,55,55)"/>
|
||||
<rect x="2010" y="0" width="10" height="1440" fill="rgb(54,54,54)"/>
|
||||
<rect x="2020" y="0" width="10" height="1440" fill="rgb(53,53,53)"/>
|
||||
<rect x="2030" y="0" width="10" height="1440" fill="rgb(52,52,52)"/>
|
||||
<rect x="2040" y="0" width="10" height="1440" fill="rgb(51,51,51)"/>
|
||||
<rect x="2050" y="0" width="10" height="1440" fill="rgb(50,50,50)"/>
|
||||
<rect x="2060" y="0" width="10" height="1440" fill="rgb(49,49,49)"/>
|
||||
<rect x="2070" y="0" width="10" height="1440" fill="rgb(48,48,48)"/>
|
||||
<rect x="2080" y="0" width="10" height="1440" fill="rgb(47,47,47)"/>
|
||||
<rect x="2090" y="0" width="10" height="1440" fill="rgb(46,46,46)"/>
|
||||
<rect x="2100" y="0" width="10" height="1440" fill="rgb(45,45,45)"/>
|
||||
<rect x="2110" y="0" width="10" height="1440" fill="rgb(44,44,44)"/>
|
||||
<rect x="2120" y="0" width="10" height="1440" fill="rgb(43,43,43)"/>
|
||||
<rect x="2130" y="0" width="10" height="1440" fill="rgb(42,42,42)"/>
|
||||
<rect x="2140" y="0" width="10" height="1440" fill="rgb(41,41,41)"/>
|
||||
<rect x="2150" y="0" width="10" height="1440" fill="rgb(40,40,40)"/>
|
||||
<rect x="2160" y="0" width="10" height="1440" fill="rgb(39,39,39)"/>
|
||||
<rect x="2170" y="0" width="10" height="1440" fill="rgb(38,38,38)"/>
|
||||
<rect x="2180" y="0" width="10" height="1440" fill="rgb(37,37,37)"/>
|
||||
<rect x="2190" y="0" width="10" height="1440" fill="rgb(36,36,36)"/>
|
||||
<rect x="2200" y="0" width="10" height="1440" fill="rgb(35,35,35)"/>
|
||||
<rect x="2210" y="0" width="10" height="1440" fill="rgb(34,34,34)"/>
|
||||
<rect x="2220" y="0" width="10" height="1440" fill="rgb(33,33,33)"/>
|
||||
<rect x="2230" y="0" width="10" height="1440" fill="rgb(32,32,32)"/>
|
||||
<rect x="2240" y="0" width="10" height="1440" fill="rgb(31,31,31)"/>
|
||||
<rect x="2250" y="0" width="10" height="1440" fill="rgb(30,30,30)"/>
|
||||
<rect x="2260" y="0" width="10" height="1440" fill="rgb(29,29,29)"/>
|
||||
<rect x="2270" y="0" width="10" height="1440" fill="rgb(28,28,28)"/>
|
||||
<rect x="2280" y="0" width="10" height="1440" fill="rgb(27,27,27)"/>
|
||||
<rect x="2290" y="0" width="10" height="1440" fill="rgb(26,26,26)"/>
|
||||
<rect x="2300" y="0" width="10" height="1440" fill="rgb(25,25,25)"/>
|
||||
<rect x="2310" y="0" width="10" height="1440" fill="rgb(24,24,24)"/>
|
||||
<rect x="2320" y="0" width="10" height="1440" fill="rgb(23,23,23)"/>
|
||||
<rect x="2330" y="0" width="10" height="1440" fill="rgb(22,22,22)"/>
|
||||
<rect x="2340" y="0" width="10" height="1440" fill="rgb(21,21,21)"/>
|
||||
<rect x="2350" y="0" width="10" height="1440" fill="rgb(20,20,20)"/>
|
||||
<rect x="2360" y="0" width="10" height="1440" fill="rgb(19,19,19)"/>
|
||||
<rect x="2370" y="0" width="10" height="1440" fill="rgb(18,18,18)"/>
|
||||
<rect x="2380" y="0" width="10" height="1440" fill="rgb(17,17,17)"/>
|
||||
<rect x="2390" y="0" width="10" height="1440" fill="rgb(16,16,16)"/>
|
||||
<rect x="2400" y="0" width="10" height="1440" fill="rgb(15,15,15)"/>
|
||||
<rect x="2410" y="0" width="10" height="1440" fill="rgb(14,14,14)"/>
|
||||
<rect x="2420" y="0" width="10" height="1440" fill="rgb(13,13,13)"/>
|
||||
<rect x="2430" y="0" width="10" height="1440" fill="rgb(12,12,12)"/>
|
||||
<rect x="2440" y="0" width="10" height="1440" fill="rgb(11,11,11)"/>
|
||||
<rect x="2450" y="0" width="10" height="1440" fill="rgb(10,10,10)"/>
|
||||
<rect x="2460" y="0" width="10" height="1440" fill="rgb(9,9,9)"/>
|
||||
<rect x="2470" y="0" width="10" height="1440" fill="rgb(8,8,8)"/>
|
||||
<rect x="2480" y="0" width="10" height="1440" fill="rgb(7,7,7)"/>
|
||||
<rect x="2490" y="0" width="10" height="1440" fill="rgb(6,6,6)"/>
|
||||
<rect x="2500" y="0" width="10" height="1440" fill="rgb(5,5,5)"/>
|
||||
<rect x="2510" y="0" width="10" height="1440" fill="rgb(4,4,4)"/>
|
||||
<rect x="2520" y="0" width="10" height="1440" fill="rgb(3,3,3)"/>
|
||||
<rect x="2530" y="0" width="10" height="1440" fill="rgb(2,2,2)"/>
|
||||
<rect x="2540" y="0" width="10" height="1440" fill="rgb(1,1,1)"/>
|
||||
<rect x="2550" y="0" width="10" height="1440" fill="rgb(0,0,0)"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 18 KiB |
@@ -0,0 +1,53 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1920 1080">
|
||||
<rect width="1920" height="1080" fill="#ffffff"/>
|
||||
<text x="960.0" y="100" text-anchor="middle" font-family="sans-serif" font-size="54" fill="#1a1a2e" font-weight="bold">Zoom: die 16 hellsten Abstufungen</text>
|
||||
<rect x="60.00" y="220" width="101.25" height="500" fill="rgb(255,255,255)" stroke="#1a1a2e" stroke-width="3"/>
|
||||
<text x="110.62" y="820" text-anchor="middle" font-family="monospace" font-size="42" fill="#1a1a2e" font-weight="bold">255</text>
|
||||
<text x="110.62" y="900" text-anchor="middle" font-family="monospace" font-size="36" fill="#4a4a6a">0xFF</text>
|
||||
<rect x="173.25" y="220" width="101.25" height="500" fill="rgb(254,254,254)" stroke="#1a1a2e" stroke-width="3"/>
|
||||
<text x="223.88" y="820" text-anchor="middle" font-family="monospace" font-size="42" fill="#1a1a2e" font-weight="bold">254</text>
|
||||
<text x="223.88" y="900" text-anchor="middle" font-family="monospace" font-size="36" fill="#4a4a6a">0xFE</text>
|
||||
<rect x="286.50" y="220" width="101.25" height="500" fill="rgb(253,253,253)" stroke="#1a1a2e" stroke-width="3"/>
|
||||
<text x="337.12" y="820" text-anchor="middle" font-family="monospace" font-size="42" fill="#1a1a2e" font-weight="bold">253</text>
|
||||
<text x="337.12" y="900" text-anchor="middle" font-family="monospace" font-size="36" fill="#4a4a6a">0xFD</text>
|
||||
<rect x="399.75" y="220" width="101.25" height="500" fill="rgb(252,252,252)" stroke="#1a1a2e" stroke-width="3"/>
|
||||
<text x="450.38" y="820" text-anchor="middle" font-family="monospace" font-size="42" fill="#1a1a2e" font-weight="bold">252</text>
|
||||
<text x="450.38" y="900" text-anchor="middle" font-family="monospace" font-size="36" fill="#4a4a6a">0xFC</text>
|
||||
<rect x="513.00" y="220" width="101.25" height="500" fill="rgb(251,251,251)" stroke="#1a1a2e" stroke-width="3"/>
|
||||
<text x="563.62" y="820" text-anchor="middle" font-family="monospace" font-size="42" fill="#1a1a2e" font-weight="bold">251</text>
|
||||
<text x="563.62" y="900" text-anchor="middle" font-family="monospace" font-size="36" fill="#4a4a6a">0xFB</text>
|
||||
<rect x="626.25" y="220" width="101.25" height="500" fill="rgb(250,250,250)" stroke="#1a1a2e" stroke-width="3"/>
|
||||
<text x="676.88" y="820" text-anchor="middle" font-family="monospace" font-size="42" fill="#1a1a2e" font-weight="bold">250</text>
|
||||
<text x="676.88" y="900" text-anchor="middle" font-family="monospace" font-size="36" fill="#4a4a6a">0xFA</text>
|
||||
<rect x="739.50" y="220" width="101.25" height="500" fill="rgb(249,249,249)" stroke="#1a1a2e" stroke-width="3"/>
|
||||
<text x="790.12" y="820" text-anchor="middle" font-family="monospace" font-size="42" fill="#1a1a2e" font-weight="bold">249</text>
|
||||
<text x="790.12" y="900" text-anchor="middle" font-family="monospace" font-size="36" fill="#4a4a6a">0xF9</text>
|
||||
<rect x="852.75" y="220" width="101.25" height="500" fill="rgb(248,248,248)" stroke="#1a1a2e" stroke-width="3"/>
|
||||
<text x="903.38" y="820" text-anchor="middle" font-family="monospace" font-size="42" fill="#1a1a2e" font-weight="bold">248</text>
|
||||
<text x="903.38" y="900" text-anchor="middle" font-family="monospace" font-size="36" fill="#4a4a6a">0xF8</text>
|
||||
<rect x="966.00" y="220" width="101.25" height="500" fill="rgb(247,247,247)" stroke="#1a1a2e" stroke-width="3"/>
|
||||
<text x="1016.62" y="820" text-anchor="middle" font-family="monospace" font-size="42" fill="#1a1a2e" font-weight="bold">247</text>
|
||||
<text x="1016.62" y="900" text-anchor="middle" font-family="monospace" font-size="36" fill="#4a4a6a">0xF7</text>
|
||||
<rect x="1079.25" y="220" width="101.25" height="500" fill="rgb(246,246,246)" stroke="#1a1a2e" stroke-width="3"/>
|
||||
<text x="1129.88" y="820" text-anchor="middle" font-family="monospace" font-size="42" fill="#1a1a2e" font-weight="bold">246</text>
|
||||
<text x="1129.88" y="900" text-anchor="middle" font-family="monospace" font-size="36" fill="#4a4a6a">0xF6</text>
|
||||
<rect x="1192.50" y="220" width="101.25" height="500" fill="rgb(245,245,245)" stroke="#1a1a2e" stroke-width="3"/>
|
||||
<text x="1243.12" y="820" text-anchor="middle" font-family="monospace" font-size="42" fill="#1a1a2e" font-weight="bold">245</text>
|
||||
<text x="1243.12" y="900" text-anchor="middle" font-family="monospace" font-size="36" fill="#4a4a6a">0xF5</text>
|
||||
<rect x="1305.75" y="220" width="101.25" height="500" fill="rgb(244,244,244)" stroke="#1a1a2e" stroke-width="3"/>
|
||||
<text x="1356.38" y="820" text-anchor="middle" font-family="monospace" font-size="42" fill="#1a1a2e" font-weight="bold">244</text>
|
||||
<text x="1356.38" y="900" text-anchor="middle" font-family="monospace" font-size="36" fill="#4a4a6a">0xF4</text>
|
||||
<rect x="1419.00" y="220" width="101.25" height="500" fill="rgb(243,243,243)" stroke="#1a1a2e" stroke-width="3"/>
|
||||
<text x="1469.62" y="820" text-anchor="middle" font-family="monospace" font-size="42" fill="#1a1a2e" font-weight="bold">243</text>
|
||||
<text x="1469.62" y="900" text-anchor="middle" font-family="monospace" font-size="36" fill="#4a4a6a">0xF3</text>
|
||||
<rect x="1532.25" y="220" width="101.25" height="500" fill="rgb(242,242,242)" stroke="#1a1a2e" stroke-width="3"/>
|
||||
<text x="1582.88" y="820" text-anchor="middle" font-family="monospace" font-size="42" fill="#1a1a2e" font-weight="bold">242</text>
|
||||
<text x="1582.88" y="900" text-anchor="middle" font-family="monospace" font-size="36" fill="#4a4a6a">0xF2</text>
|
||||
<rect x="1645.50" y="220" width="101.25" height="500" fill="rgb(241,241,241)" stroke="#1a1a2e" stroke-width="3"/>
|
||||
<text x="1696.12" y="820" text-anchor="middle" font-family="monospace" font-size="42" fill="#1a1a2e" font-weight="bold">241</text>
|
||||
<text x="1696.12" y="900" text-anchor="middle" font-family="monospace" font-size="36" fill="#4a4a6a">0xF1</text>
|
||||
<rect x="1758.75" y="220" width="101.25" height="500" fill="rgb(240,240,240)" stroke="#1a1a2e" stroke-width="3"/>
|
||||
<text x="1809.38" y="820" text-anchor="middle" font-family="monospace" font-size="42" fill="#1a1a2e" font-weight="bold">240</text>
|
||||
<text x="1809.38" y="900" text-anchor="middle" font-family="monospace" font-size="36" fill="#4a4a6a">0xF0</text>
|
||||
<text x="960.0" y="1020" text-anchor="middle" font-family="sans-serif" font-size="28" fill="#4a4a6a" font-style="italic">jede Stufe = Unterschied von 1/255 ≈ 0,4% Helligkeit</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 6.0 KiB |
|
After Width: | Height: | Size: 161 KiB |
|
After Width: | Height: | Size: 2.3 MiB |
|
After Width: | Height: | Size: 175 KiB |
|
After Width: | Height: | Size: 204 KiB |
|
After Width: | Height: | Size: 84 KiB |
|
After Width: | Height: | Size: 2.7 MiB |
|
After Width: | Height: | Size: 112 KiB |
|
After Width: | Height: | Size: 2.1 MiB |
|
After Width: | Height: | Size: 2.6 MiB |
|
After Width: | Height: | Size: 55 KiB |
|
After Width: | Height: | Size: 2.5 MiB |
|
After Width: | Height: | Size: 525 KiB |
|
After Width: | Height: | Size: 171 KiB |
@@ -0,0 +1,9 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="80" height="80">
|
||||
<defs>
|
||||
<pattern id="diagonalStripes" patternUnits="userSpaceOnUse" width="80" height="80" patternTransform="rotate(135)">
|
||||
<rect width="40" height="80" fill="#e3f2fd"/>
|
||||
<rect x="40" width="40" height="80" fill="#ffffff"/>
|
||||
</pattern>
|
||||
</defs>
|
||||
<rect width="100%" height="100%" fill="url(#diagonalStripes)"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 401 B |
|
After Width: | Height: | Size: 198 KiB |
|
After Width: | Height: | Size: 2.0 MiB |
|
After Width: | Height: | Size: 251 KiB |
|
After Width: | Height: | Size: 2.7 MiB |