- Änderungsprotokoll
+ Changelog
- Verfolgung aller neuen Funktionen, Verbesserungen und Fehlerbehebungen.
+ Tracking all new features, improvements, and bug fixes.
@@ -38,12 +32,12 @@ export function Changelog() {
- {typeTranslations[change.type] || change.type}
+ {change.type}
{change.text}
diff --git a/src/components/image-list-item.tsx b/src/components/image-list-item.tsx
index 28c2844..3196fc8 100644
--- a/src/components/image-list-item.tsx
+++ b/src/components/image-list-item.tsx
@@ -34,7 +34,7 @@ export function ImageListItem({
-
Basisname
+
Basename
- Finaler Name: {finalFilename}.{settings.format}
+ Final name: {finalFilename}.{settings.format}
@@ -58,7 +58,7 @@ export function ImageListItem({
-
Dieses Bild herunterladen
+
Download this image
@@ -72,7 +72,7 @@ export function ImageListItem({
- Dieses Bild entfernen
+ Remove this image
diff --git a/src/components/image-list.tsx b/src/components/image-list.tsx
index ab0a01f..4775dc6 100644
--- a/src/components/image-list.tsx
+++ b/src/components/image-list.tsx
@@ -41,24 +41,24 @@ export function ImageList({
-
Hochgeladene Bilder
+
Uploaded Images
- Alle löschen
+ Clear All
- Alle hochgeladenen Bilder entfernen.
+ Remove all uploaded images.
- {isConverting ? "Konvertiere..." : `Alle herunterladen (${images.length})`}
+ {isConverting ? "Converting..." : `Download All (${images.length})`}
- Alle Bilder mit den aktuellen Einstellungen konvertieren und herunterladen.
+ Convert and download all images with the current settings.
diff --git a/src/components/image-upload-area.tsx b/src/components/image-upload-area.tsx
index c87ec59..907fd49 100644
--- a/src/components/image-upload-area.tsx
+++ b/src/components/image-upload-area.tsx
@@ -39,7 +39,7 @@ export function ImageUploadArea({ onFilesSelected }: ImageUploadAreaProps) {
-
Bilder hochladen
+
Upload Images
-
Klicken oder per Drag & Drop hochladen
-
PNG, JPG, WEBP werden unterstützt
+
Click or drag & drop to upload
+
PNG, JPG, WEBP are supported
diff --git a/src/components/settings-panel.tsx b/src/components/settings-panel.tsx
index 62591e4..d1c2241 100644
--- a/src/components/settings-panel.tsx
+++ b/src/components/settings-panel.tsx
@@ -31,8 +31,8 @@ export function SettingsPanel({
-
Bildeinstellungen
-
Auflösung und Skalierung für alle Bilder anpassen.
+
Image Settings
+
Adjust resolution and scaling for all images.
@@ -48,8 +48,8 @@ export function SettingsPanel({
-
Dateinameneinstellungen
-
Die Ausgabe-Dateinamen anpassen.
+
Filename Settings
+
Customize the output filenames.
@@ -65,8 +65,8 @@ export function SettingsPanel({
-
Qualitätseinstellungen
-
Format und Komprimierungsstufe auswählen.
+
Quality Settings
+
Select format and compression level.
diff --git a/src/components/settings/filename-settings.tsx b/src/components/settings/filename-settings.tsx
index 418fe81..269ff5c 100644
--- a/src/components/settings/filename-settings.tsx
+++ b/src/components/settings/filename-settings.tsx
@@ -26,61 +26,61 @@ export function FilenameSettings({
onSettingsChange({ useDefaultBaseName: checked })} />
- Standard-Basisnamen verwenden
+ Use default basename
e.preventDefault()}>
- Wenn aktiviert, verwenden alle neu hochgeladenen Bilder den angegebenen Standard-Basisnamen.
+ When enabled, all newly uploaded images will use the specified default basename.
{settings.useDefaultBaseName && (
-
Standard-Basisname
+
Default Basename
onSettingsChange({ defaultBaseName: e.target.value })}
/>
- Auf alle anwenden
+ Apply to all
- Diesen Basisnamen auf alle aktuell hochgeladenen Bilder anwenden.
+ Apply this basename to all currently uploaded images.
)}
-
Präfix
+
Prefix
- Text am Anfang jedes Dateinamens hinzufügen.
+ Add text to the beginning of each filename.
-
onSettingsChange({ prefix: e.target.value })} />
+
onSettingsChange({ prefix: e.target.value })} />
onSettingsChange({ useCounter: checked })} />
- Fortlaufende Nummer hinzufügen
+ Add sequential number
e.preventDefault()}>
- Eine nummerierte Sequenz an jeden Dateinamen anhängen.
+ Append a numbered sequence to each filename.
@@ -88,10 +88,10 @@ export function FilenameSettings({
-
Startnummer
+
Start number
- Die erste Nummer, die in der Sequenz verwendet wird.
+ The first number to be used in the sequence.
-
Auffüllende Ziffern
+
Padding digits
- Gesamtzahl der Ziffern für den Zähler, mit führenden Nullen aufgefüllt (z.B. 3 für 001).
+ Total number of digits for the counter, padded with leading zeros (e.g., 3 for 001).
-
Seitenverhältnis
+
Aspect Ratio
- Wählen Sie ein voreingestelltes Seitenverhältnis oder 'Benutzerdefiniert', um die Abmessungen manuell einzugeben.
+ Select a preset aspect ratio or 'Custom' to enter dimensions manually.
-
+
{aspectRatios.map((ratio) => (
{ratio.name}
@@ -53,28 +53,28 @@ export function ImageSettings({
-
Breite (px)
+
Width (px)
- Legen Sie die Ausgabebreite in Pixeln fest. Leer lassen, um die Originalbreite zu verwenden.
+ Set the output width in pixels. Leave empty to use the original width.
{ onSettingsChange({ width: e.target.value, aspectRatio: 'custom' }) }} />
-
+
- Die eingegebenen Werte für Breite und Höhe tauschen.
+ Swap the entered values for width and height.
-
Höhe (px)
+
Height (px)
- Legen Sie die Ausgabehöhe in Pixeln fest. Leer lassen, um die Originalhöhe zu verwenden.
+ Set the output height in pixels. Leave empty to use the original height.
{ onSettingsChange({ height: e.target.value, aspectRatio: 'custom' }) }} />
@@ -83,27 +83,27 @@ export function ImageSettings({
onSettingsChange({ keepOrientation: Boolean(checked) })} />
- Originalausrichtung beibehalten
+ Keep original orientation
e.preventDefault()}>
- Tauscht automatisch Breite und Höhe, um der Ausrichtung des Originalbildes zu entsprechen.
+ Automatically swaps width and height to match the original image's orientation.
-
Skalierung
+
Scaling
- Bestimmt, wie das Bild in die neuen Abmessungen passt.
+ Determines how the image fits into the new dimensions.
onSettingsChange({ scaleMode: value as any })}>
-
+
- Füllen (strecken)
- Abdecken (zuschneiden)
- Enthalten (Letterbox)
+ Fill (stretch)
+ Cover (crop)
+ Contain (letterbox)
@@ -113,7 +113,7 @@ export function ImageSettings({
Position
- Legt den Ankerpunkt für die Skalierung 'Abdecken' oder 'Enthalten' fest.
+ Sets the anchor point for 'Cover' or 'Contain' scaling.
onSettingsChange({ objectPosition: pos as ObjectPosition })} />
diff --git a/src/components/settings/preset-settings.tsx b/src/components/settings/preset-settings.tsx
index 56ac45d..40bb6ef 100644
--- a/src/components/settings/preset-settings.tsx
+++ b/src/components/settings/preset-settings.tsx
@@ -39,7 +39,7 @@ export function PresetSettings({ onSettingsChange }: PresetSettingsProps) {
const selectedPreset = presets.find(p => p.name === presetName);
if (selectedPreset) {
onSettingsChange(selectedPreset.settings);
- toast.success(`Preset "${selectedPreset.name}" angewendet.`);
+ toast.success(`Preset "${selectedPreset.name}" applied.`);
}
};
@@ -49,7 +49,7 @@ export function PresetSettings({ onSettingsChange }: PresetSettingsProps) {
Presets
-
Schnell gängige Einstellungen anwenden.
+
Quickly apply common settings.
@@ -57,10 +57,10 @@ export function PresetSettings({ onSettingsChange }: PresetSettingsProps) {
{presetsEnabled && (
-
Preset auswählen
+
Select Preset
-
+
{presets.map((preset) => (
diff --git a/src/components/settings/quality-settings.tsx b/src/components/settings/quality-settings.tsx
index 2a3a0e4..6889060 100644
--- a/src/components/settings/quality-settings.tsx
+++ b/src/components/settings/quality-settings.tsx
@@ -20,11 +20,11 @@ export function QualitySettings({ settings, onSettingsChange }: QualitySettingsP
Format
- Wählen Sie das Ausgabedateiformat für die Bilder.
+ Select the output file format for the images.
onSettingsChange({ format: value })}>
-
+
PNG
JPEG
@@ -35,10 +35,10 @@ export function QualitySettings({ settings, onSettingsChange }: QualitySettingsP
-
Qualität
+
Quality
- Stellen Sie die Komprimierungsqualität für JPEG/WEBP ein. Höher bedeutet bessere Qualität, aber größere Dateigröße.
+ Set the compression quality for JPEG/WEBP. Higher means better quality but larger file size.
{settings.quality}%
@@ -53,7 +53,7 @@ export function QualitySettings({ settings, onSettingsChange }: QualitySettingsP
disabled={settings.format === 'png'}
/>
{settings.format === 'png' && (
-
Der Qualitätsregler ist für PNG (verlustfreies Format) deaktiviert.
+
The quality slider is disabled for PNG (lossless format).
)}
diff --git a/src/components/theme-toggle.tsx b/src/components/theme-toggle.tsx
index fb88418..fee7017 100644
--- a/src/components/theme-toggle.tsx
+++ b/src/components/theme-toggle.tsx
@@ -29,10 +29,10 @@ export function ThemeToggle() {
System
setTheme("light")}>
- Hell
+ Light
setTheme("dark")}>
- Dunkel
+ Dark
diff --git a/src/hooks/use-image-converter.ts b/src/hooks/use-image-converter.ts
index f4b1465..41ce503 100644
--- a/src/hooks/use-image-converter.ts
+++ b/src/hooks/use-image-converter.ts
@@ -43,7 +43,7 @@ export function useImageConverter() {
const imageFiles = Array.from(files).filter(file => file.type.startsWith("image/"));
if (imageFiles.length === 0) {
- toast.error("Keine gültigen Bilddateien gefunden.");
+ toast.error("No valid image files found.");
return;
}
@@ -56,7 +56,7 @@ export function useImageConverter() {
}));
setImages(prev => [...prev, ...newImageFiles]);
- toast.success(`${imageFiles.length} Bild(er) hinzugefügt.`);
+ toast.success(`${imageFiles.length} image(s) added.`);
}, [settings.useDefaultBaseName, settings.defaultBaseName]);
const handleRemoveImage = useCallback((indexToRemove: number) => {
@@ -72,7 +72,7 @@ export function useImageConverter() {
const handleClearAll = useCallback(() => {
setImages([]);
updateSettings({ width: initialSettings.width, height: initialSettings.height });
- toast.info("Alle Bilder gelöscht.");
+ toast.info("All images cleared.");
}, [updateSettings]);
const handleFilenameChange = useCallback((index: number, newName: string) => {
@@ -87,15 +87,15 @@ export function useImageConverter() {
const handleConvertAndDownloadSingle = useCallback(async (index: number) => {
setConvertingIndex(index);
- toast.info(`Starte Konvertierung für ${images[index].filename}...`);
+ toast.info(`Starting conversion for ${images[index].filename}...`);
try {
const imageToConvert = images[index];
const dataUrl = await processImage(imageToConvert, settings);
const finalFilename = generateFinalFilename(imageToConvert.filename, settings, index);
downloadDataUrl(dataUrl, `${finalFilename}.${settings.format}`);
- toast.success(`${imageToConvert.filename} erfolgreich exportiert!`);
+ toast.success(`${imageToConvert.filename} exported successfully!`);
} catch (error) {
- const message = error instanceof Error ? error.message : "Ein unbekannter Fehler ist aufgetreten.";
+ const message = error instanceof Error ? error.message : "An unknown error occurred.";
toast.error(message);
} finally {
setConvertingIndex(null);
@@ -104,11 +104,11 @@ export function useImageConverter() {
const handleConvertAndDownloadAll = useCallback(async () => {
if (images.length === 0) {
- toast.error("Bitte laden Sie zuerst Bilder hoch.");
+ toast.error("Please upload images first.");
return;
}
setIsConverting(true);
- toast.info(`Starte Konvertierung für ${images.length} Bilder...`);
+ toast.info(`Starting conversion for ${images.length} images...`);
const conversionPromises = images.map(async (image, index) => {
try {
@@ -116,7 +116,7 @@ export function useImageConverter() {
const finalFilename = generateFinalFilename(image.filename, settings, index);
downloadDataUrl(dataUrl, `${finalFilename}.${settings.format}`);
} catch (error) {
- const message = error instanceof Error ? error.message : `Verarbeitung von ${image.filename} fehlgeschlagen`;
+ const message = error instanceof Error ? error.message : `Processing of ${image.filename} failed`;
toast.error(message);
throw error;
}
@@ -124,9 +124,9 @@ export function useImageConverter() {
try {
await Promise.all(conversionPromises);
- toast.success(`Alle ${images.length} Bilder erfolgreich exportiert!`);
+ toast.success(`All ${images.length} images exported successfully!`);
} catch (error) {
- toast.error("Einige Bilder konnten nicht konvertiert werden. Siehe einzelne Fehler.");
+ toast.error("Some images could not be converted. See individual errors.");
} finally {
setIsConverting(false);
}
@@ -134,7 +134,7 @@ export function useImageConverter() {
const handleResetSettings = useCallback(() => {
setSettings(initialSettings);
- toast.success("Alle Einstellungen wurden auf ihre Standardwerte zurückgesetzt.");
+ toast.success("All settings have been reset to their default values.");
}, []);
const handleAspectRatioChange = useCallback((value: string) => {
@@ -159,15 +159,15 @@ export function useImageConverter() {
const handleApplyDefaultBaseNameToAll = useCallback(() => {
if (!settings.defaultBaseName) {
- toast.error("Bitte geben Sie einen Standard-Basisnamen zum Anwenden ein.");
+ toast.error("Please enter a default basename to apply.");
return;
}
if (images.length === 0) {
- toast.info("Laden Sie zuerst einige Bilder hoch.");
+ toast.info("Upload some images first.");
return;
}
setImages(prev => prev.map(img => ({ ...img, filename: settings.defaultBaseName })));
- toast.success(`Basisname für alle ${images.length} Bilder auf "${settings.defaultBaseName}" gesetzt.`);
+ toast.success(`Basename for all ${images.length} images set to "${settings.defaultBaseName}".`);
}, [images.length, settings.defaultBaseName]);
return {
diff --git a/src/lib/changelog-data.ts b/src/lib/changelog-data.ts
index 5d72584..ac3f46a 100644
--- a/src/lib/changelog-data.ts
+++ b/src/lib/changelog-data.ts
@@ -1,9 +1,9 @@
export const changelogData = [
{
version: "1.0.0",
- date: "15. Januar 2026",
+ date: "January 15, 2026",
changes: [
- { type: "Neu", text: "Erstveröffentlichung des Bild Web Exporters." },
+ { type: "New", text: "Initial release of the Image Web Exporter." },
],
},
];
\ No newline at end of file