واجهة برمجة تطبيقات البيانات الوصفية
يوفر Sharp وظائف غنية لمعالجة البيانات الوصفية، مما يتيح قراءة وتعديل وكتابة معلومات البيانات الوصفية للصور.
قراءة البيانات الوصفية
الاستخدام الأساسي
javascript
import sharp from 'sharp';
// قراءة البيانات الوصفية للصورة
const metadata = await sharp('input.jpg').metadata();
console.log(metadata);بنية كائن البيانات الوصفية
javascript
{
format: 'jpeg', // تنسيق الصورة
width: 1920, // العرض
height: 1080, // الارتفاع
space: 'srgb', // مساحة اللون
channels: 3, // عدد القنوات
depth: 'uchar', // عمق البت
density: 72, // الدقة
hasProfile: false, // ما إذا كان يحتوي على ملف تعريف اللون
hasAlpha: false, // ما إذا كان يحتوي على قناة الشفافية
isOpaque: true, // ما إذا كان معتمًا
orientation: 1, // اتجاه EXIF
exif: { ... }, // بيانات EXIF
icc: { ... }, // ملف تعريف ICC
iptc: { ... }, // بيانات IPTC
xmp: { ... }, // بيانات XMP
tifftagPhotoshop: { ... } // علامات Photoshop TIFF
}بيانات EXIF
قراءة EXIF
javascript
const metadata = await sharp('input.jpg').metadata();
if (metadata.exif) {
console.log('بيانات EXIF:', metadata.exif);
// تحليل بيانات EXIF
const exif = sharp.exif(metadata.exif);
console.log('وقت التصوير:', exif.DateTime);
console.log('طراز الكاميرا:', exif.Model);
console.log('ISO:', exif.ISOSpeedRatings);
}كتابة EXIF
javascript
// إنشاء بيانات EXIF
const exif = sharp.exif({
IFD0: {
ImageDescription: 'صورة معالجة بـ Sharp',
Copyright: '© 2024'
},
IFD1: {
Orientation: 1
},
EXIF: {
DateTimeOriginal: new Date().toISOString(),
UserComment: 'معالجة باستخدام Sharp'
}
});
// كتابة بيانات EXIF
await sharp('input.jpg')
.withMetadata({ exif })
.jpeg()
.toFile('output.jpg');ملفات تعريف اللون ICC
قراءة ملف تعريف ICC
javascript
const metadata = await sharp('input.jpg').metadata();
if (metadata.icc) {
console.log('ملف تعريف ICC:', metadata.icc);
}تضمين ملف تعريف ICC
javascript
// تضمين ملف تعريف sRGB
await sharp('input.jpg')
.withMetadata({ icc: 'srgb' })
.jpeg()
.toFile('output.jpg');
// تضمين ملف تعريف ICC مخصص
const iccProfile = fs.readFileSync('custom.icc');
await sharp('input.jpg')
.withMetadata({ icc: iccProfile })
.jpeg()
.toFile('output.jpg');بيانات IPTC
قراءة IPTC
javascript
const metadata = await sharp('input.jpg').metadata();
if (metadata.iptc) {
console.log('بيانات IPTC:', metadata.iptc);
}كتابة IPTC
javascript
const iptc = {
'2:05': 'Object Name',
'2:15': 'Category',
'2:25': 'Keywords',
'2:55': 'Date Created',
'2:80': 'By-line',
'2:116': 'Copyright'
};
await sharp('input.jpg')
.withMetadata({ iptc })
.jpeg()
.toFile('output.jpg');بيانات XMP
قراءة XMP
javascript
const metadata = await sharp('input.jpg').metadata();
if (metadata.xmp) {
console.log('بيانات XMP:', metadata.xmp);
}كتابة XMP
javascript
const xmp = `
<x:xmpmeta xmlns:x="adobe:ns:meta/">
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
<rdf:Description rdf:about=""
xmlns:dc="http://purl.org/dc/elements/1.1/">
<dc:title>صورة معالجة بـ Sharp</dc:title>
<dc:creator>Sharp</dc:creator>
</rdf:Description>
</rdf:RDF>
</x:xmpmeta>
`;
await sharp('input.jpg')
.withMetadata({ xmp })
.jpeg()
.toFile('output.jpg');معلومات الاتجاه
قراءة الاتجاه
javascript
const metadata = await sharp('input.jpg').metadata();
console.log('اتجاه الصورة:', metadata.orientation);التدوير التلقائي
javascript
// التدوير التلقائي بناءً على اتجاه EXIF
await sharp('input.jpg')
.rotate() // تدوير تلقائي
.jpeg()
.toFile('output.jpg');معلومات الدقة
قراءة الدقة
javascript
const metadata = await sharp('input.jpg').metadata();
console.log('الدقة:', metadata.density);تعيين الدقة
javascript
await sharp('input.jpg')
.withMetadata({ density: 300 })
.jpeg()
.toFile('output.jpg');الاحتفاظ بالبيانات الوصفية
الاحتفاظ بجميع البيانات الوصفية
javascript
// الاحتفاظ بجميع البيانات الوصفية الموجودة
await sharp('input.jpg')
.resize(800, 600)
.withMetadata()
.jpeg()
.toFile('output.jpg');الاحتفاظ الانتقائي
javascript
// الاحتفاظ ببيانات EXIF فقط
await sharp('input.jpg')
.resize(800, 600)
.withMetadata({ exif: true })
.jpeg()
.toFile('output.jpg');
// الاحتفاظ بـ EXIF و ICC
await sharp('input.jpg')
.resize(800, 600)
.withMetadata({ exif: true, icc: true })
.jpeg()
.toFile('output.jpg');إزالة البيانات الوصفية
إزالة جميع البيانات الوصفية
javascript
// إزالة جميع البيانات الوصفية
await sharp('input.jpg')
.resize(800, 600)
.jpeg()
.toFile('output.jpg');إزالة بيانات وصفية محددة
javascript
// إزالة EXIF مع الاحتفاظ بالباقي
await sharp('input.jpg')
.resize(800, 600)
.withMetadata({ exif: false })
.jpeg()
.toFile('output.jpg');معالجة البيانات الوصفية المجمعة
القراءة المجمعة
javascript
const fs = require('fs').promises;
async function batchReadMetadata(directory) {
const files = await fs.readdir(directory);
const results = [];
for (const file of files) {
if (file.match(/\.(jpg|jpeg|png|webp)$/i)) {
try {
const metadata = await sharp(`${directory}/${file}`).metadata();
results.push({ file, metadata });
} catch (error) {
console.error(`فشل قراءة البيانات الوصفية لـ ${file}:`, error.message);
}
}
}
return results;
}الكتابة المجمعة
javascript
async function batchWriteMetadata(directory, metadata) {
const files = await fs.readdir(directory);
for (const file of files) {
if (file.match(/\.(jpg|jpeg|png|webp)$/i)) {
try {
await sharp(`${directory}/${file}`)
.withMetadata(metadata)
.toFile(`${directory}/processed_${file}`);
} catch (error) {
console.error(`فشل معالجة ${file}:`, error.message);
}
}
}
}التحقق من البيانات الوصفية
التحقق من اكتمال البيانات الوصفية
javascript
async function validateMetadata(filePath) {
try {
const metadata = await sharp(filePath).metadata();
// التحقق من الخصائص الأساسية
if (!metadata.width || !metadata.height) {
throw new Error('معلومات الأبعاد مفقودة');
}
// التحقق من التنسيق
if (!metadata.format) {
throw new Error('معلومات التنسيق مفقودة');
}
// التحقق من عدد القنوات
if (!metadata.channels) {
throw new Error('معلومات القناة مفقودة');
}
return {
valid: true,
metadata
};
} catch (error) {
return {
valid: false,
error: error.message
};
}
}تحسين الأداء
قراءة البيانات الوصفية المطلوبة فقط
javascript
// قراءة المعلومات الأساسية فقط، بدون تحليل EXIF
const metadata = await sharp('input.jpg')
.metadata({ pages: -1 });
// قراءة EXIF فقط
const metadata = await sharp('input.jpg')
.metadata({ exif: true });المعالجة المتدفقة
javascript
const fs = require('fs');
// قراءة البيانات الوصفية بشكل متدفق
const stream = fs.createReadStream('input.jpg');
const metadata = await sharp(stream).metadata();معالجة الأخطاء
javascript
try {
const metadata = await sharp('input.jpg').metadata();
console.log('البيانات الوصفية:', metadata);
} catch (error) {
if (error.code === 'VipsForeignLoad') {
console.error('تنسيق صورة غير مدعوم');
} else if (error.code === 'VipsForeignLoadLimit') {
console.error('الصورة كبيرة جدًا');
} else {
console.error('فشل قراءة البيانات الوصفية:', error.message);
}
}