فرز الصور حسب البيانات من EXIF ​​+ PHP

أريد أن أشارك تجربتي في فرز الصور باستخدام برنامج نصي في PHP
تأتي لحظة لا يوجد فيها الكثير من الصور ، ولكن هناك الكثير من الكوارث.

قبل التاريخ


في أحد الأيام ، قررت فرز أرشيفي الكامل للصور الرقمية ، المتراكمة على مدار 20 عامًا ، وأدركت أنه في كل ذلك الوقت قمت بتجميع 112000 صورة بمعدل 435 غيغابايت.

علاوة على ذلك ، يتم تصنيف بعضها بشكل أو بآخر ، على سبيل المثال ، صور من كاميرا SLR ، بواسطة مجلدات تحمل أسماء وتواريخ ، بينما لم يتم تسمية وفرز الجزء الآخر من الصور التي تم استيرادها من iphone / android ، وغالبًا ما يكون مجرد مجلد عملاق 10 غيغابايت ، مع وجود آلاف الملفات في الداخل ، ومن المؤسف حذفها وترتيبها.

لقد بدأت في البحث عن أدوات الفرز التلقائي وأدركت أن جميع الخدمات الجيدة ، مثل بيكاسا ، قد تم شراؤها وإغلاقها بالفعل من قبل Google ، بالطبع يمكنك تحميل كل شيء عليها على Google ، ومع ذلك ، هناك مشاكل هناك ، لا يتم البحث فيها جميعها ونصف الوظائف عمومًا مفقودة من أن تكون في بيكاسا ، وإذا كنت لا تزال تشعر بالقلق من أن صورك سيتم التعرف عليها واستخدامها ، فإن التحميل على الويب ليس في طريقك على الإطلاق.

نتيجة لذلك ، تقرر كتابة برنامج نصي صغير يقوم بترتيب كل شيء ، في البداية فكرت في برنامج نصي ، ولكن مع إدراك أنني بحاجة إليه ، قررت EXIF ​​العودة إلى PHP القديم الجيد.

المهمة رقم 1 - توسيع جميع الملفات حسب التواريخ


أولاً ، لقد ذهبت إلى أبسط طريقة ، وأخذ جميع الملفات ، وانظر إلى تاريخ الإنشاء وانتشر على طول المسارات المتداخلة:

$file_list = $files->getDirContents($config['photos.unsorted']); foreach ($file_list as $key => $value) { moveImageFile($value); } function moveImageFile($filename) { $dt= new DateTime(); $dt->setTimestamp(filectime($filename)); $start_path = $this->config['photos']; $year = $start_path."\Year".$dt->format('Y'); if (!is_dir($year)) mkdir($year); $month = $year."\\".$dt->format('Ym-F'); if (!is_dir($month)) mkdir($month); $path = $month."\\".$dt->format('Ym-d'); if (!is_dir($path)) mkdir($path); } $full_path = getUniqueFilename($filename, $path, $dt, 0); copy($filename, $full_path); 

كانت هناك عدة مشاكل:

  • كان لبعض الملفات تاريخ إنشاء غير صحيح
  • إذا قمت بنسخ ، يتم إنشاء ملف جديد بحلول التاريخ الحالي.
  • يمكن أن تحتوي الملفات على تكرارات في نفس وقت الإنشاء

المشكلة رقم 2 - الحصول على التاريخ من Exif


تقرر أخذ التاريخ من EXIF ​​، وإعادة تسمية ولمس الملفات لتعيين التاريخ من exif ، وكذلك التحقق من الملفات المكررة باستخدام md5.

من حيث المبدأ ، يحتوي PHP بالفعل على ملحق exif في مجموعة المكتبة ، لذلك لم يكن من المتوقع حدوث أي شيء خارق

  $dt = DateTime::createFromFormat('Y:m:d H:i:s', $exif['DateTime']); $start_path = $this->config['photos.exif']; $is_exif = true; if (md5_file($filename) == md5_file($full_path)) return false; rename($filename, $full_path); touch($full_path, $dt->getTimestamp()); 

