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>
Функция возвращает четыре значения: реальные размеры и текущие размеры изображения. Теперь их можно использовать для своих целей, например, чтобы подогнать слишком большое изображение под размер экрана или плавно увеличить его.

Поделиться ссылкой ВКонтакте
Просмотров: 13213 | Комментариев: 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-2024
При использовании материалов ссылка на сайт обязательна
Время генерации: 0.11 сек. / MySQL: 2 (0.0038 сек.) / Память: 4.5 Mb
Наверх