Pull to refresh

Exponator – расширение для просмотра EXIF-данных фотографий

Reading time3 min
Views11K
Exponator Я достаточно давно хотел сделать расширение, которое позволяло бы просматривать данные об экспозиции фотографии, которые хранятся в EXIF. И вот, вдохновленный постом «Создание расширения для Google Chrome» решил-таки потратить на это время.

Ссылка на расширение: Exponator.

Под катом будет кратко рассказано о процессе создания, нескольких подводных камнях и задан вопрос опытным разработчикам. :-)

Сперва я озаботился поиском javascript-библиотеки, которая бы читала EXIF блок из jpeg файлов: изобретать велосипед никакого желания не было. Почти сразу я нашел необходимое на сайте Nihigoloc: http://www.nihilogic.dk/labs/exif/. В библиотеке скрипт проходит по всем изображением, скачивает их в бинарном виде, проверяет наличие EXIF-данных, парсит их и добавляет новое поле к исходному изображению. Практически то, что нужно.

Вторым шагом стало изучение документации и более подробное прочтение статьи про создание расширения. Для расширения не нужна кнопка в строке адреса, да и страница настроек на данном этапе лишняя. Недолго думая я открыл раздел Content Scripts и приступил к третьему шагу: написал, казалось бы, рабочий код, который, как ни странно, не заработал.

При этом дебаггер Хрома (я даже не ожидал, что он настолько хорош) ни на что не ругался: XMLHttpRequest отправлялся, а ответа не было. Я убил на это около часа, а потом узнал, что Content-скрипты не могут обращаться к данным вне домена страницы. А фотографии, в большинстве своем, хостятся на серверах, отличных от тех на которых отображаются.

Решением задачи оказалась фоновая страница, которая ограничивается только в манифесте расширения в разделе permissions. Если там указать http://*/, то из фоновой страницы можно будет послать запрос на любой домен. Кусок манифеста:

"background_page": "background.html",

"permissions": [
 "http://*/"
],

"content_scripts": [
 {
  "matches": ["http://*/*"],
  "js": [ "EXIF.js", "js.js"],
  "run_at": "document_start"
 }
 ]


* This source code was highlighted with Source Code Highlighter.


Но решение одной задачи влечет за собой появление следующей: как фоновой странице обмениваться данными с Content Script? Документация описывает два способа: разовый запрос и соединение, которое может жить неопределенное время. Мне нужно было отправить в фоновую страницу ссылку на изображение, загрузить ее там, а назад вернуть массив с разобранными EXIF-данными. По логике вещей мне вполне подходит разовый запрос, но я не смог разобраться в том, как он работает. А обычное соединение пошло сразу.

В результате в фоновой странице был добавлен обработчик сообщений, который получает адрес изображения, скачивает картинку, достает из нее необходимые данные и, пользуясь тем же портом, отправляет их обратно:

chrome.extension.onConnect.addListener(function(port) {
    port.onMessage.addListener(function(imgSrc) {
      BinaryAjax(
        imgSrc,
        function(HTTP) {
          var EXIF = EXIF.findEXIFinJPEG(HTTP.binaryResponse);
          port.postMessage(EXIF);
          }
        )
    });
  });


* This source code was highlighted with Source Code Highlighter.


А в скрипте страницы создается порт, отправляется ссылка на изображение, а при получении ответного сообщения массив данных присваивается полю exifdata:

var port = chrome.extension.connect({name: "exif"});
    port.onMessage.addListener(function(oEXIF) {
        oImg.exifdata = oEXIF || {};  
              });
    port.postMessage(oImg.src);


* This source code was highlighted with Source Code Highlighter.


После чего из EXIF берутся диафрагма, выдержка и светочувствительность и добавляются к Title изображения:



Вопрос к залу: возможно ли получить доступ к кэшу Хрома? Кэширует ли Хром XMLHttpRequest? А то сейчас каждое изображение скачивается дважды: один раз при загрузке страницы, второй раз при получении EXIF-данных.

Ссылка на расширение: Exponator.

UPD: Некоторые картинки могут не работать. Почему-то некоторые сервера не дают их загрузить.

UPD: При желании шаблон можно изменить в настройках.

UPD: Символ * в шаблоне выводит все доступные поля EXIF.
Tags:
Hubs:
+27
Comments19

Articles