मुख्य सामग्री पर जाएं

छवि प्रोसेसिंग

बैंडविड्थ और स्टोरेज लागत को कम करने के लिए अपलोड करने से पहले क्लाइंट-साइड पर छवियों को प्रोसेस करें।

छवि संपीड़न

import { useDropup } from '@samithahansaka/dropup';
import { compressImage } from '@samithahansaka/dropup/image';

function CompressedUploader() {
const { files, actions, getDropProps, getInputProps } = useDropup({
accept: 'image/*',
upload: { url: '/api/upload' },

// अपलोड से पहले फ़ाइलों को प्रोसेस करें
onFilesAdded: async (newFiles) => {
for (const file of newFiles) {
// छवि को संपीड़ित करें
const compressed = await compressImage(file.file, {
maxWidth: 1920,
maxHeight: 1080,
quality: 0.8,
});

// संपीड़ित संस्करण से बदलें
actions.updateFileMeta(file.id, {
originalSize: file.size,
compressedFile: compressed,
});
}
},
});

return (
<div {...getDropProps()}>
<input {...getInputProps()} />
<p>छवियां अपलोड से पहले संपीड़ित की जाएंगी</p>
</div>
);
}

संपीड़न विकल्प

interface CompressOptions {
// अधिकतम आयाम (पक्ष अनुपात बनाए रखता है)
maxWidth?: number; // डिफ़ॉल्ट: 1920
maxHeight?: number; // डिफ़ॉल्ट: 1080

// गुणवत्ता (0-1)
quality?: number; // डिफ़ॉल्ट: 0.8

// आउटपुट फ़ॉर्मेट
type?: 'image/jpeg' | 'image/png' | 'image/webp'; // डिफ़ॉल्ट: मूल प्रकार
}

// उदाहरण
await compressImage(file, { quality: 0.6 }); // कम गुणवत्ता
await compressImage(file, { maxWidth: 800, maxHeight: 600 }); // छोटा आकार
await compressImage(file, { type: 'image/webp' }); // WebP में कनवर्ट करें

संपीड़न के साथ पूर्वावलोकन

import { useDropup } from '@samithahansaka/dropup';
import { compressImage } from '@samithahansaka/dropup/image';
import { useState } from 'react';

function PreviewWithCompression() {
const [compressionStats, setCompressionStats] = useState<Map<string, {
original: number;
compressed: number;
}>>(new Map());

const { files, actions, getDropProps, getInputProps } = useDropup({
accept: 'image/*',

onFilesAdded: async (newFiles) => {
for (const file of newFiles) {
const compressed = await compressImage(file.file, {
maxWidth: 1200,
quality: 0.75,
});

setCompressionStats(prev => new Map(prev).set(file.id, {
original: file.size,
compressed: compressed.size,
}));

// अपलोड के लिए संपीड़ित फ़ाइल संग्रहीत करें
actions.updateFileMeta(file.id, { compressedFile: compressed });
}
},
});

const formatSize = (bytes: number) => {
if (bytes < 1024) return `${bytes} B`;
if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
return `${(bytes / 1024 / 1024).toFixed(1)} MB`;
};

return (
<div>
<div {...getDropProps()} style={styles.dropzone}>
<input {...getInputProps()} />
<p>संपीड़ित करने के लिए छवियां छोड़ें</p>
</div>

<div style={styles.grid}>
{files.map(file => {
const stats = compressionStats.get(file.id);
const savings = stats
? ((1 - stats.compressed / stats.original) * 100).toFixed(0)
: 0;

return (
<div key={file.id} style={styles.card}>
{file.preview && (
<img src={file.preview} alt="" style={styles.preview} />
)}
<p>{file.name}</p>
{stats && (
<p style={styles.stats}>
{formatSize(stats.original)}{formatSize(stats.compressed)}
<span style={styles.savings}> (-{savings}%)</span>
</p>
)}
</div>
);
})}
</div>
</div>
);
}

const styles = {
dropzone: {
border: '2px dashed #ccc',
borderRadius: 8,
padding: 40,
textAlign: 'center' as const,
marginBottom: 20,
},
grid: {
display: 'grid',
gridTemplateColumns: 'repeat(auto-fill, minmax(200px, 1fr))',
gap: 16,
},
card: {
border: '1px solid #eee',
borderRadius: 8,
padding: 12,
},
preview: {
width: '100%',
height: 150,
objectFit: 'cover' as const,
borderRadius: 4,
},
stats: {
fontSize: 12,
color: '#666',
},
savings: {
color: '#4caf50',
fontWeight: 'bold',
},
};

छवि का आकार बदलना

import { resizeImage } from '@samithahansaka/dropup/image';

// सटीक आयामों में आकार बदलें
const resized = await resizeImage(file, {
width: 300,
height: 300,
mode: 'cover', // 'cover' | 'contain' | 'fill'
});

// थंबनेल बनाएं
const thumbnail = await resizeImage(file, {
width: 150,
height: 150,
mode: 'cover',
});

आकार बदलने के मोड

मोडविवरण
coverपूरे क्षेत्र को भरता है, क्रॉप हो सकता है
containक्षेत्र के भीतर फिट होता है, खाली स्थान हो सकता है
fillभरने के लिए खिंचता है (विकृत हो सकता है)

