Blog. Just Blog

Как на JavaScript узнать реальный размер изображения

Версия для печати Добавить в Избранное Отправить на E-Mail | Категория: Web-мастеру и не только | Автор: ManHunter
Как на JavaScript узнать реальный размер изображения
Как на JavaScript узнать реальный размер изображения

Для работы с масштабированными изображениями в JavaScript или эффектов типа лайтбокса, необходимо знать реальную высоту и ширину изображения. Но в CSS или в атрибутах изображения width и height можно задать любые размеры. Поэтому попытка определить реальный размер из этих атрибутов вернет неправильные значения, свойства ширины и высоты покажут текущие размеры. К счастью, современные браузеры с поддержкой HTML5 позволяют обрабатывать два дополнительных свойства: naturalWidth и naturalHeight, в которых содержатся реальные размеры изображения.

По результатам тестирования выяснено, что эти свойства поддерживаются в Internet Explorer версии 9 и выше, Firefox и других браузеразх на движке Gecko, Chrome и другие браузеры на движке WebKit, в том числе Safari, а также Opera на движке Presto, начиная с версии 10. Для старых браузеров, таких как Internet Explorer 6-8, Opera 9 и ниже, существует хитрый трюк, с помощью которого все-таки можно определить реальные размеры изображения. Для этого создается новое изображение, которому присваивается атрибут src равный проверяемому изображению. После этого атрибуты width и height вновь созданного изображения будут содержать его реальные размеры. Если объединить оба способа, то получится примерно такая функция, как у меня:
  1. <script type="text/javascript">
  2. // Функция для получения реального размера изображения
  3. // На входе: el - элемент DOM, для которого надо получить размеры
  4. // На выходе: объект {real_width, real_height, client_width, client_height}
  5. // или false, если произошла ошибка
  6. function get_dimensions(el) {
  7.     // Браузер с поддержкой naturalWidth/naturalHeight
  8.     if (el.naturalWidth!=undefined) {
  9.         return { 'real_width':el.naturalWidth,
  10.                  'real_height':el.naturalHeight,
  11.                  'client_width':el.width,
  12.                  'client_height':el.height };
  13.     }
  14.     // Устаревший браузер
  15.     else if (el.tagName.toLowerCase()=='img') {
  16.         var img=new Image();
  17.         img.src=el.src;
  18.         var real_w=img.width;
  19.         var real_h=img.height;
  20.         return { 'real_width':real_w,
  21.                  'real_height':real_h,
  22.                  'client_width':el.width,
  23.                  'client_height':el.height };
  24.     }
  25.     // Что-то непонятное
  26.     else {
  27.         return false;
  28.     }
  29. }
  30. </script>
Для того, чтобы функция сработала, изображение должно быть полностью загружено. Чтобы убедиться в этом, надо проверить атрибут complete элемента или же установить обработчик на событие onload изображения. Вот как это выглядит на web-странице:
  1. <img id="my_image" src="image.jpg" width="100" height="100" />
  2.  
  3. <script type="text/javascript">
  4. var el=document.getElementById('my_image');
  5. // Изображение уже загружено или взято из кэша браузера
  6. if (el.complete) {
  7.     var tmp=get_dimensions(el);
  8.     alert('complete: '+[tmp.real_widthtmp.real_height]);
  9. }
  10. // Ожидаем загрузки изображения
  11. else {
  12.     el.onload=function(event) {
  13.         event=event || window.event;
  14.         var el=event.target || event.srcElement;
  15.         var tmp=get_dimensions(el);
  16.         alert('onload: '+[tmp.real_widthtmp.real_height]);
  17.     }
  18. }
  19. </script>
Функция возвращает четыре значения: реальные размеры и текущие размеры изображения. Теперь их можно использовать для своих целей, например, чтобы подогнать слишком большое изображение под размер экрана или плавно увеличить его.