كل شيء سيكون على ما يرام ، تم فرز 500 غيغابايت من الصور وإزالتها من التكرارات في بضع ساعات ، ولكن بعد ذلك تذكرت المجلدات القديمة التي تحتوي على اسم المنطقة التي تم فيها التقاط الصورة ، وفكرت ، لماذا لا أحصل على أسماء المدن من البيانات الجغرافية؟

المهمة №3 - البلدان والمدن والمناطق من البيانات الجغرافية EXIF


يسهل العثور على الإحداثيات في الملفات ، فهي موجودة في Exif في GPSLongitude و GPSLatitude ، لكن يجب ألا ننسى أنه تم تخزينها هناك بالدرجات والدقائق والثواني ، لذلك تحتاج إلى استخدام الوظائف لتحويل الإحداثيات إلى رقم عشري.

 function getGps($exifCoord, $hemi) { $degrees = count($exifCoord) > 0 ? $this->gps2Num($exifCoord[0]) : 0; $minutes = count($exifCoord) > 1 ? $this->gps2Num($exifCoord[1]) : 0; $seconds = count($exifCoord) > 2 ? $this->gps2Num($exifCoord[2]) : 0; $flip = ($hemi == 'W' or $hemi == 'S') ? -1 : 1; return $flip * ($degrees + $minutes / 60 + $seconds / 3600); } 

السؤال الثاني ، ماذا تفعل مع الإحداثيات ، وكيفية الحصول على اسم المدينة؟
Geocoder من Yandex يأتي إلى الإنقاذ ، ولكن كن حذرا مع حدود وشروط الاستخدام.

 $url = "https://geocode-maps.yandex.ru/1.x/"; $apikey = require('../config/apikey.php'); $json = array( 'geocode' => $lon.",".$lat, 'kind' => 'locality', 'apikey' => $apikey, 'results' =>'1', 'skip' => '0', 'format' => 'json' ); $response = file_get_contents($url."?".http_build_query($json)); 

حتى لا تقتل Yandex بملايين الاستعلامات ، نقوم بتخزين البيانات مؤقتًا في MySql ، حيث نجمع الإحداثيات إلى 3 منازل عشرية ، أي 43.161 - 19.182 تكفي لتحديد المدينة ، وبالتالي حصلت على 1500000 صورة فقط هندسيًا.

ظهور المجلدات هو شيء مثل هذا:

  • D: \ photos \ photos_exif \ Year2019 \ 2019-09-September \ 2019-09-23-Bosnia and Herzegovina، Republika Srpska، Foca \
  • D: \ photos \ photos_exif \ Year2019 \ 2019-08-August \ 2019-08-25-Albania، Durres region، Kruja \
  • D: \ photos \ photos_exif \ Year2018 \ 2018-10 October \ 2018-10-06-Russia، Moscow Region، Balashikha \

بدلا من الاستنتاج


في الواقع ، إذا كنت تتناول هذا المنتج ، فيمكنك فعل ذلك لعدة أشهر ، لقد استغرق الأمر مني يومًا لكتابة برنامج نصي وتحسين تخزين الصور.

من الخطط: إضافة علامات جغرافية إلى الصور الحالية ، وإعادة ترتيب أرشيف الصور الحالي ، وإيجاد التكرارات بين الصور المقطوعة.

جميع ملفات المشاريع متوفرة على جيثب

لا تضربني بشدة ، هذا هو أول مشروع مفتوح المصدر بالكامل ، إذا تم نشر شيء ما أو كتابته بشكل غير صحيح ، أخبرني ، والآن يتم سجن كل شيء لبيئة تشغيل Windows بترميز 1251.

Source: https://habr.com/ru/post/ar470009/


All Articles