EXIF ओरिएंटेशन फिक्स

कुछ कैमरे EXIF रोटेशन डेटा के साथ छवियां सहेजते हैं। प्रदर्शन से पहले ओरिएंटेशन ठीक करें:

import { fixOrientation } from '@samithahansaka/dropup/image';

const corrected = await fixOrientation(file);

छवि क्रॉप करें

import { cropImage } from '@samithahansaka/dropup/image';

const cropped = await cropImage(file, {
x: 100, // प्रारंभ X
y: 50, // प्रारंभ Y
width: 400, // क्रॉप चौड़ाई
height: 400, // क्रॉप ऊंचाई
});

छवि संपादक कंपोनेंट

import { useDropup } from '@samithahansaka/dropup';
import { compressImage, cropImage } from '@samithahansaka/dropup/image';
import { useState, useRef } from 'react';

function ImageEditor() {
const [selectedFile, setSelectedFile] = useState<DropupFile | null>(null);
const [cropArea, setCropArea] = useState({ x: 0, y: 0, width: 200, height: 200 });

const { files, actions, getDropProps, getInputProps } = useDropup({
accept: 'image/*',
maxFiles: 1,
multiple: false,
});

const handleCrop = async () => {
if (!selectedFile) return;

const cropped = await cropImage(selectedFile.file, cropArea);

// मूल को क्रॉप किए गए संस्करण से बदलें
actions.updateFileMeta(selectedFile.id, {
processedFile: cropped,
});
};

const handleCompress = async () => {
if (!selectedFile) return;

const compressed = await compressImage(selectedFile.file, {
quality: 0.7,
});

actions.updateFileMeta(selectedFile.id, {
processedFile: compressed,
});
};

return (
<div style={styles.container}>
{files.length === 0 ? (
<div {...getDropProps()} style={styles.dropzone}>
<input {...getInputProps()} />
<p>संपादित करने के लिए एक छवि छोड़ें</p>
</div>
) : (
<div style={styles.editor}>
<div style={styles.preview}>
<img
src={files[0].preview}
alt=""
style={styles.image}
onClick={() => setSelectedFile(files[0])}
/>
</div>

<div style={styles.tools}>
<h4>उपकरण</h4>
<button onClick={handleCrop}>क्रॉप करें</button>
<button onClick={handleCompress}>संपीड़ित करें</button>
<button onClick={() => actions.reset()}>हटाएं</button>
</div>
</div>
)}
</div>
);
}

const styles = {
container: {
maxWidth: 600,
margin: '0 auto',
},
dropzone: {
border: '2px dashed #ccc',
borderRadius: 8,
padding: 60,
textAlign: 'center' as const,
},
editor: {
display: 'flex',
gap: 20,
},
preview: {
flex: 1,
},
image: {
maxWidth: '100%',
borderRadius: 8,
},
tools: {
width: 150,
display: 'flex',
flexDirection: 'column' as const,
gap: 8,
},
};

छवि फ़ॉर्मेट कनवर्ट करें

import { convertImage } from '@samithahansaka/dropup/image';

// छोटे फ़ाइल आकार के लिए WebP में कनवर्ट करें
const webp = await convertImage(file, 'image/webp');

// JPEG में कनवर्ट करें
const jpeg = await convertImage(file, 'image/jpeg', { quality: 0.9 });

// PNG में कनवर्ट करें (lossless)
const png = await convertImage(file, 'image/png');

छवि मेटाडेटा प्राप्त करें

import { getImageMetadata } from '@samithahansaka/dropup/image';

const metadata = await getImageMetadata(file);
console.log(metadata);
// {
// width: 1920,
// height: 1080,
// aspectRatio: 1.78,
// orientation: 1, // EXIF ओरिएंटेशन
// hasAlpha: false,
// format: 'image/jpeg',
// }

पाइपलाइन प्रोसेसिंग

कई ऑपरेशन चेन करें:

import {
compressImage,
fixOrientation,
resizeImage,
} from '@samithahansaka/dropup/image';

async function processImage(file: File): Promise<File> {
let processed = file;

// चरण 1: ओरिएंटेशन ठीक करें
processed = await fixOrientation(processed);

// चरण 2: यदि बहुत बड़ा है तो आकार बदलें
const metadata = await getImageMetadata(processed);
if (metadata.width > 2000 || metadata.height > 2000) {
processed = await resizeImage(processed, {
maxWidth: 2000,
maxHeight: 2000,
});
}

// चरण 3: संपीड़ित करें
processed = await compressImage(processed, {
quality: 0.8,
type: 'image/webp',
});

return processed;
}

// अपलोडर में उपयोग करें
const { files } = useDropup({
accept: 'image/*',
onFilesAdded: async (newFiles) => {
for (const file of newFiles) {
const processed = await processImage(file.file);
actions.updateFileMeta(file.id, { processedFile: processed });
}
},
});

ब्राउज़र समर्थन

छवि प्रोसेसिंग Canvas API का उपयोग करती है और सभी आधुनिक ब्राउज़रों में समर्थित है:

सुविधाChromeFirefoxSafariEdge
Resize/Crop
JPEG/PNG
WebP14+
EXIF Fix