Поделиться ссылкой ВКонтакте Поделиться ссылкой на Facebook Поделиться ссылкой на LiveJournal Поделиться ссылкой в Мой Круг Добавить в Мой мир Добавить на ЛиРу (Liveinternet) Добавить в закладки Memori Добавить в закладки Google
Просмотров: 12503 | Комментариев: 8

Метки: JavaScript
Внимание! Статья опубликована больше года назад, информация могла устареть!

Комментарии

Отзывы посетителей сайта о статье
ManHunter (16.08.2021 в 16:28):
Если запрошенный элемент не является изображением
Petya (16.08.2021 в 16:22):
А есть ли какие-то реальные условия (исключая заведомо некорректный вызов), при которых сработает ветка "что-то непонятное"?
ManHunter (24.10.2016 в 20:51):
ЦитатаНу и если придираться, то зачем писать так?:
   el.tagName.toLowerCase()=='img'

Потому что не все браузеры возвращают имя тега в верхнем регистре. Про delete согласен, лишнее.
Mnemonist (24.10.2016 в 18:58):
Спасибо. Как раз то что искал.

Более компактный вариант:

function getRealSizeImg(img) {
   if (img.tagName !== 'IMG') return;
   
   if (img.naturalWidth) {
      var width = img.naturalWidth;
      var height = img.naturalHeight;
   } else {
      var helpImg = new Image();
      helpImg.src = img.src;
         
      var width = helpImg.width;
      var height = helpImg.height;
   }
     
   return {
      width: width,
      height: height,
   }
     
}
- - -
1) client_width/client_height в этой фукнции совершенно не нужны. Функция должна делать только то зачем была написана. То есть реальные размеры. А текущие и так можно без проблем узнать.

2) Зачем такая вложенность условий? Они только читабельность ухуджают


3) В других коментариях спорили о delete/null. Но здесь (как и в 90% случаев) ради оптимизации не нужно писать н delete ни null.
В javascript нет фукнции которая удаляет объект. delete удаляет свойство. null - меняет значение. Но не сам объект.
удаляется только то на что нет никаких ссылок.

Здесь же в любом случае никаких ссылок не сохранится. Фукнция выполнятся - и все. Все что в нем было создано больше недоступно. Его никак нельзя достать. А значит оно больше не нужно, и JavaScript его удалит.

4) Ну и если придираться, то зачем писать так?:
   el.tagName.toLowerCase()=='img'
Если можно написать: el.tagName === 'IMG'. Ведь toLowerCase это метод, а на его выполнение нужно время
ManHunter (07.09.2015 в 14:00):
delete поддерживается браузерами еще с первого пришествия
Arris (06.09.2015 в 13:35):
У меня нет уверенности, что delete something будет поддерживаться старыми браузерами так же, как описано в современном стандарте. Впрочем, на этот случай лучше совместить - поставить И delete, И =null.
ManHunter (03.09.2015 в 07:44):
Не совсем так, конечно, но мысль правильная. За собой надо прибираться, освобождая ресурсы. Подкорректировал, спасибо!
Arris (03.09.2015 в 03:03):
Отмечу, что первый листинг стоит переписать:

if (el.tagName.toLowerCase()=='img') {
            var img=new Image();
            img.src=el.src;
var cl_w = el.width, cl_h = el.height;
img = null;
            return { 'real_width':img.width,
                     'real_height':img.height,
                     'client_width':cl_w,
                     'client_height':cl_h };
        }

Или delete img;

Добавить комментарий

Заполните форму для добавления комментария
Имя*:
Текст комментария (не более 2000 символов)*:

*Все поля обязательны для заполнения.
Комментарии, содержащие рекламу, ненормативную лексику, оскорбления и т.п., а также флуд и сообщения не по теме, будут удаляться. Нарушителям может быть заблокирован доступ к сайту.
Наверх
Powered by PCL's Speckled Band Engine 0.2 RC3
© ManHunter / PCL, 2008-2023
При использовании материалов ссылка на сайт обязательна
Время генерации: 0.07 сек. / MySQL: 2 (0.0083 сек.) / Память: 4.5 Mb
Наверх